proof_checker/lib/proof.ml

64 lines
2 KiB
OCaml

type label =
| Axiom
| AndI
| AndE
| OrI
| OrE
| ArrI
| ArrE
| NegI
| NegE
| RAA
| IffI
| IffE
| EqI
| EqE
| ForallI
| ForallE
| ExistsI
| ExistsE
type pref = Linenum of int | Named of string
type t = { children : pref list; label : label; formula : Formula.t }
let rec valid res a { children; label; formula } =
let children = List.map res children in
match (children, label, formula) with
| [], Axiom, phi -> List.mem phi a
| [ left; right ], AndI, Conj (phi, psi) ->
left.formula = phi && right.formula = psi && valid res a left
&& valid res a right
| [ ({ formula = Conj (phi, psi); _ } as kid) ], AndE, chi ->
(chi = phi || chi = psi) && valid res a kid
| [ kid ], OrI, Disj (phi, psi) ->
(kid.formula = phi || kid.formula = psi) && valid res a kid
| [ ({ formula = Disj (phi, psi); _ } as left); middle; right ], OrE, chi ->
middle.formula = chi && right.formula = chi && valid res a left
&& valid res (phi :: a) middle
&& valid res (psi :: a) right
| [ kid ], ArrI, Impl (phi, psi) ->
kid.formula = psi && valid res (phi :: a) kid
| [ left; right ], ArrE, psi ->
left.formula = Impl (right.formula, psi)
&& valid res a left && valid res a right
| [ kid ], NegI, Neg phi -> kid.formula = Bottom && valid res (phi :: a) kid
| [ left; right ], NegE, Bottom ->
left.formula = Neg right.formula && valid res a left && valid res a right
| [ kid ], RAA, phi -> kid.formula = Bottom && valid res (Neg phi :: a) kid
| [ left; right ], IffI, Iff (phi, psi) ->
left.formula = Impl (phi, psi)
&& right.formula = Impl (psi, phi)
&& valid res a left && valid res a right
| [ left; right ], IffE, phi ->
(left.formula = Iff (right.formula, phi)
|| left.formula = Iff (phi, right.formula))
&& valid res a left && valid res a right
| [], EqI, Equal (x, y) -> x = y
(* TODO:
- EqE
- ForallI
- ForallE
- ExistsI
- ExistsE
*)