Ejemplo n.º 1
0
    def get_proof_term(self, goal, *, args=None, prevs=None):
        assert isinstance(args, Term), "cases"

        As = goal.hyps
        C = goal.prop
        goal1 = ProofTerm.sorry(Thm(goal.hyps, Implies(args, C)))
        goal2 = ProofTerm.sorry(Thm(goal.hyps, Implies(Not(args), C)))
        return apply_theorem('classical_cases', goal1, goal2)
Ejemplo n.º 2
0
    def get_proof_term(self, goal, *, args=None, prevs=None):
        assert isinstance(prevs,
                          list) and len(prevs) == 1, "rewrite_goal_with_prev"
        pt = prevs[0]
        C = goal.prop

        # In general, we assume pt.th has forall quantification.
        # First, obtain the patterns
        new_names = logic.get_forall_names(pt.prop)
        new_vars, prev_As, prev_C = logic.strip_all_implies(pt.prop, new_names)

        # Fact used must be an equality
        assert len(
            prev_As) == 0 and prev_C.is_equals(), "rewrite_goal_with_prev"

        for new_var in new_vars:
            pt = pt.forall_elim(new_var)

        # Check whether rewriting using the theorem has an effect
        assert has_rewrite(pt.th, C), "rewrite_goal_with_prev"

        cv = then_conv(top_sweep_conv(rewr_conv(pt)), beta_norm_conv())
        eq_th = cv.eval(C)
        new_goal = eq_th.prop.rhs

        prevs = list(prevs)
        if not new_goal.is_reflexive():
            prevs.append(ProofTerm.sorry(Thm(goal.hyps, new_goal)))
        return ProofTerm('rewrite_goal_with_prev', args=C, prevs=prevs)
Ejemplo n.º 3
0
    def get_proof_term(self, goal, *, args=None, prevs=None):
        th_name = args
        C = goal.prop

        # Check whether rewriting using the theorem has an effect
        assert has_rewrite(th_name, C, sym=self.sym, conds=prevs), \
            "rewrite: unable to apply theorem."

        cv = then_conv(
            top_sweep_conv(rewr_conv(th_name, sym=self.sym, conds=prevs)),
            beta_norm_conv())
        eq_th = cv.eval(C)
        new_goal = eq_th.prop.rhs

        if self.sym:
            macro_name = 'rewrite_goal_sym'
        else:
            macro_name = 'rewrite_goal'
        if new_goal.is_equals() and new_goal.lhs == new_goal.rhs:
            return ProofTerm(macro_name, args=(th_name, C), prevs=prevs)
        else:
            new_goal = ProofTerm.sorry(Thm(goal.hyps, new_goal))
            assert new_goal.prop != goal.prop, "rewrite: unable to apply theorem"
            return ProofTerm(macro_name,
                             args=(th_name, C),
                             prevs=[new_goal] + prevs)
Ejemplo n.º 4
0
    def get_proof_term(self, goal):
        if not goal.prop.is_forall():
            raise TacticException('intro_forall: goal is not forall')

        v, body = goal.prop.arg.dest_abs(self.var_name)
        new_goal = ProofTerm.sorry(Thm(goal.hyps, body))
        return new_goal.forall_intr(v)
Ejemplo n.º 5
0
    def get_proof_term(self, goal):
        th = theory.get_theorem(self.th_name)

        assum = th.assums[0]
        cond = self.cond
        if cond is None:
            # Find cond by matching with goal.hyps one by one
            for hyp in goal.hyps:
                try:
                    inst = matcher.first_order_match(th.assums[0], hyp,
                                                     self.inst)
                    cond = hyp
                    break
                except matcher.MatchException:
                    pass

        if cond is None:
            raise TacticException('elim: cannot match assumption')

        try:
            inst = matcher.first_order_match(th.concl, goal.prop, inst)
        except matcher.MatchException:
            raise TacticException('elim: matching failed')

        if any(v.name not in inst for v in th.prop.get_svars()):
            raise TacticException('elim: not all variables are matched')

        pt = ProofTerm.theorem(self.th_name).substitution(inst).on_prop(
            beta_norm_conv())
        pt = pt.implies_elim(ProofTerm.assume(cond))
        for assum in pt.assums:
            pt = pt.implies_elim(ProofTerm.sorry(Thm(goal.hyps, assum)))
        return pt
Ejemplo n.º 6
0
    def get_proof_term(self, goal):
        if not goal.prop.is_implies():
            raise TacticException('intro_imp: goal is not implies.')

        A, C = goal.prop.args
        new_goal = ProofTerm.sorry(Thm(list(goal.hyps) + [A], C))
        return new_goal.implies_intr(A)
Ejemplo n.º 7
0
 def get_proof_term(self, goal):
     pt = ProofTerm.sorry(goal)
     while True:
         try:
             pt = pt.tac(self.tac)
         except TacticException:
             break
     return pt
Ejemplo n.º 8
0
    def eval(self, args, prevs):
        """Obtain the result of applying the macro.
        
        Input is the current theory, argument of the proof method, and
        the list of previous theorems.

        """
        pts = [ProofTerm.sorry(prev) for prev in prevs]
        return self.get_proof_term(args, pts).th
Ejemplo n.º 9
0
    def get_proof_term(self, goal, *, args=None, prevs=None):
        if isinstance(args, tuple):
            th_name, inst = args
        else:
            th_name, inst = args, None
        assert isinstance(th_name, str), "rule: theorem name must be a string"

        if prevs is None:
            prevs = []

        th = theory.get_theorem(th_name)
        As, C = th.assums, th.concl

        # Length of prevs is at most length of As
        assert len(prevs) <= len(As), "rule: too many previous facts"
        if inst is None:
            inst = Inst()

        # Match the conclusion and assumptions. Either the conclusion
        # or the list of assumptions must be a first-order pattern.
        if matcher.is_pattern(C, []):
            inst = matcher.first_order_match(C, goal.prop, inst)
            for pat, prev in zip(As, prevs):
                inst = matcher.first_order_match(pat, prev.prop, inst)
        else:
            for pat, prev in zip(As, prevs):
                inst = matcher.first_order_match(pat, prev.prop, inst)
            inst = matcher.first_order_match(C, goal.prop, inst)

        # Check that every variable in the theorem has an instantiation.
        unmatched_vars = [
            v.name for v in term.get_svars(As + [C]) if v.name not in inst
        ]
        if unmatched_vars:
            raise theory.ParameterQueryException(
                list("param_" + name for name in unmatched_vars))

        # Substitute and normalize
        As, _ = th.prop.subst_norm(inst).strip_implies()
        goal_Alen = len(goal.assums)
        if goal_Alen > 0:
            As = As[:-goal_Alen]

        pts = prevs + [
            ProofTerm.sorry(Thm(goal.hyps, A)) for A in As[len(prevs):]
        ]

        # Determine whether it is necessary to provide instantiation
        # to apply_theorem.
        if set(term.get_svars(th.assums)) != set(th.prop.get_svars()) or \
           set(term.get_stvars(th.assums)) != set(th.prop.get_stvars()) or \
           not matcher.is_pattern_list(th.assums, []):
            return apply_theorem(th_name, *pts, inst=inst)
        else:
            return apply_theorem(th_name, *pts)
Ejemplo n.º 10
0
    def get_proof_term(self, goal, args, prevs):
        assert len(goal.hyps) == 0, "vcg_tactic"
        assert goal.prop.is_comb("Valid", 3), "vcg_tactic"
        P, c, Q = goal.prop.args

        # Obtain the theorem [...] |- Valid P c Q
        T = Q.get_type().domain_type()
        pt = vcg_norm(T, goal.prop)

        ptAs = [ProofTerm.sorry(Thm(goal.hyps, A)) for A in pt.assums]
        return ProofTerm("vcg", goal.prop, ptAs)
Ejemplo n.º 11
0
    def get_proof_term(self, goal, *, args=None, prevs=None):
        if args is None:
            var_names = []
        else:
            var_names = args

        vars, As, C = logic.strip_all_implies(goal.prop, var_names, svar=False)

        pt = ProofTerm.sorry(Thm(list(goal.hyps) + As, C))
        ptAs = [ProofTerm.assume(A) for A in As]
        ptVars = [ProofTerm.variable(var.name, var.T) for var in vars]
        return ProofTerm('intros', None, ptVars + ptAs + [pt])
Ejemplo n.º 12
0
    def get_proof_term(self, goal):
        th = theory.get_theorem(self.th_name)
        try:
            inst = matcher.first_order_match(th.concl, goal.prop, self.inst)
        except matcher.MatchException:
            raise TacticException('rule: matching failed')

        if any(v.name not in inst for v in th.prop.get_svars()):
            raise TacticException('rule: not all variables are matched')

        pt = ProofTerm.theorem(self.th_name).substitution(inst).on_prop(
            beta_norm_conv())
        for assum in pt.assums:
            pt = pt.implies_elim(ProofTerm.sorry(Thm(goal.hyps, assum)))
        return pt
Ejemplo n.º 13
0
    def testIntro(self):
        basic.load_theory('logic_base')
        macro = logic.intros_macro()

        Ta = TVar('a')
        x = Var('x', Ta)
        P = Var('P', TFun(Ta, BoolType))
        C = Var('C', BoolType)
        ex_P = Exists(x, P(x))
        pt1 = ProofTerm.assume(ex_P)
        pt2 = ProofTerm.variable('x', Ta)
        pt3 = ProofTerm.assume(P(x))
        pt4 = ProofTerm.sorry(Thm([P(x)], C))
        pt4 = ProofTerm('intros', args=[ex_P], prevs=[pt1, pt2, pt3, pt4])
        prf = pt4.export()
        self.assertEqual(theory.check_proof(prf), Thm([ex_P], C))
Ejemplo n.º 14
0
    def run_test(self,
                 thy_name,
                 tactic,
                 *,
                 vars=None,
                 prevs=None,
                 goal,
                 args=None,
                 new_goals=None,
                 failed=None):
        """Test a single invocation of a tactic."""
        context.set_context(thy_name, vars=vars)

        assms = [parser.parse_term(prev)
                 for prev in prevs] if prevs is not None else []
        prf = Proof(*assms)
        prevs = [
            ProofTerm.atom(i, Thm.assume(assm)) for i, assm in enumerate(assms)
        ]
        goal = parser.parse_term(goal)
        goal_pt = ProofTerm.sorry(Thm(assms, goal))

        # Invoke the tactic to get the proof term
        if failed is not None:
            self.assertRaises(failed,
                              tactic.get_proof_term,
                              goal_pt,
                              prevs=prevs,
                              args=args)
            return

        pt = tactic.get_proof_term(goal_pt, prevs=prevs, args=args)

        # Export and check proof
        prefix = ItemID(len(prevs) -
                        1) if len(prevs) > 0 else ItemID(len(prevs))
        prf = pt.export(prefix=prefix, prf=prf, subproof=False)
        self.assertEqual(theory.check_proof(prf), Thm(assms, goal))

        # Test agreement of new goals
        new_goals = [parser.parse_term(new_goal) for new_goal in new_goals
                     ] if new_goals is not None else []
        concls = [goal.prop for goal in prf.get_sorrys()]
        self.assertEqual(new_goals, concls)
Ejemplo n.º 15
0
    def get_proof_term(self, goal, *, args=None, prevs=None):
        assert isinstance(prevs, list) and len(prevs) >= 1, "apply_prev"
        pt, prev_pts = prevs[0], prevs[1:]

        # First, obtain the patterns
        new_names = logic.get_forall_names(pt.prop)
        new_vars, As, C = logic.strip_all_implies(pt.prop, new_names)
        assert len(prev_pts) <= len(As), "apply_prev: too many prev_pts"

        if args is None:
            inst = Inst()
        else:
            inst = args
        inst = matcher.first_order_match(C, goal.prop, inst)
        for idx, prev_pt in enumerate(prev_pts):
            inst = matcher.first_order_match(As[idx], prev_pt.prop, inst)

        unmatched_vars = [v for v in new_names if v not in inst]
        if unmatched_vars:
            raise theory.ParameterQueryException(
                list("param_" + name for name in unmatched_vars))

        pt = pt.subst_type(inst.tyinst)
        for new_name in new_names:
            pt = pt.forall_elim(inst[new_name])
        if pt.prop.beta_norm() != pt.prop:
            pt = pt.on_prop(beta_norm_conv())
        inst_As, inst_C = pt.prop.strip_implies()

        inst_arg = [inst[new_name] for new_name in new_names]
        new_goals = [
            ProofTerm.sorry(Thm(goal.hyps, A)) for A in inst_As[len(prev_pts):]
        ]
        if set(new_names).issubset({v.name for v in term.get_vars(As)}) and \
           matcher.is_pattern_list(As, []):
            return ProofTerm('apply_fact', args=None, prevs=prevs + new_goals)
        else:
            return ProofTerm('apply_fact_for',
                             args=inst_arg,
                             prevs=prevs + new_goals)
Ejemplo n.º 16
0
        def get_proofterm(u, v):
            """Get proof term corresponding to u = v."""
            path = explain[(u, v)]
            cur_pos = u
            pt = ProofTerm.reflexive(self.index[u])
            for eq in path:
                # Form the proof term for eq, depending on the two cases.
                if eq[0] == EQ_CONST:
                    _, a, b = eq
                    if (a, b) in self.pts:
                        eq_pt = self.pts[(a, b)]
                    else:
                        eq_pt = ProofTerm.sorry(
                            Thm([], Eq(self.index[a], self.index[b])))
                else:
                    _, ((a1, a2), a), ((b1, b2), b) = eq
                    # We already should have:
                    # - a corresponds to Comb(a1, a2)
                    # - b corresponds to Comb(b1, b2)
                    eq_pt1 = get_proofterm(
                        a1, b1) if a1 != b1 else ProofTerm.reflexive(
                            self.index[a1])
                    eq_pt2 = get_proofterm(
                        a2, b2) if a2 != b2 else ProofTerm.reflexive(
                            self.index[a2])
                    eq_pt = eq_pt1.combination(eq_pt2)

                # Append the equality to the current chain.
                if a == cur_pos:
                    pt = pt.transitive(eq_pt)
                    cur_pos = b
                else:
                    assert b == cur_pos
                    pt = pt.transitive(pt, eq_pt.symmetric())
                    cur_pos = a

            return pt
Ejemplo n.º 17
0
 def get_proof_term(self, goal):
     return ProofTerm.sorry(goal).tacs(elim_tac('conjE'), intro_imp_tac(),
                                       intro_imp_tac())
Ejemplo n.º 18
0
 def get_proof_term(self, goal):
     return ProofTerm.sorry(goal).tacs(self.tac1, self.tac2)