示例#1
0
def propositional_prove(formula: str, assumptions: List[str]):
    from propositions.syntax import Formula
    from propositions.tautology import proof_or_counterexample, prove_in_model, evaluate, all_models
    from propositions.tautology import prove_tautology, encode_as_formula
    from propositions.proofs import InferenceRule

    f = Formula.parse(formula)
    if f is None:
        print_error('Could not parse the given formula')
        return None

    collected_assumptions = []
    for assumption in assumptions:
        a = Formula.parse(assumption)
        if a is None:
            print_error('Could not parse the given assumption')
            return None
        collected_assumptions.append(a)

    f = encode_as_formula(InferenceRule(collected_assumptions, f))

    valid_proofs = []
    for model in all_models(list(f.variables())):
        if not evaluate(f, model):
            valid_proofs.append(prove_in_model(f, model))

    if len(valid_proofs) > 0:
        print_result('Found valid proof:\n' + str(valid_proofs))
        return True

    print_result('No valid proof.\n' + str(proof_or_counterexample(f)))
    return False
示例#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_convert_to(formula: str, to: str):
    from propositions.syntax import Formula
    from propositions.operators import to_implies_false, to_implies_not, to_nand, to_not_and, to_not_and_or

    f = Formula.parse(formula)
    if f is None:
        print_error('Could not parse the given formula')
        return None

    to = to.lower().strip('to_')
    if to == 'implies_false':
        f = to_implies_false(f)
    elif to == 'implies_not':
        f = to_implies_not(f)
    elif to == 'nand':
        f = to_nand(f)
    elif to == 'not_and':
        f = to_not_and(f)
    elif to == 'not_and_or':
        f = to_not_and_or(f)
    else:
        print_error('Undefined action: ' + to +
                    '. Allowed actions are: implies_false, implies_not, '
                    'nand, not_and, not_and_or.')
        return False

    print_result(str(f))
    return True
示例#4
0
def propositional_is_consistent(formulas: List[str]):
    from propositions.syntax import Formula
    from propositions.tautology import all_models, evaluate
    from propositions.operators import to_implies_not

    formulas_list = []
    for f in formulas:
        f = Formula.parse(f)
        if f is None:
            print_error('Could not parse the given formula')
            return None
        f = to_implies_not(f)
        formulas_list.append(f)

    all_variables = list()
    for formula in formulas_list:
        all_variables += list(formula.variables())

    # Check if we got a formula that doesn't evaluate to true with one of the models
    for model in all_models(all_variables):
        if not any(True for f in formulas_list if not evaluate(f, model)):
            print_result('Formulas: ' + str(formulas) +
                         '\nThat is consistent! Model: ' + str(model))
            return True

    print_result('Formulas: ' + str(formulas) + '\nThat is NOT consistent!')
    return False
示例#5
0
def predicate_try_find_world(formula: str,
                             relation: str,
                             arity: int,
                             max_item: int = 4):
    from predicates.prenex import to_prenex_normal_form
    from predicates.syntax import Formula
    from predicates.semantics import Model
    from itertools import product, combinations
    f = Formula.parse(formula)
    if f is None:
        print_error('Could not parse the given formula')
        return None

    world = set(range(1, max_item))
    world_prod = set(product(world, repeat=arity))
    i = 1
    while i < 10:
        cbns = list(combinations(world_prod, i))
        if len(cbns) == 0:
            break
        i += 1

        for cbn in cbns:
            try:
                m = Model(world, {str(k): k
                                  for k in world}, {str(relation): set(cbn)})
                if m.is_model_of({f}):
                    print_result('Found Model!\nWorld: ' + str(world) +
                                 "\nModel: " + str(m))
                    return True
            except:
                pass
    print_error('Couldnt find model. Maybe we should try different args.')
示例#6
0
def run_sat_cnf(formula: str):
    """run sat solver on CNF formula without redundancies"""
    f_prop = propositional_Formula.parse(formula)
    to_solve = Sat_Solver(f_prop)

    msg, _ = to_solve.start_sat()
    if msg is not True:
        return msg, None

    to_decide = True
    decision_var = BUG_MSG

    while True:

        # decide
        if to_decide:
            decision_var, assignments = to_solve.decide()
            if decision_var == SAT_MSG:
                return SAT_MSG, assignments
        else:
            to_decide = True

        # propagate
        assert decision_var != BUG_MSG  # sanity check
        conflict_clause, backjump_level = to_solve.propagate(decision_var)

        # backtrack
        if conflict_clause is not True and conflict_clause != UNSAT_MSG:
            to_solve.backtrack(conflict_clause, backjump_level)
            to_decide = False
            decision_var = BACKTRACK_MSG

        if conflict_clause is UNSAT_MSG:
            return UNSAT_MSG, None
示例#7
0
def run_sat_solver(formula: str):
    """preprocess non cnf formula with redundancies and then hand off to sat solver"""
    f_prop = propositional_Formula.parse(formula)

    # tseitin and preprocessing
    f_tseitin = propositions.tseitin.to_tseitin(f_prop)
    f_tseitin_processed = propositions.tseitin.preprocess_clauses(f_tseitin)
    if f_tseitin_processed.root == 'F':
        return UNSAT_MSG, None
    elif f_tseitin_processed.root == 'T':
        variables = f_prop.variables()
        if variables == set():
            return SAT_MSG, "Trivial"
        else:
            model = next(propositional_semantics.all_models(list(variables)))
            return SAT_MSG, str(model)

    # deduction steps
    msg, settings = run_sat_cnf(str(f_tseitin_processed))
    if msg == SAT_MSG:
        original_variables = f_prop.variables()
        original_settings = {key: settings[key] for key in original_variables}
        return msg, original_settings
    else:
        return msg, settings
示例#8
0
def propositional_to_prefix(formula: str):
    from propositions.syntax import Formula
    f = Formula.parse(formula)
    if f is None:
        print_error('Could not parse the given formula')
        return None

    print(f.polish())
示例#9
0
def predicate_create_instance(schema_name: str,
                              instantiation_map,
                              destination_formula: str = None):
    from predicates.syntax import Formula
    from predicates.proofs import PROPOSITIONAL_AXIOM_TO_SCHEMA
    from predicates.prover import Prover
    consts = [name for name in vars(Prover) if not name.startswith('_')]
    if schema_name not in consts:
        print_error('Cant find the schema name.')
        return

    for key in instantiation_map:
        if isinstance(instantiation_map[key], str):
            instantiation_map[key] = Formula.parse(instantiation_map[key])

    schema = vars(Prover)[schema_name]
    result = [str(schema)]
    result.append('Instantiation Map: ' + str(instantiation_map))
    result.append('')

    instance = None
    try:
        # instantiation_map = {'Q': Formula.parse('Ax[Q(x)]')}
        instance = schema.instantiate(instantiation_map)
        result.append('Instance: ' + str(instance))
    except AssertionError:
        # raise
        result.append('ASSERT ERROR. CAN NOT GENERATE INSTANCE.')
        print_result('\n'.join(result))
        return

    if destination_formula is not None:
        destination_formula = Formula.parse(destination_formula)
        if destination_formula is None:
            print_error('Could not parse the given destination_formula')
            return None

        result.append('')
        result.append('Destination Formula: ' + str(destination_formula))
        result.append('')
        if destination_formula == instance:
            result.append('V! Formulas are equal.')
        else:
            result.append('X! Formulas ARE NOT equal.')
    print_result('\n'.join(result))
示例#10
0
    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)
示例#11
0
def predicate_get_primitives(formula: str):
    from predicates.syntax import Formula
    from predicates.completeness import get_primitives, get_constants
    f = Formula.parse(formula)
    if f is None:
        print_error('Could not parse the given formula')
        return None

    print_result('Formula: ' + str(f) + '\nPrimitives: ' +
                 str(get_primitives(f)))
示例#12
0
def predicate_is_model(formula: str, world: Set[int],
                       relations: Mapping[str, Set[Tuple]]):
    from predicates.prenex import to_prenex_normal_form
    from predicates.syntax import Formula
    from predicates.semantics import Model

    f = Formula.parse(formula)
    if f is None:
        print_error('Could not parse the given formula')
        return None

    m = Model(world, {str(k): k for k in world}, relations)
    print_result(m.is_model_of({f}))
示例#13
0
def predicate_prenex_form(formula: str):
    from predicates.prenex import to_prenex_normal_form, is_in_prenex_normal_form
    from predicates.syntax import Formula
    f = Formula.parse(formula)
    if f is None:
        print_error('Could not parse the given formula')
        return None

    if is_in_prenex_normal_form(f):
        print_result('Original formula was already in prenex normal form.')
    else:
        print_result('Original formula wasnt in prenex normal form.'
                     '\nPrenex Normal Form: ' +
                     str(to_prenex_normal_form(f)[0]))
示例#14
0
    def propositional_skeleton(
            self) -> 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.
        """
        substitution_map = {}
        skeleton = self.__create_propositional_skeleton(substitution_map)
        skeleton = PropositionalFormula.parse(str(skeleton))
        return skeleton, {v.root: k for k, v in substitution_map.items()}