Esempio n. 1
0
 def step(self, s):
     s = U(s)
     if not (self.handwaving or self.is_valid_new_theorem(s)):
         raise InvalidStep()
     self.handwaving = False
     self.theorems.add(s)
     self.conclusion = s
Esempio n. 2
0
 def is_valid_by_detachment(self, s):
     s = U(s)
     for theorem in self.theorems:
         implication = u'<%s⊃%s>' % (theorem, s)
         if implication in self.theorems:
             return True  # because of the implication
     return False
Esempio n. 3
0
 def is_valid_by_interchange(self, s):
     s = U(s)
     for theorem in self.theorems:
         if len(theorem) == len(s):
             a = theorem.find(u'∀')
             while a >= 0 and s[:a] == theorem[:a]:
                 if s[a:a + 2] == u'~∃':
                     colon = theorem.find(':', a + 1)
                     u = theorem[a + 1:colon]
                     assert is_variable(u)
                     if theorem[colon + 1] == '~':
                         if s == theorem[:a] + u'~∃' + u + ':' + theorem[
                                 colon + 2:]:
                             return True
                 a = theorem.find(u'∀', a + 1)
             ne = theorem.find(u'~∃')
             while ne >= 0 and s[:ne] == theorem[:ne]:
                 if s[ne] == u'∀':
                     colon = theorem.find(':', ne + 2)
                     u = theorem[ne + 2:colon]
                     assert is_variable(u)
                     if s == theorem[:ne] + u'∀' + u + ':~' + theorem[
                             colon + 1:]:
                         return True
                 ne = theorem.find(u'~∃', ne + 2)
     return False
Esempio n. 4
0
 def is_valid_by_joining(self, s):
     s = U(s)
     if s[0] == '<' and s[-1] == '>':
         for i in range(len(s)):
             if s[i] == u'∧':
                 first, second = s[1:i], s[i + 1:-1]
                 if set([first, second]) <= self.theorems:
                     return True
     return False
Esempio n. 5
0
    def is_valid_by_double_tilde(self, s):
        s = U(s)
        if not wff.is_well_formed_formula(s):
            return False

        for theorem in self.theorems:
            if self.is_removal_of_double_tilde(
                    s, theorem) or self.is_removal_of_double_tilde(theorem, s):
                return True
        return False
Esempio n. 6
0
 def is_valid_by_separation(self, s):
     s = U(s)
     if not wff.is_well_formed_formula(s):
         return False
     for theorem in self.theorems:
         if theorem[0] == '<' and theorem[-1] == '>':
             if theorem.startswith(u'<%s∧' % s):
                 return True
             if theorem.endswith(u'∧%s>' % s):
                 return True
     return False
Esempio n. 7
0
 def is_valid_by_existence(self, s):
     s = U(s)
     if s.startswith(u'∃'):
         colon = s.find(':')
         if colon >= 0:
             u, x = s[1:colon], s[colon + 1:]
             if is_variable(u) and u in wff.get_free_variables(x):
                 for theorem in self.theorems:
                     if self._is_substitution_of_some_term_for_variable(
                             u, x, theorem):
                         return True
     return False
Esempio n. 8
0
 def is_valid_by_specification(self, s):
     s = U(s)
     for theorem in self.theorems:
         if theorem.startswith(u'∀'):
             colon = theorem.find(':')
             if colon >= 0:
                 u, x = theorem[1:colon], theorem[colon + 1:]
                 assert is_variable(u)
                 if self._is_substitution_of_some_term_for_variable(
                         u, x, s):
                     return True
     return False
Esempio n. 9
0
 def is_valid_by_induction(self, s):
     s = U(s)
     if wff.is_well_formed_formula(s) and s[0] == u'∀':
         colon = s.find(':')
         assert colon >= 0
         u, x = s[1:colon], s[colon + 1:]
         assert is_variable(u)
         base_case = x.replace(u, '0')
         if base_case in self.theorems:
             inductive_case = u'∀%s:<%s⊃%s>' % (u, x, x.replace(u, 'S' + u))
             if inductive_case in self.theorems:
                 return True
     return False
Esempio n. 10
0
 def is_valid_by_generalization(self, s):
     s = U(s)
     if s.startswith(u'∀'):
         colon = s.find(':')
         if colon >= 0:
             u, x = s[1:colon], s[colon + 1:]
             if wff.is_variable(u) and u in wff.get_free_variables(x):
                 if self.premise is not None and u in wff.get_free_variables(
                         self.premise):
                     return False
                 if x in self.theorems:
                     return True
     return False
Esempio n. 11
0
 def is_valid_by_successorship(self, s):
     s = U(s)
     equals = s.find('=')
     if equals > 0:
         first, second = s[:equals], s[equals + 1:]
         if is_term(first) and is_term(second):
             add_s = u'S%s=S%s' % (first, second)
             if add_s in self.theorems:
                 return True
             if first[0] == 'S' and second[0] == 'S':
                 drop_s = u'%s=%s' % (first[1:], second[1:])
                 if drop_s in self.theorems:
                     return True
     return False
Esempio n. 12
0
 def is_valid_new_theorem(self, s):
     s = U(s)
     return ((s in self.theorems) or self.is_valid_by_joining(s)
             or self.is_valid_by_separation(s)
             or self.is_valid_by_double_tilde(s)
             or self.is_valid_by_detachment(s)
             or self.is_valid_by_contrapositive(s)
             or self.is_valid_by_de_morgans(s)
             or self.is_valid_by_switcheroo(s)
             or self.is_valid_by_specification(s)
             or self.is_valid_by_generalization(s)
             or self.is_valid_by_interchange(s)
             or self.is_valid_by_existence(s)
             or self.is_valid_by_equality(s)
             or self.is_valid_by_successorship(s)
             or self.is_valid_by_induction(s) or False)
Esempio n. 13
0
 def is_valid_by_equality(self, s):
     s = U(s)
     equals = s.find('=')
     if equals > 0:
         first, second = s[:equals], s[equals + 1:]
         if is_term(first) and is_term(second):
             symmetrical_s = u'%s=%s' % (second, first)
             if symmetrical_s in self.theorems:
                 return True
         for theorem in self.theorems:
             if theorem.startswith(first + '='):
                 middle = theorem[len(first) + 1:]
                 transitive_s = u'%s=%s' % (middle, second)
                 if transitive_s in self.theorems:
                     return True
     return False
Esempio n. 14
0
 def _is_valid_by_substituting(self, s, a, b):
     s = U(s)
     for xi in range(0, len(s)):
         for xj in range(xi + 1, len(s)):
             x = s[xi:xj]
             if wff.is_well_formed_formula(x):
                 for yi in range(0, len(s)):
                     for yj in range(yi + 1, len(s)):
                         y = s[yi:yj]
                         if wff.is_well_formed_formula(y):
                             first = a.replace('X', x).replace('Y', y)
                             if len(first) > len(s):
                                 continue
                             second = b.replace('X', x).replace('Y', y)
                             i = s.find(first)
                             while i != -1:
                                 substituted_s = s[:i] + second + s[
                                     i + len(first):]
                                 if substituted_s in self.theorems:
                                     return True
                                 i = s.find(first, i + 1)
     return False
Esempio n. 15
0
 def fantasy(self, premise):
     f = Derivation([U(premise), self.theorems.copy()])
     yield f
     s = u'<%s⊃%s>' % (f.premise, f.conclusion)
     self.theorems.add(s)
     self.conclusion = s
Esempio n. 16
0
def check_well_formed_formula(s):
    s = U(s)
    opr, opd = [], []

    def opr_top():
        return opr[-1] if opr else 'X'

    def opr_push(x):
        return opr.append(x)

    def opd_push(x):
        assert not (x[2] & x[3])
        return opd.append(x)

    nope = FormulaInfo(False, set(), set())
    try:
        for token in re.split(u'(S*0)|(S*[a-z]′*)|(S+)|(.)', s):
            if not token:
                continue
            if is_variable(token):
                if opr_top() in u'∀∃':
                    opd_push(['V', token, set([token]), set()])
                else:
                    opd_push(['T', token, set([token]), set()])
            elif re.match(u'(S*0)|(S*[a-z]′*)', token):
                opd_push(
                    ['T', token,
                     get_free_variables_in_term(token),
                     set()])
            elif re.match('S+', token):
                opr_push(token)
            elif token in u'<(∀∃:+⋅~':
                opr_push(token)
            elif token == '=':
                if re.match('S+', opr_top()):
                    op = opr.pop()
                    t1 = opd.pop()
                    if t1[0] != 'T': return nope
                    opd_push(['T', op + t1[1], t1[2], set()])
                opr_push(token)
            elif token == ')':
                t2 = opd.pop()
                t1 = opd.pop()
                op = opr.pop()
                if opr.pop() != '(': return nope
                if op not in u'+⋅': return nope
                if t1[0] != 'T' or t2[0] != 'T': return nope
                opd_push([
                    'T',
                    u'(%s%s%s)' % (t1[1], op, t2[1]), t1[2] | t2[2],
                    set()
                ])
                if re.match('S+', opr_top()):
                    op = opr.pop()
                    t1 = opd.pop()
                    opd_push(['T', op + t1[1], t1[2], set()])
            elif token in u'∧∨⊃':
                if re.match('S+', opr_top()):
                    op = opr.pop()
                    t1 = opd.pop()
                    if t1[0] != 'T': return nope
                    opd_push(['T', op + t1[1], t1[2], set()])
                if opr_top() == '=':
                    t2 = opd.pop()
                    t1 = opd.pop()
                    op = opr.pop()
                    if t1[0] != 'T' or t2[0] != 'T': return nope
                    opd_push(
                        ['F',
                         u'%s=%s' % (t1[1], t2[1]), t1[2] | t2[2],
                         set()])
                while opr_top() in ':~':
                    op = opr.pop()
                    if op == '~':
                        t1 = opd.pop()
                        if t1[0] != 'F': return nope
                        opd_push(['F', u'~%s' % t1[1], t1[2], t1[3]])
                    elif op == ':':
                        x = opd.pop()
                        v = opd.pop()
                        op = opr.pop()
                        if op not in u'∀∃': return nope
                        if x[0] != 'F' or v[0] != 'V': return nope
                        if v[1] not in x[2]: return nope  # v must be free in x
                        opd_push([
                            'F',
                            u'%s%s:%s' % (op, v[1], x[1]), x[2] - set([v[1]]),
                            x[3] | set([v[1]])
                        ])
                opr_push(token)
            elif token == '>':
                if opr_top() == '=':
                    t2 = opd.pop()
                    t1 = opd.pop()
                    op = opr.pop()
                    if t1[0] != 'T' or t2[0] != 'T': return nope
                    opd_push(
                        ['F',
                         u'%s=%s' % (t1[1], t2[1]), t1[2] | t2[2],
                         set()])
                while opr_top() in ':~':
                    op = opr.pop()
                    if op == '~':
                        t1 = opd.pop()
                        if t1[0] != 'F': return nope
                        opd_push(['F', u'~%s' % t1[1], t1[2], t1[3]])
                    elif op == ':':
                        x = opd.pop()
                        v = opd.pop()
                        op = opr.pop()
                        if op not in u'∀∃': return nope
                        if x[0] != 'F' or v[0] != 'V': return nope
                        if v[1] not in x[2]: return nope  # v must be free in x
                        opd_push([
                            'F',
                            u'%s%s:%s' % (op, v[1], x[1]), x[2] - set([v[1]]),
                            x[3] | set([v[1]])
                        ])
                t2 = opd.pop()
                t1 = opd.pop()
                op = opr.pop()
                if opr.pop() != '<': return nope
                if op not in u'∧∨⊃': return nope
                if t1[0] != 'F' or t2[0] != 'F': return nope
                fv = (t1[2] | t2[2])
                qv = (t1[3] | t2[3])
                if (fv & qv):
                    return nope
                opd_push(['F', u'<%s%s%s>' % (t1[1], op, t2[1]), fv, qv])
            else:
                assert False
        while opr:
            if re.match('S+', opr_top()):
                op = opr.pop()
                t1 = opd.pop()
                if t1[0] != 'T': return nope
                opd_push(['T', op + t1[1], t1[2], set()])
            elif opr_top() == '=':
                t2 = opd.pop()
                t1 = opd.pop()
                op = opr.pop()
                if t1[0] != 'T' or t2[0] != 'T': return nope
                opd_push(
                    ['F', u'%s=%s' % (t1[1], t2[1]), t1[2] | t2[2],
                     set()])
            elif opr_top() == '~':
                t1 = opd.pop()
                assert opr.pop() == '~'
                if t1[0] != 'F': return nope
                opd_push(['F', u'~%s' % t1[1], t1[2], t1[3]])
            elif opr_top() == ':':
                x = opd.pop()
                v = opd.pop()
                assert opr.pop() == ':'
                op = opr.pop()
                if op not in u'∀∃': return nope
                if x[0] != 'F' or v[0] != 'V': return nope
                if v[1] not in x[2]: return nope  # v must be free in x
                opd_push([
                    'F',
                    u'%s%s:%s' % (op, v[1], x[1]), x[2] - set([v[1]]),
                    x[3] | set([v[1]])
                ])
            else:
                return nope
        result = opd.pop()
        if opd: return nope
        if result[1] != s:
            print 'x is ', s
            print 'r is ', result[1]
            assert False
        return FormulaInfo(result[0] == 'F', result[2], result[3])
    except IndexError:
        # Failed to pop something from one of the two stacks.
        return nope