rewrite Z3 model equations one-by-one (the previous approach led to loss of information)
authorboehmes
Wed, 15 Dec 2010 08:39:24 +0100
changeset 41122 72176ec5e031
parent 41121 5c5d05963f93
child 41123 3bb9be510a9d
rewrite Z3 model equations one-by-one (the previous approach led to loss of information)
src/HOL/Tools/SMT/z3_model.ML
--- a/src/HOL/Tools/SMT/z3_model.ML	Wed Dec 15 08:39:24 2010 +0100
+++ b/src/HOL/Tools/SMT/z3_model.ML	Wed Dec 15 08:39:24 2010 +0100
@@ -194,6 +194,16 @@
       | NONE => (xs, t :: ts))
   in (fn ts => fold part ts ([], [])) end
 
+fun first_eq pred =
+  let
+    fun part _ [] = NONE
+      | part us (t :: ts) =
+          (case try HOLogic.dest_eq t of
+            SOME lr =>
+              if pred lr then SOME (lr, fold cons us ts) else part (t :: us) ts
+          | NONE => part (t :: us) ts)
+  in (fn ts => part [] ts) end
+
 fun replace_vars tab =
   let
     fun replace (v as Var _) = the_default v (AList.lookup (op aconv) tab v)
@@ -235,19 +245,17 @@
 
 fun unfold_eqs (eqs, defs) =
   let
-    val is_ground = not o Term.exists_subterm (fn Var _ => true | _ => false)
-    fun add_rewr l (r as Var _) = if is_ground l then SOME (r, l) else NONE
-      | add_rewr _ _ = NONE
+    val is_ground = not o Term.exists_subterm Term.is_Var
 
     fun is_trivial (Const (@{const_name HOL.eq}, _) $ t $ u) = t aconv u
       | is_trivial _ = false
 
-    fun replace rs = replace_vars rs #> filter_out is_trivial
+    fun replace r = replace_vars [r] #> filter_out is_trivial
 
     fun unfold (es, ds) =
-      (case partition_eqs add_rewr es of
-        ([], _) => (es, ds)
-      | (rs, es') => unfold (pairself (replace rs) (es', ds)))
+      (case first_eq (fn (l, Var _) => is_ground l | _ => false) es of
+        SOME ((l, r), es') => unfold (pairself (replace (r, l)) (es', ds))
+      | NONE => (es, ds))
 
   in unfold (eqs, defs) end