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
Beispiel #2
0
    def from_propositional_skeleton(skeleton: PropositionalFormula,
                                    substitution_map: Mapping[str, Formula]) -> \
            Formula:
        """Computes a predicate-logic formula from a propositional skeleton and
        a substitution map.

        Arguments:
            skeleton: propositional skeleton for the formula to compute,
                containing no constants or operators beyond ``'~'``, ``'->'``,
                ``'|'``, and ``'&'``.
            substitution_map: mapping from each atomic propositional subformula
                of the given skeleton to a predicate-logic formula.

        Returns:
            A predicate-logic formula obtained from the given propositional
            skeleton by substituting each atomic propositional subformula with
            the formula mapped to it by the given map.

        Examples:
            >>> Formula.from_propositional_skeleton(
            ...     PropositionalFormula.parse('((z1&z2)|(z2->~z3))'),
            ...     {'z1': Formula.parse('Ax[x=7]'), 'z2': Formula.parse('x=7'),
            ...      'z3': Formula.parse('Q(y)')})
            ((Ax[x=7]&x=7)|(x=7->~Q(y)))
        """
        for operator in skeleton.operators():
            assert is_unary(operator) or is_binary(operator)
        for variable in skeleton.variables():
            assert variable in substitution_map
Beispiel #3
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
Beispiel #4
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
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
Beispiel #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
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.')
Beispiel #8
0
def test_from_prefix_all_operators(debug=False):
    for prefix in ['T', 'F', 'p', '~p', '&pq', '|pq', '->pq', '<->pq', '-&pq',
                   '-|pq', '?:pqr', '?:FFF', '->TT', '->~->xyz', '~?:TTT',
                   '?:<->xxxx', '?:F-&y123F-|y123F']:
        if debug:
            print("Testing prefix parsing of formula", prefix)
        assert Formula.from_prefix(prefix).prefix() == prefix
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
Beispiel #10
0
def test_variables_all_operators(debug=False):
    for infix,variables in [['(x|(y70&~(p?y70:z)))', {'p', 'x', 'y70', 'z'}],
                            ['(((x1->x11)-|x111)-&(x1?x11:(x111<->x1111)))',
                             {'x1', 'x11', 'x111', 'x1111'}]]:
        formula = Formula.from_infix(infix)
        if debug:
            print ("Testing variables of", formula)
        assert formula.variables() == variables
Beispiel #11
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())
Beispiel #12
0
def test_from_infix_all_operators(debug=False):
    for infix in ['T', 'F', 'p', '~p', '(p&q)', '(p|q)', '(p->q)', '(p<->q)',
                  '(p-&q)', '(p-|q)', '(p?q:r)', '(F?F:F)', '(T->T)',
                  '(~(x->y)->z)', '~(T?T:T)', '((x<->x)?x:x)',
                  '(F?(y123-&F):(y123-|F))']:
        if debug:
            print("Testing infix parsing of formula", infix)
        assert Formula.from_infix(infix).infix() == infix
Beispiel #13
0
def test_infix(debug=False):
    if debug:
        print("Testing infix of formula 'x12'")
    assert Formula('x12').infix() == 'x12'
    if debug:
        print("Testing infix of formula '(p|p)'")
    assert Formula('|',Formula('p'),Formula('p')).infix() == '(p|p)'
    if debug:
        print("Testing infix of formula '~(p&q7)'")
    assert Formula('~', Formula('&', Formula('p'), Formula('q7'))).infix() == '~(p&q7)'
Beispiel #14
0
def test_prefix(debug=False):
    if debug:
        print("Testing prefix of formula 'x12'")
    assert Formula('x12').prefix() == 'x12'
    if debug:
        print("Testing prefix of formula '|pp' (in infix: '(p|p)')")
    assert Formula('|',Formula('p'),Formula('p')).prefix() == '|pp'
    if debug:
        print("Testing prefix of formula '~&pq7' (in infix: '~(p&q7)')")
    assert Formula('~', Formula('&', Formula('p'), Formula('q7'))).prefix() == '~&pq7'
Beispiel #15
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))
Beispiel #16
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)
Beispiel #17
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)))
Beispiel #18
0
def test_variables(debug=False):
    for infix,variables in [['(x|(y70&~x))', {'x', 'y70'}],
                            ['((x|y)|z)', {'x', 'y', 'z'}],
                            ['~~(p11&~q11)', {'p11', 'q11'}],
                            ['(T|p)', {'p'}],
                            ['F', set()],
                            ['~(T|F)', set()]]:
        formula = Formula.from_infix(infix)
        if debug:
            print ("Testing variables of", formula)
        assert formula.variables() == variables
Beispiel #19
0
def test_infix_all_operators(debug=False):
    for binary_operator in ['->', '<->', '-&', '-|']:
        infix = '(p' + binary_operator + 'q)'
        if debug:
            print("Testing infix of formula '" + infix + "'")
        assert Formula(binary_operator, Formula('p'), Formula('q')).infix() == infix

    if debug:
        print("Testing infix of formula '(p?q:r)'")
    assert Formula('?:', Formula('p'), Formula('q'), Formula('r')).infix() == '(p?q:r)'
Beispiel #20
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}))
Beispiel #21
0
def test_prefix_all_operators(debug=False):
    for binary_operator in ['->', '<->', '-&', '-|']:
        infix = '(p' + binary_operator + 'q)'
        prefix = binary_operator + 'pq'
        if debug:
            print("Testing prefix of formula '" + prefix + "' (in infix: '" + infix + "')")
        assert Formula(binary_operator, Formula('p'), Formula('q')).prefix() == prefix

    if debug:
        print("Testing prefix of formula '?:pqr' (in infix: '(p?q:r)')")
    assert Formula('?:', Formula('p'), Formula('q'), Formula('r')).prefix() == '?:pqr'
Beispiel #22
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]))
Beispiel #23
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()}
Beispiel #24
0
    def from_propositional_skeleton(skeleton: PropositionalFormula,
                                    substitution_map: Mapping[str, Formula]) -> \
            Formula:
        """Computes a first-order formula from a propositional skeleton and a
        substitution map.

        Arguments:
            skeleton: propositional skeleton for the formula to compute.
            substitution_map: a map from each atomic propositional subformula
                of the given skeleton to a first-order formula.

        Returns:
            A first-order formula obtained from the given propositional skeleton
            by substituting each atomic propositional subformula with the formula
            mapped to it by the given map.
        """
        for key in substitution_map:
            assert is_propositional_variable(key)

        node_type = skeleton.getType()
        if node_type is PropositionalFormula.NodeType.T_UNARY_OP:
            # Parse the lhs
            lhs = Formula.from_propositional_skeleton(skeleton.first,
                                                      substitution_map)
            return Formula(skeleton.root, lhs)
        elif node_type is PropositionalFormula.NodeType.T_BINARY_OP:
            # Parse the lhs and rhs
            lhs = Formula.from_propositional_skeleton(skeleton.first,
                                                      substitution_map)
            rhs = Formula.from_propositional_skeleton(skeleton.second,
                                                      substitution_map)
            return Formula(skeleton.root, lhs, rhs)
        elif node_type is PropositionalFormula.NodeType.T_VAR:
            # Return the substituted variable, if we got one
            if skeleton.root in substitution_map:
                return substitution_map[skeleton.root]

        # Use the original value
        return skeleton
Beispiel #25
0
def test_from_prefix_all_operators(debug=False):
    for prefix in ['->~->xyz', '~?:TTT', '?:<->xxxx', '?:F-&y123F-|y123F']:
        if debug:
            print("Testing prefix parsing of formula", prefix)
        x = Formula.from_prefix(prefix).prefix()
        assert x == prefix
##################################################
#  FILE: testFile.py
#  WRITER : Erez Kaufman, erez, 305605255.
#  EXERCISE : intro2cs ex# 2015-2016
#  DESCRIPTION :
#
##################################################

from propositions.syntax import Formula

if __name__ == '__main__':
    q = Formula('q')
    z = Formula('z')
    nz = Formula('~', z)
    f = Formula('&', q, z)
    t = Formula('~', f)
    s = '(((~(y10|F)|T)&(F|T))|s2)'
    prefixString = '~|~~&pq2&pq5'
    q = Formula('|', t, f)
    infixTest = Formula.from_infix(s)
    print(infixTest)
    # h = Formula(t,q,f)
    q.from_infix('~(~~(q&r4)|(q&r6))')
    # if q.from_prefix(prefixString ).prefix() == prefixString :
    #     print(q.from_prefix(prefixString ))
    #     print(q.from_prefix(prefixString ).prefix())
    #     print("variables of prefix:", q.from_prefix(prefixString ).variables())
    #
    #     print('variables of q: ', q.variables())
    #
    #     exit(0)
Beispiel #27
0
def test_from_infix(debug=False):
    for infix in ['p', '~x12', '(x&y)', '~~(x|~T)', '((x1&~x2)|F)']:
        if debug:
            print("Testing infix parsing of formula", infix)
        assert Formula.from_infix(infix).infix() == infix
Beispiel #28
0
def test_from_prefix(debug=False):
    for prefix in ['p', '~x12', '&xy', '~~|x~T', '|&x1~x2F']:
        if debug:
            print("Testing prefix parsing of formula", prefix)
        assert Formula.from_prefix(prefix).prefix() == prefix