exercises_lesson5.htmlImplement each rule as a Python function: given the premises, return the conclusion. The goal is not to check validity but to simulate the rule and chain it with others.
Pr. Zouhair el Hadiq
Rule abstraction SymPy
Every exercise below assumes:
Each exercise asks you to fill in an apply function and wrap it in a Rule.
isinstance(x, Implies) / And / Or / Not to pattern-match; use x.args to access sub-formulae; raise InferenceError when the premises don't match the rule's pattern.Implement modus_ponens(prem1, prem2) -> q. Either order should be accepted (the rule should figure out which premise is the implication).
Implement modus_tollens(prem1, prem2) -> Not(p). The premises can be given in either order.
Implement hyp_syll(imp1, imp2) -> Implies(p, r). The two implications must chain — the consequent of one must equal the antecedent of the other.
Implement disj_syll(disj, neg) -> q. The function must also handle (¬q, p ∨ q) → p (the cancelled side can be either disjunct).
Unlike the other rules, Addition introduces a new formula. Implement addition(p_formula, extra) -> Or(p_formula, extra) with arity 2: the second argument is the disjunct you choose to add.
Implement simplification(conj, side='left') returning either the left or the right operand of an And. Use arity 1 (the second parameter is a keyword option).
Implement conjunction(a, b) -> And(a, b). The simplest rule of all.
Implement resolution(c1, c2) -> Or(...). Both premises are clauses (each a literal or an Or of literals). The function must find a complementary pair — a literal $\ell$ in one clause whose negation $\neg \ell$ is in the other — and return the disjunction of the remaining literals.
Collect every Rule from exercises 1–8 in a dictionary keyed by name. Then write
satisfiable(And(*premises, Not(conclusion))) returns False — i.e. the simulated conclusion is logically entailed.Reproduce the proof from the lesson (slide 8) by simulation. Given:
Use your simulated rules to build the proof step by step and finish at $u$:
u.SymPy's ForAll / Exists are limited; we simulate them with an explicit predicate + substitution.
UI, accept any constant; in UG (not implemented here) you would require the constant be arbitrary (i.e. not occurring in any open assumption); in EI the chosen constant must be fresh.Combine everything into a tiny proof checker that takes a proof script — a list of steps where each step is either a premise or (rule_name, [indices into earlier steps]) — and produces a numbered transcript.
InferenceError, prefix the offending line with FAIL: and continue.proof_to_latex(script) function that emits a natural-deduction tree in LaTeX (`bussproofs` package).