예제 #1
0
    def _proposition_skeleton_helper(f: Formula,
                                     f2z: Mapping[Formula,
                                                  PropositionalFormula],
                                     z2f: Mapping[str, Formula]):

        # case equality, relation, quantifier
        if is_equality(f.root) or is_relation(f.root) or is_quantifier(f.root):
            if f in f2z.keys():
                return f2z[f]
            else:
                new_z = next(fresh_variable_name_generator)
                f_as_proposition = PropositionalFormula(new_z)
                z2f[new_z] = f
                f2z[f] = f_as_proposition
                return f_as_proposition

        # deeper recursion cases
        if is_unary(f.root) or is_binary(f.root):
            new_first = Formula._proposition_skeleton_helper(f.first, f2z, z2f)

            if is_binary(f.root):
                new_second = Formula._proposition_skeleton_helper(
                    f.second, f2z, z2f)
                return PropositionalFormula(f.root, new_first, new_second)

            return PropositionalFormula(f.root, new_first)
예제 #2
0
 def compile_formula(self, skeleton: Dict[str, Formula], reversed_skeleton=None) -> Formula:
     """
     compiles the formula for the needed skeleton, as well as updating the mapping between every z to its formula
     representative
     :param skeleton: str to formula
     :param reversed_skeleton: formula to str
     :return: compiled formula
     """
     if reversed_skeleton is None:
         reversed_skeleton = dict()
     if is_binary(self.root):
         compiled_formula1 = self.first.compile_formula(skeleton, reversed_skeleton)
         compiled_formula2 = self.second.compile_formula(skeleton, reversed_skeleton)
         compiled_formula = PropositionalFormula(self.root, compiled_formula1, compiled_formula2)
     elif is_unary(self.root):
         compiled_formula1 = self.first.compile_formula(skeleton, reversed_skeleton)
         compiled_formula = PropositionalFormula(self.root, compiled_formula1)
     else:
         if self in reversed_skeleton:
             return reversed_skeleton[self]
         z = next(fresh_variable_name_generator)
         parsed_z = PropositionalFormula.parse(z)
         skeleton[z] = self
         reversed_skeleton[self] = parsed_z
         return parsed_z
     return compiled_formula
예제 #3
0
    def propositional_skeleton_helper(self, mapping: Mapping[str, Formula]) \
            -> Tuple[PropositionalFormula, Mapping[str, Formula]]:

        if is_quantifier(self.root) or is_relation(self.root) or is_equality(
                self.root):
            mapping = dict(mapping)
            for key in mapping.keys():
                if mapping[key] == self:
                    return PropositionalFormula(key), mapping
            atomic_variable = next(fresh_variable_name_generator)
            mapping[atomic_variable] = self
            return PropositionalFormula(atomic_variable), mapping

        elif is_unary(self.root):
            temp_formula, mapping = Formula.propositional_skeleton_helper(
                self.first, mapping)
            return PropositionalFormula(self.root, temp_formula), mapping

        elif is_binary(self.root):
            temp_formula1, mapping = Formula.propositional_skeleton_helper(
                self.first, mapping)
            temp_formula2, mapping = Formula.propositional_skeleton_helper(
                self.second, mapping)
            return PropositionalFormula(self.root, temp_formula1,
                                        temp_formula2), mapping
예제 #4
0
    def propositional_skeleton(self, mapping=None) ->\
            Tuple[PropositionalFormula, Mapping[str, Formula]]:
        """Computes a propositional skeleton of the current formula.

        Returns:
            A pair. The first element of the pair is a propositional formula
            obtained from the current formula by substituting every (outermost)
            subformula that has a relation or quantifier at its root with an
            atomic propositional formula, consistently such that multiple equal
            such (outermost) subformulas are substituted with the same atomic
            propositional formula. The atomic propositional formulas used for
            substitution are obtained, from left to right, by calling
            `next`\ ``(``\ `~logic_utils.fresh_variable_name_generator`\ ``)``.
            The second element of the pair is a map from each atomic
            propositional formula to the subformula for which it was
            substituted.
        """
        # Task 9.8
        if not is_binary(self.root) and not is_unary(self.root):
            if mapping is not None:
                # check if the formula was already seen, if so, don't remap it
                if self in mapping.keys():
                    return PropositionalFormula(mapping[self]), dict()
            # else, not in mapping, define a new variable for it
            new = next(fresh_variable_name_generator)
            pf = PropositionalFormula(new)
            m = {new: self}
            # return propositional skeleton of the Formula
            return pf, m
        if is_unary(self.root):
            # get the first's side propositional skeleton
            ps1 = Formula.propositional_skeleton(self.first, mapping)
            pf = PropositionalFormula(self.root, first=ps1[0])
            # return new propositional formula and the map
            return pf, ps1[1]
        if is_binary(self.root):
            # get the first's side propositional skeleton
            ps1 = Formula.propositional_skeleton(self.first, mapping)
            if mapping is not None:
                new_dict = dict(mapping)
            else:
                new_dict = dict()
            for key in ps1[1]:
                new_dict[ps1[1][key]] = key
            # get the second's side propositional skeleton
            ps2 = Formula.propositional_skeleton(self.second, new_dict)
            pf = PropositionalFormula(self.root, first=ps1[0], second=ps2[0])
            joined_map = dict(ps1[1])
            joined_map.update(ps2[1])
            # return new propositional formula and the two sides joined map
            return pf, joined_map
예제 #5
0
 def propositional_skeleton_helper(self, switches_dict):
     if is_unary(self.root):
         return PropositionalFormula(
             self.root,
             self.first.propositional_skeleton_helper(switches_dict))
     if is_binary(self.root):
         return PropositionalFormula(
             self.root,
             self.first.propositional_skeleton_helper(switches_dict),
             self.second.propositional_skeleton_helper(switches_dict))
     if self in switches_dict:
         return switches_dict[self]
     else:
         value = PropositionalFormula(next(fresh_variable_name_generator))
         switches_dict[self] = value
         return value
예제 #6
0
파일: syntax.py 프로젝트: shaigindin/Logic
    def helper(self, already_map: dict) -> Tuple[PropositionalFormula, dict]:
        if is_quantifier(self.root) or is_equality(self.root) or is_relation(
                self.root):
            # d = dict()
            if self in already_map.values():
                for key in already_map.keys():
                    if already_map[key] == self:
                        return (PropositionalFormula.parse(key), already_map)
            new_fresh_var = next(fresh_variable_name_generator)
            already_map[new_fresh_var] = self
            return (PropositionalFormula.parse(new_fresh_var), already_map)

        if is_unary(self.root):
            formula1, d = self.first.helper(already_map)
            return (PropositionalFormula("~", formula1), d)
        if is_binary(self.root):
            formula1, d1 = self.first.helper(already_map)
            formula2, d2 = self.second.helper(d1)
            return (PropositionalFormula(self.root, formula1, formula2), d2)
예제 #7
0
 def propositional_skeleton_helper(self, form_dict):
     """
     A recursive helper for the propositional_skeleton method.
     :param form_dict: a dictionary of types {str : formula} mapping each variable to
     the formula he assigned for.
     :return:
         A pair. The first element of the pair is a propositional formula
         obtained from the current formula by substituting every (outermost)
         subformula that has a relation or quantifier at its root with an
         atomic propositional formula, consistently such that multiple equal
         such (outermost) subformulas are substituted with the same atomic
         propositional formula. The atomic propositional formulas used for
         substitution are obtained, from left to right, by calling
         `next`\ ``(``\ `~logic_utils.fresh_variable_name_generator`\ ``)``.
         The second element of the pair is a map from each atomic
         propositional formula to the subformula for which it was
         substituted.
     """
     if is_unary(self.root):
         form_var, form_dict = self.first.propositional_skeleton_helper(
             form_dict)
         str_form = PropositionalFormula(self.root, form_var)
         return str_form, form_dict
     if is_binary(self.root):
         form_var1, form_dict = self.first.propositional_skeleton_helper(
             form_dict)
         form_var2, form_dict = self.second.propositional_skeleton_helper(
             form_dict)
         str_form = PropositionalFormula(self.root, form_var1, form_var2)
         return str_form, form_dict
     form_var = False
     for k, v in form_dict.items():
         if v == self:
             form_var = k
     if not form_var:
         form_var = next(fresh_variable_name_generator)
         form_dict[form_var] = self
     return PropositionalFormula(form_var), form_dict
예제 #8
0
        def recursive_skeleton_helper(formula : PropositionalFormula, formula_map : Mapping[str, Formula]):

            # base case: formula is a relation equality or quantifier:
            if is_relation(formula.root) or is_quantifier(formula.root) or is_equality(formula.root):
                # check if the value is in the map
                for key, val in formula_map.items():
                    if str(val) == str(formula):
                        return PropositionalFormula(key), formula_map
                else:
                    new_term = Term(next(fresh_variable_name_generator))
                    formula_map[str(new_term)] = formula
                    return PropositionalFormula(new_term.root), formula_map

            # unary recursive call
            if is_unary(formula.root):
                first_child_term, formula_map_first = recursive_skeleton_helper(formula.first, formula_map)
                return PropositionalFormula(formula.root, first_child_term), formula_map_first

            # binary recursive call
            if is_binary(formula.root):
                first_child_term, formula_map_first = recursive_skeleton_helper(formula.first, formula_map)
                second_child_term, formula_map_second = recursive_skeleton_helper(formula.second, formula_map_first)
                merged_map = formula_map_second
                return PropositionalFormula(formula.root, first_child_term, second_child_term), merged_map
예제 #9
0
    def propositional_skeleton_helper(self, map):
        """Computes a propositional skeleton of the current formula.

                Args:
                    map: the current map of  from each atomic propositional formula to the subformula for
                    which it was substituted.

                Returns:
                    A pair. The first element of the pair is a propositional formula
                    obtained from the current formula by substituting every (outermost)
                    subformula that has a relation or quantifier at its root with an
                    atomic propositional formula, consistently such that multiple equal
                    such (outermost) subformulas are substituted with the same atomic
                    propositional formula. The atomic propositional formulas used for
                    substitution are obtained, from left to right, by calling
                    `next`\ ``(``\ `~logic_utils.fresh_variable_name_generator`\ ``)``.
                    The second element of the pair is a mapping from each atomic
                    propositional formula to the subformula for which it was
                    substituted.
        """
        root = self.root

        if is_unary(root):
            for key in map:
                if self.first == map[key]:  # first arg already in the map
                    return PropositionalFormula(root,
                                                PropositionalFormula(key)), map

            first, first_map = self.first.propositional_skeleton_helper(map)

            return PropositionalFormula(root, first), map

        elif is_binary(root):
            for key in map:
                if self.first == map[key]:
                    first = PropositionalFormula(
                        key)  # first arg already in the map
                    break
            else:
                # first arg not in the map yet
                first, first_map = self.first.propositional_skeleton_helper(
                    map)

            for key in map:
                if map[key] == self.second:
                    second = PropositionalFormula(
                        key)  # second arg already in the map
                    break
            else:
                # second arg not in the map yet
                second, second_map = self.second.propositional_skeleton_helper(
                    map)

            return PropositionalFormula(root, first, second), map

        else:
            for key in map:
                if map[key] == self:  # formula in map already
                    return PropositionalFormula(key), map

            var_name = next(fresh_variable_name_generator)
            map[var_name] = self
            return PropositionalFormula(var_name), map