summaryrefslogtreecommitdiff
path: root/src/datatypes.ml
blob: cb712ecdc56942e10ec3890cd0361f694e78d858 (plain)
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
(* Data types useful for our theorem prover(s) *)

type proposition = (* logical proposition *)
  | True
  | False
  | Lit of string
  | Not of proposition
  | And of proposition * proposition
  | Or of proposition * proposition
  | Implies of proposition * proposition
  | Iff of proposition * proposition;;

type interpretation = (string * bool) list;; (* interpretation *)


(* Utility functions to deal with the data types *)

let rec string_of_prop = function
  | True -> "True"
  | False -> "False"
  | Lit symbol -> symbol
  | Not p -> "¬" ^ (string_of_prop p)
  | And (p1, p2) -> "(" ^ (string_of_prop p1) ^ " ∧ " ^ (string_of_prop p2) ^ ")"
  | Or (p1, p2) -> "(" ^ (string_of_prop p1) ^ " ∨ " ^ (string_of_prop p2) ^ ")"
  | Implies (p1, p2) -> "(" ^ (string_of_prop p1) ^ " → " ^ (string_of_prop p2) ^ ")"
  | Iff (p1, p2) -> "(" ^ (string_of_prop p1) ^ " ↔ " ^ (string_of_prop p2) ^ ")";;

let string_of_interpr (i : interpretation) =
  let rec stringify = function
    | [] -> ""
    | (s, value) :: [] -> "(" ^ s ^ ": " ^ (string_of_bool value) ^ ")"
    | (s, value) :: tl -> "(" ^ s ^ ": " ^ (string_of_bool value) ^ "), " ^ (stringify tl)
  in "[" ^ (stringify i) ^ "]";;

let print_prop prop = print_endline (string_of_prop prop)

let rec find (i : interpretation) symbol =
  match i with
  | [] -> None
  | (s, value) :: i ->
    if s = symbol then
      (if value then Some True else Some False)
    else
      find i symbol;;

(* Apply all relevant mappings from an interpretation to the symbols of a proposition *)
let rec interpret prop i =
  match prop with
  | True -> prop
  | False -> prop
  | Lit symbol ->
    (match find i symbol with
    | None -> prop
    | Some a -> a)
  | Not prop' ->
    (match interpret prop' i with
    | True -> False
    | False -> True
    | _ -> prop)
  | And (p1, p2) ->
    (match interpret p1 i, interpret p2 i with
    | False, _ -> False
    | _, False -> False
    | True, p2' -> p2'
    | p1', True -> p1'
    | _ -> prop)
  | Or (p1, p2) ->
    (match interpret p1 i, interpret p2 i with
    | True, _ -> True
    | _, True -> True
    | False, p2' -> p2'
    | p1', False -> p1'
    | _ -> prop)
  | Implies (p1, p2) -> interpret (Or(Not(p1), p2)) i
  | Iff (p1, p2) -> interpret (And(Implies(p1, p2), Implies(p2, p1))) i;;

(* Tests whether a proposition holds under a given interpretation *)
let test prop i =
  match interpret prop i with
  | True -> Some true
  | False -> Some false
  | _ -> None;; (* return None if cannot be determined *)

(* Convert a proposition to negation normal form *)
let to_nnf prop = "TODO"


(* Examples *)
let show_example p i =
  print_endline ("Proposition p:     " ^ (string_of_prop p));
  print_endline ("Interpretation i:  " ^ (string_of_interpr i));
  print_endline ("p under i:         " ^ (string_of_prop (interpret p i)) ^ "\n");;

let p1 = Iff(Not(Implies(Or(Lit "a", Lit "b"), And(Lit "b", Lit "c"))), True);;
let i1 = [("a", false); ("b", true); ("c", false)];;
let i2 = [("a", false); ("b", false)];;
let i3 = [("c", true)];;

show_example p1 i1;;
show_example p1 i2;;
show_example p1 i3;;
(* print_endline (match test p i with None -> "None" | Some a -> string_of_bool a);; *)