Ejemplo n.º 1
0
    def ABS(
            self,
            idx1: int,
            v: Term,
            fake: bool = False,
    ) -> Thm:
        assume(v.token() == '__v')

        assume(idx1 in self._theorems)
        thm1 = self._theorems[idx1]
        c1 = thm1.concl()

        assume(c1.token() == '__C')
        assume(c1.left.token() == '__C')
        assume(c1.left.left.token() == '__c')
        assume(c1.left.left.left.token() == '=')

        l1 = c1.left.right
        r1 = c1.right

        assume(len(list(filter(
            lambda t: self.free_in(v, t),
            thm1.hyp(),
        ))) == 0)

        return self._theorem(
            thm1.hyp(),
            self.safe_mk_eq(
                Term(1, v, l1, '__A'),
                Term(1, v, r1, '__A'),
            ),
            fake,
        )
Ejemplo n.º 2
0
    def type_of(
            self,
            term: Term,
    ) -> Type:
        if term.token() == '__v':
            assert type(term.right.value) is Type
            return term.right.value

        if term.token() == '__c':
            assert type(term.right.value) is Type
            return term.right.value

        if term.token() == '__C':
            ty = self.type_of(term.left)
            assert ty.token() == '__c'
            assert ty.left.token() == 'fun'
            assert ty.right.token() == '__a'
            assert ty.right.right.token() == '__a'
            assert ty.right.right.left is not None
            return ty.right.right.left

        if term.token() == '__A':
            return self.fun_type(
                self.type_of(term.left),
                self.type_of(term.right),
            )
Ejemplo n.º 3
0
    def MK_COMB(
            self,
            idx1: int,
            idx2: int,
            fake: bool = False,
    ) -> Thm:
        assume(idx1 in self._theorems)
        assume(idx2 in self._theorems)

        thm1 = self._theorems[idx1]
        thm2 = self._theorems[idx2]

        c1 = thm1.concl()
        c2 = thm2.concl()

        assume(c1.token() == '__C')
        assume(c1.left.token() == '__C')
        assume(c1.left.left.token() == '__c')
        assume(c1.left.left.left.token() == '=')

        l1 = c1.left.right
        r1 = c1.right

        assume(c2.token() == '__C')
        assume(c2.left.token() == '__C')
        assume(c2.left.left.token() == '__c')
        assume(c2.left.left.left.token() == '=')

        l2 = c2.left.right
        r2 = c2.right

        tyr1 = self.type_of(r1)

        assume(tyr1.token() == '__c')
        assume(tyr1.left.token() == 'fun')

        # TODO(stan): investigate
        assume(tyr1.right is not None)

        ty = tyr1.right.left
        tyr2 = self.type_of(r2)

        assume(ty.type_string() == tyr2.type_string())

        return self._theorem(
            self.term_union(thm1.hyp(), thm2.hyp()),
            self.safe_mk_eq(
                Term(0, l1, l2, '__C'),
                Term(0, r1, r2, '__C'),
            ),
            fake,
        )
Ejemplo n.º 4
0
 def inst(tm, subst_type, env):
     if tm.token() == '__v':
         ty = tsubst(tm.right.value, subst_type)
         stm = Term(3, tm.left, Term(ty, None, None, None), '__v')
         if ty.hash() == tm.right.value.hash():
             stm = tm
         ttm = tm
         for s in env:
             if s[0].term_string() == stm.term_string():
                 ttm = s[1]
         if ttm.term_string() != tm.term_string():
             raise Clash(stm)
         return stm
     if tm.token() == '__c':
         ty = tsubst(tm.right.value, subst_type)
         if ty.hash() == tm.right.value.hash():
             return tm
         return Term(2, tm.left, Term(ty, None, None, None), '__c')
     if tm.token() == '__C':
         ltm = inst(tm.left, subst_type, env)
         rtm = inst(tm.right, subst_type, env)
         if ltm.hash() == tm.left.hash() and \
                 rtm.hash() == tm.right.hash():
             return tm
         else:
             return Term(0, ltm, rtm, '__C')
     if tm.token() == '__A':
         v = inst(tm.left, subst_type, [])
         try:
             b = inst(tm.right, subst_type, env + [[v, tm.left]])
             if v.hash() == tm.left.hash() and \
                     b.hash() == tm.right.hash():
                 return tm
             else:
                 return Term(1, v, b, '__A')
         except Clash as e:
             assume(e.term.term_string() == v.term_string())
             frees = [inst(v, subst_type, [])
                      for v in self.frees(tm.right)]
             vv = self.variant(frees, v)
             assume(vv.token() == '__v')
             assume(v.token() == '__v')
             z = Term(3, vv.left, tm.left.right, '__v')
             return inst(
                 Term(1, z, self.subst(
                     tm.right, [[tm.left, z]]
                 ), '__A'),
                 subst_type,
                 env,
             )
Ejemplo n.º 5
0
 def token_term(
         self,
         token,
 ) -> Type:
     if token == '=':
         return Term(5, None, None, '=')
     assert False
Ejemplo n.º 6
0
    def safe_mk_eq(
            self,
            left: Term,
            right: Term,
    ) -> Term:
        ty = self.type_of(left)

        return Term(
            0,
            Term(
                0, Term(
                    2, self.token_term('='),
                    Term(
                        self.fun_type(
                            ty,
                            self.fun_type(ty, self.bool_type()),
                        ), None, None, None,
                    ), '__c'
                ), left, '__C',
            ), right, '__C',
        )
Ejemplo n.º 7
0
 def vsubst(tm, subst):
     if len(subst) == 0:
         return tm
     if tm.token() == '__v':
         for s in subst:
             if s[0].term_string() == tm.term_string():
                 assume(self.type_of(tm).type_string() ==
                        self.type_of(s[1]).type_string())
                 return s[1]
         return tm
     if tm.token() == '__c':
         return tm
     if tm.token() == '__C':
         ltm = vsubst(tm.left, subst)
         rtm = vsubst(tm.right, subst)
         if ltm.hash() == tm.left.hash() and \
                 rtm.hash() == tm.right.hash():
             return tm
         else:
             return Term(0, ltm, rtm, '__C')
     if tm.token() == '__A':
         v = tm.left
         fsubst = list(filter(
             lambda s: s[0].term_string() != v.term_string(),
             subst,
         ))
         b = vsubst(tm.right, fsubst)
         if b.hash() == tm.right.hash():
             return tm
         if len(list(filter(
                 lambda s: (self.free_in(v, s[1]) and
                            self.free_in(s[0], tm.right)),
                 fsubst,
         ))) > 0:
             vv = self.variant([b], v)
             return Term(1, vv, vsubst(
                 tm.right, fsubst + [[v, vv]]
             ), '__A')
         return Term(1, v, b, '__A')
Ejemplo n.º 8
0
    def variant(
            self,
            avoid: typing.List[Term],
            v: Term,
    ):
        assume(v.token() == '__v')

        if len(list(filter(
            lambda t: self.free_in(v, t),
            avoid,
        ))) == 0:
            return v

        token = v.left.token() + '\''

        if token not in self._t._term_tokens:
            self._t._term_tokens[token] = len(self._t._term_tokens)

        return self.variant(
            avoid,
            Term(3, Term(
                self._t._term_tokens[token], None, None, token
            ), v.right, '__v'),
        )
Ejemplo n.º 9
0
    def free_in(
            self,
            v: Term,
            term: Term,
    ) -> bool:
        assume(v.token() == '__v')

        def vfree_in(v, tm):
            if tm.token() == '__A':
                return v.term_string() != tm.left.term_string() and \
                    vfree_in(v, tm.right)
            if tm.token() == '__C':
                return vfree_in(v, tm.left) or vfree_in(v, tm.right)
            return v.term_string() == tm.term_string()

        return vfree_in(v, term)
Ejemplo n.º 10
0
    def BETA(
            self,
            term: Term,
            fake: bool = False,
    ) -> Thm:
        assume(term.token() == '__C')
        assume(term.left.token() == '__A')

        v = term.left.left
        bod = term.left.right
        arg = term.right

        assume(v.term_string() == arg.term_string())

        return self._theorem(
            [],
            self.safe_mk_eq(term, bod),
            fake,
        )
Ejemplo n.º 11
0
    def TRANS(
            self,
            idx1: int,
            idx2: int,
            fake: bool = False,
    ) -> Thm:
        assume(idx1 in self._theorems)
        assume(idx2 in self._theorems)

        thm1 = self._theorems[idx1]
        thm2 = self._theorems[idx2]

        c1 = thm1.concl()
        c2 = thm2.concl()

        assume(c1.token() == '__C')
        assume(c1.left.token() == '__C')
        assume(c1.left.left.token() == '__c')
        assume(c1.left.left.left.token() == '=')

        eql = c1.left
        m1 = c1.right

        assume(c2.token() == '__C')
        assume(c2.left.token() == '__C')
        assume(c2.left.left.token() == '__c')
        assume(c2.left.left.left.token() == '=')

        r = c2.right
        m2 = c2.left.right

        assume(m1.term_string(True) == m2.term_string(True))

        return self._theorem(
            self.term_union(thm1.hyp(), thm2.hyp()),
            Term(0, eql, r, '__C'),
            fake,
        )