Ejemplo n.º 1
0
    def coalesce(self, other):

        import logical.Connective as Connective

        if not isinstance(other, type(self)):
            raise ValueError(
                "Can't coalesce quantifiers of different types {} {}".format(
                    repr(self), repr(other)))

        s = copy.deepcopy(self)
        o = copy.deepcopy(other)

        less, more = (s, o) if len(s.variables) < len(o.variables) else (o, s)
        translation = {
            old: new
            for old, new in zip(less.variables, more.variables)
        }

        less = less.rename(translation)

        terms = less.get_term()
        terms.extend(more.get_term())

        if isinstance(self, Universal):
            ret = type(self)(more.variables, Connective.Conjunction(terms))
        else:
            ret = type(self)(more.variables, Connective.Disjunction(terms))

        return ret
Ejemplo n.º 2
0
def p_biconditional(p):
    """
    biconditional : LPAREN IFF axiom axiom RPAREN
    """

    p[0] = Connective.Conjunction([
        Connective.Disjunction([Negation.Negation(p[3]), p[4]]),
        Connective.Disjunction([Negation.Negation(p[4]), p[3]])
    ])
Ejemplo n.º 3
0
    def __and__(self, other):
        '''
        Operator overload for the '&' command, to simplify first-order logic
        operations.

        :return Connective.Conjunction()
        '''

        import logical.Connective as Connective

        return Connective.Conjunction([self, other])
Ejemplo n.º 4
0
    def push(self):
        '''
        Push negation inwards and apply to all children
        '''

        # Can be a conjunction or disjunction
        # Can be a single predicate
        # Can be a quantifier

        if isinstance(self.term(), Connective.Conjunction):

            ret = Connective.Disjunction([Negation(x) for x in self.term().get_term()])

        elif isinstance(self.term(), Connective.Disjunction):

            ret = Connective.Conjunction([Negation(x) for x in self.term().get_term()])

        elif isinstance(self.term(), Symbol.Predicate):

            ret = self

        elif isinstance(self.term(), Quantifier.Existential):

            ret = Quantifier.Universal(self.term().variables, Negation(self.term().get_term()))

        elif isinstance(self.term(), Quantifier.Universal):

            ret = Quantifier.Existential(self.term().variables, Negation(self.term().get_term()))

        elif isinstance(self.term(), Negation):

            ret = self.term().term()

        else:

            raise ValueError("Negation onto unknown type!", self.term)

        return copy.deepcopy(ret)
Ejemplo n.º 5
0
    def substitute_function(self, negated = False):
        '''
        Find a function that's nested and replace it by adding a new variable and term
        '''

        # TODO This a dirty hack because cyclic imports are painful
        import logical.Quantifier as Quantifier
        import logical.Negation as Negation
        import logical.Connective as Connective

        global gen

        def sub_functions(term, predicates, variables):
            '''
            Does three things: (1) returns a variable that serves as the placeholder 
            for the function. (2) adds a minted predicate to the accumulator (3) adds
            any the newly introduced variable for each function to the accumulator
            '''

            # Singleton used to access an increasing integer sequence
            global gen

            # Base Case 0: I'm not event a function, I'm a variable
            if isinstance(term, str):
                
                # I'm a variable so I go in the variable accumulator
                variables.append(term)

                return term

            # Base Case 1: I'm a function with no nested functions!
            if isinstance(term, Function) and term.has_functions() == False:

                # Mint a new variable special
                new_variable = term.name.lower()[0] + gen()
                variables.append(new_variable)


                # Mint a new predicate with our original variables + the new one
                predicate_variables = term.variables
                predicate_variables.append(new_variable)

                predicate = Predicate(term.name, predicate_variables)
                predicates.append(predicate)

                # Return our fresh variable
                return new_variable

            # Recursive Case: I'm a function with nested functions!
            if isinstance(term, Function): #and term.has_functions() == True:

                # Still mint a new variable cuz I'm still a function
                new_variable = term.name.lower()[0] + gen()
                variables.append(new_variable)

                # Assemble my variables by a DFS down on my function / atom children
                predicate_variables = [sub_functions(x, predicates, variables) for x in term.variables]
                predicate_variables.append(new_variable)

                predicate = Predicate(term.name, predicate_variables)
                predicates.append(predicate)

                return new_variable

        predicate_accumulator = []
        variable_accumulator = []

        variables = [sub_functions(x, predicate_accumulator, variable_accumulator) for x in self.variables]
        if len(predicate_accumulator) > 1:
            term = Connective.Conjunction(predicate_accumulator)
        else:
            term = predicate_accumulator.pop()

        predicate = Predicate(self.name, variables)

        if negated:
            # The negation cancels out the normal conditional breakdown
            universal = Quantifier.Universal(variable_accumulator, predicate | term)
        else:
            universal = Quantifier.Universal(variable_accumulator, ~predicate | term)

        return universal, predicate_accumulator
Ejemplo n.º 6
0
def p_conjunction(p):
    """
    conjunction : LPAREN AND axiom_list RPAREN
    """

    p[0] = Connective.Conjunction(p[3])