src/Tools/Metis/src/Units.sml
changeset 23442 028e39e5e8f3
child 23510 4521fead5609
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Tools/Metis/src/Units.sml	Wed Jun 20 22:07:52 2007 +0200
@@ -0,0 +1,106 @@
+(* ========================================================================= *)
+(* A STORE FOR UNIT THEOREMS                                                 *)
+(* Copyright (c) 2001-2006 Joe Hurd, distributed under the GNU GPL version 2 *)
+(* ========================================================================= *)
+
+structure Units :> Units =
+struct
+
+open Useful;
+
+(* ------------------------------------------------------------------------- *)
+(* A type of unit store.                                                     *)
+(* ------------------------------------------------------------------------- *)
+
+type unitThm = Literal.literal * Thm.thm;
+
+datatype units = Units of unitThm LiteralNet.literalNet;
+
+(* ------------------------------------------------------------------------- *)
+(* Basic operations.                                                         *)
+(* ------------------------------------------------------------------------- *)
+
+val empty = Units (LiteralNet.new {fifo = false});
+
+fun size (Units net) = LiteralNet.size net;
+
+fun toString units = "U{" ^ Int.toString (size units) ^ "}";
+
+val pp = Parser.ppMap toString Parser.ppString;
+
+(* ------------------------------------------------------------------------- *)
+(* Add units into the store.                                                 *)
+(* ------------------------------------------------------------------------- *)
+
+fun add (units as Units net) (uTh as (lit,th)) =
+    let
+      val net = LiteralNet.insert net (lit,uTh)
+    in
+      case total Literal.sym lit of
+        NONE => Units net
+      | SOME (lit' as (pol,_)) =>
+        let
+          val th' = (if pol then Rule.symEq else Rule.symNeq) lit th
+          val net = LiteralNet.insert net (lit',(lit',th'))
+        in
+          Units net
+        end
+    end;
+
+val addList = foldl (fn (th,u) => add u th);
+
+(* ------------------------------------------------------------------------- *)
+(* Matching.                                                                 *)
+(* ------------------------------------------------------------------------- *)
+
+fun match (Units net) lit =
+    let
+      fun check (uTh as (lit',_)) =
+          case total (Literal.match Subst.empty lit') lit of
+            NONE => NONE
+          | SOME sub => SOME (uTh,sub)
+    in
+      first check (LiteralNet.match net lit)
+    end;
+
+(* ------------------------------------------------------------------------- *)
+(* Reducing by repeated matching and resolution.                             *)
+(* ------------------------------------------------------------------------- *)
+
+fun reduce units =
+    let
+      fun red1 (lit,news_th) =
+          case total Literal.destIrrefl lit of
+            SOME tm =>
+            let
+              val (news,th) = news_th
+              val th = Thm.resolve lit th (Thm.refl tm)
+            in
+              (news,th)
+            end
+          | NONE =>
+            let
+              val lit' = Literal.negate lit
+            in
+              case match units lit' of
+                NONE => news_th
+              | SOME ((_,rth),sub) =>
+                let
+                  val (news,th) = news_th
+                  val rth = Thm.subst sub rth
+                  val th = Thm.resolve lit th rth
+                  val new = LiteralSet.delete (Thm.clause rth) lit'
+                  val news = LiteralSet.union new news
+                in
+                  (news,th)
+                end
+            end
+
+      fun red (news,th) =
+          if LiteralSet.null news then th
+          else red (LiteralSet.foldl red1 (LiteralSet.empty,th) news)
+    in
+      fn th => Rule.removeSym (red (Thm.clause th, th))
+    end;
+
+end