-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathformulas.ml
120 lines (88 loc) · 3.98 KB
/
formulas.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
(* Compiles with Ocaml 4.07 and 4.09 *)
(* implementation exceptions are errors *)
exception Implementation of string
exception Precondition of string
open Utility
module Formula =
struct
include List
type literal = Pos of int | Neg of int
type clause = literal list
type formula = clause list
let negate (lit : literal) : literal =
(match lit with
| Pos n -> Neg n
| Neg n -> Pos n)
let empty_clausep (c : clause) : bool =
(match c with
| [] -> true
| _ -> false)
let unit_clausep (c : clause) : bool =
(match c with
| [_] -> true
| _ -> false)
let var (lit : literal) : int = (match lit with | Pos n -> n | Neg n -> n)
let get_free_variable (bound : int list) (form : formula) : int option =
(MyOption.bind
(find_opt (fun lit -> (not (mem (var lit) bound))) (flatten form))
(fun x -> Some (var x)))
let tautologyp (form : formula) : bool =
(form = [])
let disjoin (c1 : clause) (c2 : clause) : clause =
(fold_right (fun lit c' -> (if (mem lit c') then c' else lit::c')) c1 c2)
let conjoin1 (cs : formula) (c : clause) : (clause list) = (c::cs)
let conjoin (forms : formula list) : formula =
(flatten forms)
let resolve_pair (c1 : clause) (c2 : clause) : clause =
(match (find_pair2 c1 c2 (fun x y -> (x = negate y))) with
| None -> raise (Precondition "this should only be called on resolvable pairs")
| Some (l1, l2) -> (disjoin (remove1 l1 c1) (remove1 l2 c2)))
let pp_lit ppf (lit : literal) =
(Printf.fprintf ppf "%s%d" (match lit with | Pos n -> "" | Neg n -> "~") (var lit))
let pp_clause ppf (clause : clause) =
(List.iter (Printf.fprintf ppf "%a " pp_lit) clause)
let pp_form ppf (form : formula) =
(if (tautologyp form) then (Printf.fprintf ppf "True")
else (List.iter (Printf.fprintf ppf "(%a) " pp_clause) form))
end;;
module Model =
struct
include Formula
type model = literal list
let value_opt (x : int) (m : model) : literal option =
(find_opt (fun lit -> (var lit) = x) m)
let (#::) (x : 'a) (xs : ('a list) option) : ('a list) option =
(match xs with
| None -> None
| Some xs' -> (Some (x::xs')))
(* alternative version *)
(* let rec instantiate_clause (clause : clause) (m : model) : clause option =
* (match m with
* | [] -> Some clause
* | lit::m' ->
* (match (find_opt (fun lit' -> (lit = lit')) clause) with
* | Some lit' -> None
* | None ->
* (let nlit = (negate lit) in
* (let clause' = (filter (fun lit' -> lit' <> nlit) clause) in
* (instantiate_clause clause' m'))))) *)
let rec instantiate_clause (clause : clause) (m : model) : clause option =
(match clause with
| [] -> Some []
| lit::clause' ->
(match (value_opt (var lit) m) with
| None -> lit #:: (instantiate_clause clause' m)
| Some lit' -> (if (lit = lit') then None
else (instantiate_clause clause' m))))
let rec instantiate_formula (form : formula) (m : model) : formula =
(match form with
| [] -> []
| clause::form' -> (match (instantiate_clause clause m) with
| None -> (instantiate_formula form' m)
| Some clause' -> clause'::(instantiate_formula form' m)))
let modelsp (m : model) (form : formula) : bool =
(tautologyp (instantiate_formula form m))
let new_model () = []
let pp_model ppf (m : model) =
(List.iter (Printf.fprintf ppf "%a " pp_lit) m)
end;;