ProgTutorial/Recipes/external_solver.ML
author Christian Urban <urbanc@in.tum.de>
Tue, 11 Jun 2019 23:31:53 +0100
changeset 579 4dc20f6921d0
parent 189 069d525f8f1d
permissions -rw-r--r--
pdf
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
94
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
     1
signature IFF_SOLVER =
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
     2
sig
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
     3
  val decide : string -> bool
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
     4
end
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
     5
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
     6
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
     7
structure IffSolver : IFF_SOLVER =
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
     8
struct
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
     9
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    10
exception FAIL
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    11
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    12
datatype formula = Atom of string | Iff of formula * formula
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    13
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    14
fun scan s =
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    15
  let
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    16
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    17
    fun push yss = [] :: yss 
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    18
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    19
    fun add x (ys :: yss) = (x :: ys) :: yss
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    20
      | add _ _ = raise FAIL
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    21
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    22
    fun pop ([a, b] :: yss) = add (Iff (b, a)) yss
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    23
      | pop _ = raise FAIL
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    24
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    25
    fun formula [] acc = acc
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    26
      | formula ("(" :: xs) acc = formula xs (push acc)
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    27
      | formula (")" :: xs) acc = formula xs (pop acc)
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    28
      | formula ("<=>" :: xs) acc = formula xs acc
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    29
      | formula (x :: xs) acc = formula xs (add (Atom x) acc)
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    30
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    31
    val tokens = String.tokens (fn c => c = #" ") s
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    32
  in
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    33
    (case formula tokens [[]] of
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    34
      [[f]] => f
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    35
    | _ => raise FAIL)
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    36
  end
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    37
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    38
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    39
fun decide s =
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    40
  let
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    41
    fun fold_atoms f (Atom n) = f s
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    42
      | fold_atoms f (Iff (p, q)) = fold_atoms f p #> fold_atoms f q
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    43
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    44
    fun collect s tab =
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    45
      (case Symtab.lookup tab s of
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    46
        NONE => Symtab.update (s, false) tab
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    47
      | SOME v => Symtab.update (s, not v) tab)
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    48
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    49
    fun check tab = Symtab.fold (fn (_, v) => fn b => b andalso v) tab true
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    50
  in 
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    51
    (case try scan s of
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    52
      NONE => false
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    53
    | SOME f => check (fold_atoms collect f Symtab.empty))
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    54
  end
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    55
531e453c9d67 rewrote recipes describing external solvers
boehmes
parents:
diff changeset
    56
end