def test_evaluate_inference(debug=False): from propositions.proofs import InferenceRule # Test 1 rule1 = InferenceRule([Formula.parse('p'), Formula.parse('q')], Formula.parse('r')) for model in all_models(['p', 'q', 'r']): if debug: print('Testing evaluation of inference rule', rule1, 'in model', model) assert evaluate_inference(rule1, frozendict(model)) == \ (not model['p']) or (not model['q']) or model['r'] # Test 2 rule2 = InferenceRule([Formula.parse('(x|y)')], Formula.parse('x')) for model in all_models(['x', 'y']): if debug: print('Testing evaluation of inference rule', rule2, 'in model', model) assert evaluate_inference(rule2, frozendict(model)) == \ (not model['y']) or model['x'] # Test 3 rule3 = InferenceRule([Formula.parse(s) for s in ['(p->q)', '(q->r)']], Formula.parse('r')) for model in all_models(['p', 'q', 'r']): if debug: print('Testing evaluation of inference rule', rule3, 'in model', model) assert evaluate_inference(rule3, frozendict(model)) == \ (model['p'] and not model['q']) or \ (model['q'] and not model['r']) or model['r']
def test_is_sound_inference(debug=False): from propositions.proofs import InferenceRule for assumptions,conclusion,tautological in [ [[], '(~p|p)', True], [[], '(p|p)', False], [[], '(~p|q)', False], [['(~p|q)', 'p'], 'q', True], [['(p|q)', 'p'], 'q', False], [['(p|q)', '(~p|r)'], '(q|r)', True], [['(p->q)', '(q->r)'], 'r', False], [['(p->q)', '(q->r)'], '(p->r)', True], [['(x|y)'], '(y|x)', True], [['x'], '(x|y)', True], [['(x&y)'], 'x', True], [['x'], '(x&y)', False]]: rule = InferenceRule( [Formula.parse(assumption) for assumption in assumptions], Formula.parse(conclusion)) if debug: print('Testing whether', rule, 'is sound') assert is_sound_inference(rule) == tautological for rule in [MP, I0, I1, D, I2, N, NI, NN, R, A, NA1, NA2, O1, O2, NO, T, NF, N_ALTERNATIVE, AE1, AE2, OE]: if debug: print('Testing that', rule, 'is sound') assert is_sound_inference(rule)
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
def test_evaluate_inference(debug=False): from propositions.proofs import InferenceRule # Test 1 rule1 = InferenceRule( [Formula.parse('p'), Formula.parse('q')], Formula.parse('r')) for model in all_models(['p', 'q', 'r']): if debug: print('Testing evaluation of inference rule', rule1, 'in model', model) evaluation_result = evaluate_inference(rule1, frozendict(model)) == \ (not model['p']) or (not model['q']) or model['r'] if not evaluation_result: print("FAILED.") print("*" * 25) print("EXPECTED:", (not model['p']) or (not model['q']) or model['r']) print( "REASON: ", "(not {}) or (not {}) or {}".format(model['p'], model['q'], model['r'])) print("*" * 25) assert evaluation_result # assert evaluate_inference(rule1, frozendict(model)) == \ # (not model['p']) or (not model['q']) or model['r'] # Test 2 rule2 = InferenceRule([Formula.parse('(x|y)')], Formula.parse('x')) for model in all_models(['x', 'y']): if debug: print('Testing evaluation of inference rule', rule2, 'in model', model) assert evaluate_inference(rule2, frozendict(model)) == \ (not model['y']) or model['x'] # Test 3 rule3 = InferenceRule([Formula.parse(s) for s in ['(p->q)', '(q->r)']], Formula.parse('r')) for model in all_models(['p', 'q', 'r']): if debug: print('Testing evaluation of inference rule', rule3, 'in model', model) assert evaluate_inference(rule3, frozendict(model)) == \ (model['p'] and not model['q']) or \ (model['q'] and not model['r']) or model['r']
def prove_from_skeleton_proof(formula: Formula, skeleton_proof: PropositionalProof, substitution_map: Mapping[str, Formula]) -> \ Proof: """Converts the given proof of a propositional skeleton of the given predicate-logic formula into a proof of that predicate-logic formula. Parameters: formula: predicate-logic formula to prove. skeleton_proof: valid propositional-logic proof of a propositional skeleton of the given formula, from no assumptions and via `~propositions.axiomatic_systems.AXIOMATIC_SYSTEM`. substitution_map: map from each atomic propositional subformula of the skeleton of the given formula that is proven in the given proof to the respective predicate-logic subformula of the given formula. Returns: A valid predicate-logic proof of the given formula from the axioms `PROPOSITIONAL_AXIOMATIC_SYSTEM_SCHEMAS` via only assumption lines and MP lines. """ assert len(skeleton_proof.statement.assumptions) == 0 and \ skeleton_proof.rules.issubset(PROPOSITIONAL_AXIOMATIC_SYSTEM) and \ skeleton_proof.is_valid() assert Formula.from_propositional_skeleton( skeleton_proof.statement.conclusion, substitution_map) == formula # Task 9.11.2 # create the proof, translate lines, assumption and conclusion # creating lines: predicate_line_formulas = [ Formula.from_propositional_skeleton(line.formula, substitution_map) for line in skeleton_proof.lines ] real_predicate_lines = [] for predicate_formula, skeleton_line in zip(predicate_line_formulas, skeleton_proof.lines): # if line was proven using MP if skeleton_line.rule == MP: # if the line is MP create a predicate MP line real_predicate_lines.append( Proof.MPLine(predicate_formula, skeleton_line.assumptions[0], skeleton_line.assumptions[1])) else: # line must be from an axiom line_to_specialization_map = PropositionalInferenceRule.formula_specialization_map( skeleton_line.rule.conclusion, skeleton_line.formula) instantiation_map = axiom_specialization_map_to_schema_instantiation_map( line_to_specialization_map, substitution_map) real_predicate_lines.append( Proof.AssumptionLine( predicate_formula, PROPOSITIONAL_AXIOM_TO_SCHEMA[skeleton_line.rule], instantiation_map)) # create the final proof return Proof(PROPOSITIONAL_AXIOMATIC_SYSTEM_SCHEMAS, formula, real_predicate_lines)
def _prove_from_skeleton_proof(formula: Formula, skeleton_proof: PropositionalProof, substitution_map: Mapping[str, Formula]) -> \ Proof: """Converts the given proof of a propositional skeleton of the given predicate-logic formula to a proof of that predicate-logic formula. Parameters: formula: predicate-logic formula to prove. skeleton_proof: valid propositional-logic proof of a propositional skeleton of the given formula, from no assumptions and via `~propositions.axiomatic_systems.AXIOMATIC_SYSTEM`, and containing no constants or operators beyond ``'~'``, ``'->'``, ``'|'``, and ``'&'``. substitution_map: mapping from each atomic propositional subformula of the skeleton of the given formula that is proven in the given proof to the respective predicate-logic subformula of the given formula. Returns: A valid predicate-logic proof of the given formula from the axioms `PROPOSITIONAL_AXIOMATIC_SYSTEM_SCHEMAS` via only assumption lines and MP lines. """ assert len(skeleton_proof.statement.assumptions) == 0 and \ skeleton_proof.rules.issubset(PROPOSITIONAL_AXIOMATIC_SYSTEM) and \ skeleton_proof.is_valid() assert Formula.from_propositional_skeleton( skeleton_proof.statement.conclusion, substitution_map) == formula for line in skeleton_proof.lines: for operator in line.formula.operators(): assert is_unary(operator) or is_binary(operator) # Task 9.11.2 lines = [] for line in skeleton_proof.lines: form = Formula.from_propositional_skeleton(line.formula, substitution_map) if line.rule == MP: mp_line = Proof.MPLine(form, line.assumptions[0], line.assumptions[1]) lines.append(mp_line) else: # rule is axiom rule = PROPOSITIONAL_AXIOM_TO_SCHEMA[line.rule] # map of format {'p': ~z33} propositional_specialization_map = PropositionalInferenceRule.specialization_map( line.rule, PropositionalInferenceRule(line.rule.assumptions, line.formula)) # map of format {'P': ~Ey[~x=y]} scheme_map = _axiom_specialization_map_to_schema_instantiation_map( propositional_specialization_map, substitution_map) lines.append(Proof.AssumptionLine(form, rule, scheme_map)) return Proof(PROPOSITIONAL_AXIOMATIC_SYSTEM_SCHEMAS, formula, lines)
def prove_from_skeleton_proof(formula: Formula, skeleton_proof: PropositionalProof, substitution_map: Mapping[str, Formula]) -> \ Proof: """Converts the given proof of a propositional skeleton of the given predicate-logic formula into a proof of that predicate-logic formula. Parameters: formula: predicate-logic formula to prove. skeleton_proof: valid propositional-logic proof of a propositional skeleton of the given formula, from no assumptions and via `~propositions.axiomatic_systems.AXIOMATIC_SYSTEM`. substitution_map: map from each atomic propositional subformula of the skeleton of the given formula that is proven in the given proof to the respective predicate-logic subformula of the given formula. Returns: A valid predicate-logic proof of the given formula from the axioms `PROPOSITIONAL_AXIOMATIC_SYSTEM_SCHEMAS` via only assumption lines and MP lines. """ assert len(skeleton_proof.statement.assumptions) == 0 and \ skeleton_proof.rules.issubset(PROPOSITIONAL_AXIOMATIC_SYSTEM) and \ skeleton_proof.is_valid() assert Formula.from_propositional_skeleton( skeleton_proof.statement.conclusion, substitution_map) == formula # Task 9.11.2 assumptions = PROPOSITIONAL_AXIOMATIC_SYSTEM_SCHEMAS conclusion = formula lines = [] for skeleton_line in skeleton_proof.lines: line_formula = Formula.from_propositional_skeleton( skeleton_line.formula, substitution_map) if PropositionalProof.Line.is_assumption(skeleton_line): assumption_schema = Schema(line_formula, set()) line = Proof.AssumptionLine(line_formula, assumption_schema, dict()) else: if skeleton_line.rule == MP: ante_line_num, cond_line_num = [ skeleton_line.assumptions[i] for i in [0, 1] ] line = Proof.MPLine(line_formula, ante_line_num, cond_line_num) else: schema_rule = PROPOSITIONAL_AXIOM_TO_SCHEMA[skeleton_line.rule] prop_spec_map = PropositionalInferenceRule.formula_specialization_map( skeleton_line.rule.conclusion, skeleton_line.formula) inst_map = axiom_specialization_map_to_schema_instantiation_map( prop_spec_map, substitution_map) line = Proof.AssumptionLine(line_formula, schema_rule, inst_map) lines.append(line) return Proof(assumptions, conclusion, lines)
def prove_from_skeleton_proof(formula: Formula, skeleton_proof: PropositionalProof, substitution_map: Mapping[str, Formula]) -> \ Proof: """Converts the given proof of a propositional skeleton of the given predicate-logic formula into a proof of that predicate-logic formula. Parameters: formula: predicate-logic formula to prove. skeleton_proof: valid propositional-logic proof of a propositional skeleton of the given formula, from no assumptions and via `~propositions.axiomatic_systems.AXIOMATIC_SYSTEM`. substitution_map: map from each atomic propositional subformula of the skeleton of the given formula that is proven in the given proof to the respective predicate-logic subformula of the given formula. Returns: A valid predicate-logic proof of the given formula from the axioms `PROPOSITIONAL_AXIOMATIC_SYSTEM_SCHEMAS` via only assumption lines and MP lines. """ assert len(skeleton_proof.statement.assumptions) == 0 and \ skeleton_proof.rules.issubset(PROPOSITIONAL_AXIOMATIC_SYSTEM) and \ skeleton_proof.is_valid() assert Formula.from_propositional_skeleton( skeleton_proof.statement.conclusion, substitution_map) == formula # Task 9.11.2 lines = list() for line in skeleton_proof.lines: if len(line.assumptions) == 0: new_line = Proof.AssumptionLine( Formula.from_propositional_skeleton(line.formula, substitution_map), PROPOSITIONAL_AXIOM_TO_SCHEMA[line.rule], axiom_specialization_map_to_schema_instantiation_map( PropositionalInferenceRule.formula_specialization_map( line.rule.conclusion, line.formula), substitution_map)) else: new_line = Proof.MPLine( Formula.from_propositional_skeleton(line.formula, substitution_map), line.assumptions[0], line.assumptions[1]) lines.append(new_line) return Proof(PROPOSITIONAL_AXIOMATIC_SYSTEM_SCHEMAS, formula, lines)
def prove_from_skeleton_proof(formula: Formula, skeleton_proof: PropositionalProof, substitution_map: Mapping[str, Formula]) -> \ Proof: """Converts the given proof of a propositional skeleton of the given predicate-logic formula into a proof of that predicate-logic formula. Parameters: formula: predicate-logic formula to prove. skeleton_proof: valid propositional-logic proof of a propositional skeleton of the given formula, from no assumptions and via `~propositions.axiomatic_systems.AXIOMATIC_SYSTEM`. substitution_map: map from each atomic propositional subformula of the skeleton of the given formula that is proven in the given proof to the respective predicate-logic subformula of the given formula. Returns: A valid predicate-logic proof of the given formula from the axioms `PROPOSITIONAL_AXIOMATIC_SYSTEM_SCHEMAS` via only assumption lines and MP lines. """ assert len(skeleton_proof.statement.assumptions) == 0 and \ skeleton_proof.rules.issubset(PROPOSITIONAL_AXIOMATIC_SYSTEM) and \ skeleton_proof.is_valid() assert Formula.from_propositional_skeleton( skeleton_proof.statement.conclusion, substitution_map) == formula # Setup the proof builder builder = Proof.ProofBuilder() \ .with_assumptions(PROPOSITIONAL_AXIOMATIC_SYSTEM_SCHEMAS) \ .with_conclusion(Formula.from_propositional_skeleton(skeleton_proof.statement.conclusion, substitution_map)) for line in skeleton_proof.lines: # Which rule type do we got if line.rule == MP: builder.add_mp_line(Formula.from_propositional_skeleton(line.formula, substitution_map), line.assumptions[0], line.assumptions[1]) else: builder.add_claim_line(Formula.from_propositional_skeleton(line.formula, substitution_map), PROPOSITIONAL_AXIOM_TO_SCHEMA[line.rule], axiom_specialization_map_to_schema_instantiation_map( PropositionalInferenceRule.formula_specialization_map(line.rule.conclusion, line.formula), substitution_map)) return builder.build()
def test_is_tautological_inference(debug=False): from propositions.proofs import InferenceRule for assumptions,conclusion,tautological in [ [[], '(~p|p)', True], [[], '(p|p)', False], [[], '(~p|q)', False], [['(~p|q)', 'p'], 'q', True], [['(p|q)', 'p'], 'q', False], [['(p|q)', '(~p|r)'], '(q|r)', True], [['(p->q)', '(q->r)'], 'r', False], [['(p->q)', '(q->r)'], '(p->r)', True], [['(x|y)'], '(y|x)', True], [['x'], '(x|y)', True], [['(x&y)'], 'x', True], [['x'], '(x&y)', False]]: rule = InferenceRule( [Formula.from_infix(assumption) for assumption in assumptions], Formula.from_infix(conclusion)) if debug: print('Testing whether', rule, 'is a tautological inference') assert is_tautological_inference(rule) == tautological