Skip to content

Commit e0bd429

Browse files
committed
Add programming project to HW 1
1 parent cca632a commit e0bd429

1 file changed

Lines changed: 330 additions & 19 deletions

File tree

homework/hw1.typ

Lines changed: 330 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)