@@ -217,22 +217,333 @@ This problem explores quantifiers, structures, and fundamental limitations of FO
217217 - Conclude: "the domain is infinite" can be expressed by an infinite set of FOL sentences, but not by a _single_ sentence (or any finite set). Why?
218218]
219219
220- = Notation Reference
221-
222- # grid (
223- columns : 2 ,
224- column-gutter : 2em ,
225- row-gutter : 1em ,
226- [
227- *Semantic relations:*
228- - $ Gamma models phi $ --- semantic entailment
229- - $ nu models phi $ --- interpretation $ nu $ satisfies $ phi $
230- - $ models phi $ --- $ phi $ is valid (tautology)
231- ],
232- [
233- *Syntactic relations:*
234- - $ Gamma tack phi $ --- syntactic derivability
235- - Fitch rules: $ and $ i/e, $ or $ i/e, $ imply $ i/e, $ not $ i/e, $ bot $ e, RAA, LEM
236- - FOL rules: $ forall $ i/e, $ exists $ i/e
237- ],
238- )
220+ == Problem 7: Programming Challenge --- Logic in Practice
221+
222+ # Block (color : teal , width : 100% )[
223+ *Implementation context:*
224+
225+ This is a _programming project_ where you implement core logic concepts from scratch and explore their real-world applications.
226+ Choose your language: Python, Rust, OCaml, Haskell, or any language with algebraic data types.
227+ For formal verification tasks, use Lean 4 or Coq.
228+
229+ *Submission:* Code repository (GitHub/GitLab) with README explaining your design choices, plus a brief report (2-3 pages) documenting what you implemented, challenges encountered, and insights gained.
230+
231+ *Grading:* Core tasks (50%), code quality & documentation (30%), extensions (20%).
232+ ]
233+
234+ === Part A: Formula Engine (Core Implementation)
235+
236+ Build a _propositional logic toolkit_ from the ground up.
237+
238+ *Task A.1: Abstract Syntax Tree*
239+
240+ Design and implement an AST representation for propositional formulas.
241+
242+ # Block (color : blue . lighten (50% ), width : 100% )[
243+ *Required:*
244+ - Data type/class for formulas: atoms ($ p, q, dots $ ), $ not $ , $ and $ , $ or $ , $ imply $ , $ iff $ , constants ($ top $ , $ bot $ )
245+ - Constructor functions or smart constructors
246+ - Structural equality and hashing (for sets/maps)
247+
248+ *Example (Rust):*
249+ ```rust
250+ enum Formula {
251+ Atom(String),
252+ Not(Box<Formula>),
253+ And(Box<Formula>, Box<Formula>),
254+ // ... complete the rest
255+ }
256+ ```
257+
258+ *Example (Python):*
259+ ```python
260+ @dataclass(frozen=True)
261+ class Atom:
262+ name: str
263+
264+ @dataclass(frozen=True)
265+ class Not:
266+ operand: Formula
267+ # ... complete using Union or inheritance
268+ ```
269+
270+ *Open question:* Should $ imply $ and $ iff $ be primitive or derived? Justify your choice.
271+ ]
272+
273+ *Task A.2: Pretty Printer and Parser*
274+
275+ # Block (color : blue . lighten (50% ), width : 100% )[
276+ *Required:*
277+ - `to_string(formula)` : Convert AST to human-readable string with minimal parentheses.
278+ Use precedence: $ not > and > or > imply > iff $
279+ - Handle associativity correctly
280+
281+ *Optional:*
282+ - Parser: `parse(string)` → AST. Use a parser combinator library (e.g., `pyparsing` , `nom` , `parsec` ) or write a recursive descent parser.
283+ - Round-trip test: `parse(to_string(f)) == f`
284+
285+ *Test case:*
286+ ```
287+ ((p ∧ q) → r) ∨ (¬p ∧ s) should print with minimal parens
288+ ```
289+ ]
290+
291+ # block (sticky : true )[*Task A.3: Evaluator and Truth Tables* ]
292+
293+ # Block (color : blue . lighten (50% ), width : 100% )[
294+ *Required:*
295+ - `eval(formula, interpretation)` : Evaluate formula under a given variable assignment.
296+ - `truth_table(formula)` : Generate complete truth table as a list/table of `(valuation, result)` pairs.
297+ - `is_tautology(formula)` , `is_satisfiable(formula)` , `is_contradiction(formula)`
298+
299+ *Output format:*
300+ ```
301+ p | q | r | (p ∧ q) → r
302+ --|---|---|-------------
303+ T | T | T | T
304+ T | T | F | F
305+ ...
306+ ```
307+
308+ *Open task:* Implement _early termination_ : stop generating the truth table for `is_satisfiable` as soon as you find one satisfying assignment.
309+ ]
310+
311+ # block (sticky : true )[*Task A.4: Normal Forms* ]
312+
313+ # Block (color : blue . lighten (50% ), width : 100% )[
314+ *Required:*
315+ - `to_nnf(formula)` : Convert to Negation Normal Form (push negations to atoms).
316+ - `to_cnf(formula)` : Convert to Conjunctive Normal Form using distributivity or Tseitin transformation.
317+
318+ *Open choice:* Should `to_cnf` always use Tseitin (polynomial blowup) or try direct conversion first (exponential worst case, but often smaller)? Implement both and compare.
319+
320+ *Test:* Verify that your CNF conversion preserves satisfiability (or equivalence, if not using Tseitin).
321+ ]
322+
323+ # block (sticky : true )[*Task A.5: Equivalence and Properties* ]
324+
325+ # Block (color : blue . lighten (50% ), width : 100% )[
326+ *Required:*
327+ - `equivalent(f1, f2)` : Check logical equivalence using truth tables or SAT solving.
328+ - Implement and test De Morgan's laws:
329+ - $ not (p and q) equiv (not p) or (not q)$
330+ - $ not (p or q) equiv (not p) and (not q)$
331+ - Test distributivity: $ p and (q or r) equiv (p and q) or (p and r)$
332+
333+ *Extension:*
334+ - Implement a _random formula generator_ for property-based testing.
335+ - Use it to test commutativity, associativity, absorption laws.
336+ ]
337+
338+ === Part B: Proof Systems (Advanced Implementation)
339+
340+ Implement proof checking and (optionally) proof search.
341+
342+ # block (sticky : true )[*Task B.1: Fitch Proof Representation* ]
343+
344+ # Block (color : green . lighten (60% ), width : 100% )[
345+ *Required:*
346+ - Data structure for Fitch proofs: list of steps, each with:
347+ - Line number
348+ - Formula
349+ - Justification (rule name + references to earlier lines)
350+ - Indentation level (for subproofs)
351+
352+ *Example structure (pseudocode):*
353+ ```
354+ Step = {
355+ line: int,
356+ formula: Formula,
357+ rule: Rule,
358+ references: List[int],
359+ level: int, // subproof depth
360+ }
361+ ```
362+
363+ *Open design question:* How do you represent assumptions vs. derived steps? How do you track subproof scope?
364+ ]
365+
366+ # block (sticky : true )[*Task B.2: Proof Checker* ]
367+
368+ # Block (color : green . lighten (60% ), width : 100% )[
369+ *Required:*
370+ Implement a checker that validates Fitch proofs step-by-step.
371+ Support at minimum:
372+ - Premise (assumption at depth 0)
373+ - Assumption (start subproof, increase depth)
374+ - ∧i, ∧e, ∨i, ∨e, →i, →e, ¬i, ¬e, ⊥e
375+ - Reiteration (repeat earlier line from valid scope)
376+
377+ *Checker requirements:*
378+ - Verify each step references valid earlier lines
379+ - Check subproof scoping (can only reference lines from current or outer scopes)
380+ - Verify rule applications are correct
381+ - Report specific errors with line numbers
382+
383+ *Test case:* Validate the proof from Problem 1(a) in HW1.
384+
385+ *Extension:*
386+ - Add RAA (reductio ad absurdum) and LEM (law of excluded middle)
387+ - Support FOL quantifier rules ($ forall $ i/e, $ exists $ i/e) with eigenvariable checking
388+ ]
389+
390+ # block (sticky : true )[*Task B.3: Automated Proof Search (Optional)* ]
391+
392+ # Block (color : green . lighten (60% ), width : 100% )[
393+ *Challenge:* Implement a simple automated prover.
394+
395+ *Approach 1 (Semantic Tableaux):*
396+ - Implement a tableau prover: try to build a countermodel by systematic case analysis.
397+ - If all branches close, the formula is a tautology.
398+
399+ *Approach 2 (Resolution):*
400+ - Convert to CNF, apply resolution until deriving $ square $ or saturating.
401+
402+ *Approach 3 (Sequent Calculus):*
403+ - Bottom-up proof search in sequent calculus.
404+
405+ *Open exploration:* Which approach finds proofs fastest for the examples in Problem 1?
406+ Can you find formulas where one method outperforms the others dramatically?
407+ ]
408+
409+ === Part C: Real-World Applications
410+
411+ Connect theory to practical software engineering.
412+
413+ # block (sticky : true )[*Task C.1: Configuration Validation* ]
414+
415+ # Block (color : orange . lighten (70% ), width : 100% )[
416+ *Scenario:* You're building a deployment system with configuration constraints (like Problem 5: production mode, debug mode, logging, security).
417+
418+ *Implementation:*
419+ - Define a configuration schema as propositional formulas (constraints).
420+ - Implement `validate_config(constraints, config)` : check if a configuration satisfies all constraints.
421+ - Implement `find_valid_configs(constraints)` : enumerate _all_ valid configurations using your SAT solver or truth table generator.
422+ - Implement `explain_conflict(constraints, config)` : if a config is invalid, report which constraints are violated and suggest fixes.
423+
424+ *Test:* Use the access control system from Problem 5.
425+
426+ *Extension:*
427+ - Minimal correction: given an invalid config, find the _smallest_ set of variables to flip to make it valid.
428+ ]
429+
430+ # block (sticky : true )[*Task C.2: SMT Solver Integration* ]
431+
432+ # Block (color : orange . lighten (70% ), width : 100% )[
433+ *Tool:* Use Z3 (Python/C\+\+ /Java bindings) or CVC5.
434+
435+ *Task:*
436+ - Translate your propositional formulas to SMT-LIB or use the API.
437+ - Solve satisfiability: `z3_solve(formula)` → SAT/UNSAT + model.
438+ - Compare performance with your truth table implementation on large formulas (100+ variables).
439+
440+ *Research direction:*
441+ - Generate random 3-SAT instances with varying clause/variable ratios.
442+ - Plot satisfiability probability vs. ratio. Observe the _phase transition_ around ratio ≈ 4.26.
443+ - Document your findings.
444+ ]
445+
446+ # block (sticky : true )[*Task C.3: Symbolic Execution (Bonus)* ]
447+
448+ # Block (color : orange . lighten (70% ), width : 100% )[
449+ *Challenge:* Implement a _toy symbolic executor_ for a simple imperative language.
450+
451+ *Language (example):*
452+ ```
453+ x := E // assignment
454+ if B then S1 else S2
455+ assert(B) // fails if B is false
456+ while B do S // bounded unrolling
457+ ```
458+
459+ # block (sticky : true )[*Symbolic execution:* ]
460+ - Execute with _symbolic_ inputs (variables, not concrete values).
461+ - Track path condition (formula representing choices made).
462+ - At `assert(B)` , check if `path_condition ∧ ¬B` is satisfiable:
463+ - If SAT → assertion can fail (counterexample).
464+ - If UNSAT → assertion always holds on this path.
465+
466+ *Deliverable:*
467+ - Implement symbolic executor for assertion checking.
468+ - Test on 2-3 small programs (e.g., array bounds check, login validation).
469+
470+ *Open question:* How do you handle loops? (Bounded unrolling? Loop invariants?)
471+ ]
472+
473+ # block (sticky : true )[*Task C.4: Type Checking as Logic (Bonus)* ]
474+
475+ # Block (color : orange . lighten (70% ), width : 100% )[
476+ *Insight:* Type systems are logical systems (Curry-Howard correspondence).
477+
478+ *Task:*
479+ - Design a simple typed lambda calculus or a subset of a real language (e.g., Simply Typed Lambda Calculus with booleans and integers).
480+ - Encode typing judgments $ Gamma tack e : tau $ as logical formulas or inference rules.
481+ - Implement a type checker using your proof representation from Part B.
482+ - Show that type checking $ equiv $ proof search in a specific logic.
483+
484+ *Extension:*
485+ - Implement in Lean or Coq: prove type safety (progress + preservation theorems).
486+ - Compare the formal proof to your implementation.
487+ ]
488+
489+ === Part D: Formal Verification Track (Optional)
490+
491+ Use Lean 4 or Coq to _prove properties_ about your implementations.
492+
493+ # block (sticky : true )[*Task D.1: Verified Evaluator (Lean/Coq)* ]
494+
495+ # Block (color : teal . lighten (60% ), width : 100% )[
496+ *Task:*
497+ - Define propositional formulas in Lean/Coq as an inductive type.
498+ - Implement `eval : Formula → Valuation → Bool` .
499+ - *Prove:* `eval` is deterministic: `∀ f v, eval f v = eval f v` (trivial, warmup).
500+ - *Prove:* Double negation: `∀ f v, eval (¬¬f) v = eval f v` .
501+ - *Prove:* De Morgan: `∀ f g v, eval (¬(f ∧ g)) v = eval (¬f ∨ ¬g) v` .
502+
503+ *Resources:*
504+ - Lean 4: # link (" https://leanprover.github.io/theorem_proving_in_lean4/" )[Theorem Proving in Lean]
505+ - Coq: Software Foundations (Vol. 1, _Logical Foundations_ )
506+ ]
507+
508+ # block (sticky : true )[*Task D.2: Verified CNF Conversion (Lean/Coq)* ]
509+
510+ # Block (color : teal . lighten (60% ), width : 100% )[
511+ *Challenge:*
512+ - Implement NNF conversion in Lean/Coq.
513+ - *Prove correctness:* `∀ f, equivalent f (to_nnf f)` where `equivalent f g := ∀ v, eval f v = eval g v` .
514+ - Prove termination (structural recursion or well-founded relation).
515+
516+ *Extension:*
517+ - Prove Tseitin transformation preserves _satisfiability_ (not equivalence).
518+ ]
519+
520+ # block (sticky : true )[*Task D.3: Soundness of Proof Checker (Lean/Coq)* ]
521+
522+ # Block (color : teal . lighten (60% ), width : 100% )[
523+ *Advanced challenge:*
524+ - Formalize Fitch-style natural deduction in Lean/Coq.
525+ - Implement proof checking.
526+ - *Prove soundness:* If `check_proof Γ φ proof = true` , then `Γ ⊢ φ` (semantic entailment).
527+
528+ *This is research-level work* — partial results are valuable. Document your approach and any obstacles.
529+ ]
530+
531+ // = Notation Reference
532+ //
533+ // #grid(
534+ // columns: 2,
535+ // column-gutter: 2em,
536+ // row-gutter: 1em,
537+ // [
538+ // *Semantic relations:*
539+ // - $Gamma models phi$ --- semantic entailment
540+ // - $nu models phi$ --- interpretation $nu$ satisfies $phi$
541+ // - $models phi$ --- $phi$ is valid (tautology)
542+ // ],
543+ // [
544+ // *Syntactic relations:*
545+ // - $Gamma tack phi$ --- syntactic derivability
546+ // - Fitch rules: $and$i/e, $or$i/e, $imply$i/e, $not$i/e, $bot$e, RAA, LEM
547+ // - FOL rules: $forall$i/e, $exists$i/e
548+ // ],
549+ // )
0 commit comments