summaryrefslogtreecommitdiff
path: root/lib/sequent_calculus
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sequent_calculus')
-rw-r--r--lib/sequent_calculus/headers.ml5
-rw-r--r--lib/sequent_calculus/sequent_proof.ml41
-rw-r--r--lib/sequent_calculus/sequent_rules.ml64
-rw-r--r--lib/sequent_calculus/sequents.ml72
4 files changed, 110 insertions, 72 deletions
diff --git a/lib/sequent_calculus/headers.ml b/lib/sequent_calculus/headers.ml
new file mode 100644
index 0000000..0bef07a
--- /dev/null
+++ b/lib/sequent_calculus/headers.ml
@@ -0,0 +1,5 @@
+(* Sequent calculus: types and exceptions *)
+
+(* exceptions that can occur when attempting a sequent proof *)
+exception RuleNotApplicable
+exception NotProvable of string
diff --git a/lib/sequent_calculus/sequent_proof.ml b/lib/sequent_calculus/sequent_proof.ml
new file mode 100644
index 0000000..7d8c0f9
--- /dev/null
+++ b/lib/sequent_calculus/sequent_proof.ml
@@ -0,0 +1,41 @@
+(* Sequent Calculus *)
+
+open Types
+open Headers
+open Sequent_rules
+
+(* returns true if arg is the basic tautological sequent *)
+let rec is_basic_sequent (Seq(l1, l2)) =
+ match l1 with
+ | [] -> false
+ | p :: ps -> List.mem p l2 || is_basic_sequent (Seq (ps, l2))
+
+(* gives list of sequents that need to be proved for this to be true *)
+let get_dependencies (s : seq) : seq list =
+ let rec apply_each fns s = (* apply each fn to s and return first result *)
+ match fns with
+ | [] -> raise (NotProvable "Couldn't find proof")
+ | fn :: fns ->
+ try
+ fn s
+ with
+ | RuleNotApplicable -> apply_each fns s
+ in
+ if is_basic_sequent s then
+ []
+ else
+ apply_each rule_precedence_list s
+
+(* generates a proof for a sequent in stree form or throws an exception *)
+(* TODO: deal with <-> case *)
+let rec prove_sequent (s : seq) : stree =
+ let dependencies = get_dependencies s in
+ let proofs = List.map prove_sequent dependencies in
+ Concl(s, proofs)
+
+(* Prove a proposition via the sequent calculus or return None if not provable *)
+let prove (p : proposition): stree option =
+ try
+ Some (prove_sequent (Seq ([], [p])))
+ with NotProvable _ ->
+ None
diff --git a/lib/sequent_calculus/sequent_rules.ml b/lib/sequent_calculus/sequent_rules.ml
new file mode 100644
index 0000000..68f2b63
--- /dev/null
+++ b/lib/sequent_calculus/sequent_rules.ml
@@ -0,0 +1,64 @@
+(* Logic for applying sequent calculus rules *)
+
+open Types
+open Headers
+
+(* apply NOT rule for LHS if possible *)
+let rec not_lhs = function
+ | Seq([], _) -> raise RuleNotApplicable
+ | Seq(Not(p1) :: p1s, p2s) -> [Seq(p1s, p1 :: p2s)]
+ | Seq(_ :: p1s, p2s) -> not_lhs (Seq(p1s, p2s))
+
+(* apply NOT rule for RHS if possible *)
+let rec not_rhs = function
+ | Seq(_, []) -> raise RuleNotApplicable
+ | Seq(p1s, Not(p2) :: p2s) -> [Seq(p2 :: p1s, p2s)]
+ | Seq(p1s, _ :: p2s) -> not_rhs (Seq(p1s, p2s))
+
+(* apply AND rule for LHS if possible *)
+let rec and_lhs = function
+ | Seq([], _) -> raise RuleNotApplicable
+ | Seq(And(p1, p1') :: p1s, p2s) -> [Seq(p1 :: p1' :: p1s, p2s)]
+ | Seq(_ :: p1s, p2s) -> and_lhs (Seq(p1s, p2s))
+
+(* apply AND rule for RHS if possible *)
+let rec and_rhs = function
+ | Seq(_, []) -> raise RuleNotApplicable
+ | Seq(p1s, And(p2, p2') :: p2s) -> [Seq(p1s, p2 :: p2s); Seq(p1s, p2' :: p2s)]
+ | Seq(p1s, _ :: p2s) -> and_rhs (Seq(p1s, p2s))
+
+(* apply OR rule for LHS if possible *)
+let rec or_lhs = function
+ | Seq([], _) -> raise RuleNotApplicable
+ | Seq(Or(p1, p1') :: p1s, p2s) -> [Seq(p1 :: p1s, p2s); Seq(p1' :: p1s, p2s)]
+ | Seq(_ :: p1s, p2s) -> or_lhs (Seq(p1s, p2s))
+
+(* apply OR rule for RHS if possible *)
+let rec or_rhs = function
+ | Seq(_, []) -> raise RuleNotApplicable
+ | Seq(p1s, Or(p2, p2') :: p2s) -> [Seq(p1s, p2 :: p2' :: p2s)]
+ | Seq(p1s, _ :: p2s) -> or_rhs (Seq(p1s, p2s))
+
+(* apply -> rule for LHS if possible *)
+let rec implies_lhs = function
+ | Seq([], _) -> raise RuleNotApplicable
+ | Seq(Implies(p1, p1') :: p1s, p2s) -> [Seq(p1s, p1 :: p2s); Seq(p1' :: p1s, p2s)]
+ | Seq(_ :: p1s, p2s) -> implies_lhs (Seq(p1s, p2s))
+
+(* apply -> rule for RHS if possible *)
+let rec implies_rhs = function
+ | Seq(_, []) -> raise RuleNotApplicable
+ | Seq(p1s, Implies(p2, p2') :: p2s) -> [Seq(p2 :: p1s, p2' :: p2s)]
+ | Seq(p1s, _ :: p2s) -> implies_rhs (Seq(p1s, p2s))
+
+(* precedence rules for applying rules *)
+let rule_precedence_list = [
+ and_lhs; (* reduce AND on LHS *)
+ or_rhs; (* reduce OR on RHS *)
+ not_lhs; (* reduce NOT on LHS *)
+ not_rhs; (* reduce NOT on RHS *)
+ implies_rhs; (* reduce -> on RHS *)
+ or_lhs; (* reduce OR on LHS *)
+ and_rhs; (* reduce AND on RHS *)
+ implies_lhs (* reduce -> on LHS *)
+]
diff --git a/lib/sequent_calculus/sequents.ml b/lib/sequent_calculus/sequents.ml
deleted file mode 100644
index 0b4a33a..0000000
--- a/lib/sequent_calculus/sequents.ml
+++ /dev/null
@@ -1,72 +0,0 @@
-
-(* Sequent Calculus *)
-
-open Types
-open To_string
-
-
-type seq = Seq of proposition list * proposition list;; (* sequent *)
-
-type stree = (* tree of sequents *)
- | Taut (* tautology of the form A, Gamma => A, Delta *)
- | Br of stree * stree
-
-let string_of_seq (Seq (p1, p2)) =
- let rec string_of_prop_list = function
- | [] -> ""
- | p :: ps -> (string_of_prop p) ^ ", " ^ (string_of_prop_list ps)
- in
- (string_of_prop_list p1) ^ "⇒" ^ (string_of_prop_list p2);;
-
-(* let rec reduce_seq s =
- let rec not_lhs (Seq(p1s, p2s)) =
- match p1s with
- | [] -> Seq(p1s, p2s), None, false
- | p::ps ->
- (match p with
- | Not(p') -> Seq(ps, p'::p2s), None, true
- | _ -> let Seq(ps', p2s), _, found = not_lhs (Seq(ps, p2s)) in Seq(p::ps', p2s), None, found)
- in
- let rec not_rhs (Seq(p1s, p2s)) =
- match p2s with
- | [] -> Seq(p1s, p2s), None, false
- | p::ps ->
- (match p with
- | Not(p') -> Seq(p'::p1s, ps), None, true
- | _ -> let Seq(p1s, ps'), _, found = not_rhs (Seq(p1s, ps)) in Seq(p1s, p::ps'), None, found)
- in
- let rec and_lhs (Seq(p1s, p2s)) =
- match p1s with
- | [] -> Seq(p1s, p2s), None, false
- | p::ps ->
- (match p with
- | And(p1, p2) -> Seq(p1::p2::ps, p2s), None, true
- | _ -> let Seq(p1s, ps'), _, found = and_lhs (Seq(p1s, ps)) in Seq(p1s, p::ps'), None, found)
- in
- let rec and_rhs (Seq(p1s, p2s)) =
- match p2s with
- | [] -> Seq(p1s, p2s), None, false
- | p::ps ->
- (match p with
- | And(p1, p2) -> Seq(p1s, p1::ps), Some (Seq(p1s, p2::ps)), true
- | _ ->
- (match and_rhs (Seq(p1s, ps)) with
- | Seq(p1s, ps'), None, found -> Seq(p1s, p2s), None, false
- | Seq(p1s, ps'), Some (Seq(p1s', ps'')), found -> Seq(p1s, p::ps'), Some (Seq(p1s', p::ps'')), true))
- in
- match s with
- | Seq *)
-
- (*
- Steps (repeat in this order):
- - reduce AND on LHS
- - reduce OR on RHS
- - reduce NOT on LHS
- - reduce NOT on RHS
- - reduce -> (RHS)
- - reduce <-> (both)
- - reduce OR (LHS)
- - reduce AND (RHS)
- - reduce -> (LHS)
- *)
- \ No newline at end of file