introduced SMT.distinct as a representation of the solvers' built-in predicate; check that SMT.distinct is always applied to an explicit list
authorboehmes
Fri, 29 Oct 2010 18:17:04 +0200
changeset 40274 6486c610a549
parent 40273 364aa76f7e21
child 40275 eed48b11abdb
introduced SMT.distinct as a representation of the solvers' built-in predicate; check that SMT.distinct is always applied to an explicit list
src/HOL/Boogie/Tools/boogie_loader.ML
src/HOL/SMT.thy
src/HOL/SMT_Examples/SMT_Examples.thy
src/HOL/SMT_Examples/SMT_Tests.thy
src/HOL/Tools/SMT/smt_normalize.ML
src/HOL/Tools/SMT/smt_translate.ML
src/HOL/Tools/SMT/smtlib_interface.ML
src/HOL/Tools/SMT/z3_interface.ML
src/HOL/Tools/SMT/z3_proof_reconstruction.ML
src/HOL/Tools/SMT/z3_proof_tools.ML
--- a/src/HOL/Boogie/Tools/boogie_loader.ML	Fri Oct 29 17:38:57 2010 +0200
+++ b/src/HOL/Boogie/Tools/boogie_loader.ML	Fri Oct 29 18:17:04 2010 +0200
@@ -191,7 +191,7 @@
             | NONE => NONE)
         | is_unique _ = NONE
       fun mk_unique_axiom T ts =
-        Const (@{const_name distinct}, HOLogic.listT T --> @{typ bool}) $
+        Const (@{const_name SMT.distinct}, HOLogic.listT T --> @{typ bool}) $
           HOLogic.mk_list T ts
     in
       map_filter is_unique fns
@@ -383,7 +383,7 @@
   fun mk_list T = HOLogic.mk_list T
 
   fun mk_distinct T ts =
-    Const (@{const_name distinct}, HOLogic.listT T --> @{typ bool}) $
+    Const (@{const_name SMT.distinct}, HOLogic.listT T --> @{typ bool}) $
       mk_list T ts
 
   fun quant name f = scan_line name (num -- num -- num) >> pair f
--- a/src/HOL/SMT.thy	Fri Oct 29 17:38:57 2010 +0200
+++ b/src/HOL/SMT.thy	Fri Oct 29 18:17:04 2010 +0200
@@ -49,6 +49,20 @@
 
 
 
+subsection {* Distinctness *}
+
+text {*
+As an abbreviation for a quadratic number of inequalities, SMT solvers
+provide a built-in @{text distinct}.  To avoid confusion with the
+already defined (and more general) @{term List.distinct}, a separate
+constant is defined.
+*}
+
+definition distinct :: "'a list \<Rightarrow> bool"
+where "distinct xs = List.distinct xs"
+
+
+
 subsection {* Higher-order encoding *}
 
 text {*
@@ -314,7 +328,7 @@
 
 hide_type (open) pattern
 hide_const Pattern term_eq
-hide_const (open) trigger pat nopat fun_app z3div z3mod
+hide_const (open) trigger pat nopat distinct fun_app z3div z3mod
 
 
 
--- a/src/HOL/SMT_Examples/SMT_Examples.thy	Fri Oct 29 17:38:57 2010 +0200
+++ b/src/HOL/SMT_Examples/SMT_Examples.thy	Fri Oct 29 18:17:04 2010 +0200
@@ -293,11 +293,11 @@
 
 lemma "(0 \<le> y + -1 * x \<or> \<not> 0 \<le> x \<or> 0 \<le> (x::int)) = (\<not> False)" by smt
 
-lemma "distinct [x < (3::int), 3 \<le> x]" by smt
+lemma "SMT.distinct [x < (3::int), 3 \<le> x]" by smt
 
 lemma
   assumes "a > (0::int)"
-  shows "distinct [a, a * 2, a - a]"
+  shows "SMT.distinct [a, a * 2, a - a]"
   using assms by smt
 
 lemma "
@@ -430,7 +430,7 @@
    False \<or> P = (x - 1 = y) \<or> (\<not>P \<longrightarrow> False)"
   by smt
 
-lemma "distinct [a + (1::nat), a * 2 + 3, a - a]" by smt
+lemma "SMT.distinct [a + (1::nat), a * 2 + 3, a - a]" by smt
 
 lemma "int (nat \<bar>x::int\<bar>) = \<bar>x\<bar>" by smt
 
--- a/src/HOL/SMT_Examples/SMT_Tests.thy	Fri Oct 29 17:38:57 2010 +0200
+++ b/src/HOL/SMT_Examples/SMT_Tests.thy	Fri Oct 29 18:17:04 2010 +0200
@@ -104,15 +104,15 @@
   by smt+
 
 lemma
-  "distinct []"
-  "distinct [a]"
-  "distinct [a, b, c] \<longrightarrow> a \<noteq> c"
-  "distinct [a, b, c] \<longrightarrow> d = b \<longrightarrow> a \<noteq> d"
-  "\<not> distinct [a, b, a, b]"
-  "a = b \<longrightarrow> \<not>distinct [a, b]"
-  "a = b \<and> a = c \<longrightarrow> \<not>distinct [a, b, c]"
-  "distinct [a, b, c, d] \<longrightarrow> distinct [d, b, c, a]"
-  "distinct [a, b, c, d] \<longrightarrow> distinct [a, b, c] \<and> distinct [b, c, d]"
+  "SMT.distinct []"
+  "SMT.distinct [a]"
+  "SMT.distinct [a, b, c] \<longrightarrow> a \<noteq> c"
+  "SMT.distinct [a, b, c] \<longrightarrow> d = b \<longrightarrow> a \<noteq> d"
+  "\<not> SMT.distinct [a, b, a, b]"
+  "a = b \<longrightarrow> \<not> SMT.distinct [a, b]"
+  "a = b \<and> a = c \<longrightarrow> \<not> SMT.distinct [a, b, c]"
+  "SMT.distinct [a, b, c, d] \<longrightarrow> SMT.distinct [d, b, c, a]"
+  "SMT.distinct [a, b, c, d] \<longrightarrow> SMT.distinct [a, b, c] \<and> SMT.distinct [b, c, d]"
   by smt+
 
 lemma
@@ -193,7 +193,7 @@
   by smt+
 
 lemma
-  "distinct [a, b, c] \<and> (\<forall>x y. f x = f y \<longrightarrow> y = x) \<longrightarrow> f a \<noteq> f b"
+  "SMT.distinct [a, b, c] \<and> (\<forall>x y. f x = f y \<longrightarrow> y = x) \<longrightarrow> f a \<noteq> f b"
   sorry  (* FIXME: injective function *)
 
 lemma
@@ -636,7 +636,7 @@
   "i1 \<noteq> i2 \<longrightarrow> (f (i1 := v1, i2 := v2)) i2 = v2"
   "i1 = i2 \<longrightarrow> (f (i1 := v1, i2 := v2)) i1 = v2"
   "i1 = i2 \<longrightarrow> (f (i1 := v1, i2 := v2)) i1 = v2"
-  "distinct [i1, i2, i3] \<longrightarrow> (f (i1 := v1, i2 := v2)) i3 = f i3"
+  "SMT.distinct [i1, i2, i3] \<longrightarrow> (f (i1 := v1, i2 := v2)) i3 = f i3"
   by smt+
 
 
--- a/src/HOL/Tools/SMT/smt_normalize.ML	Fri Oct 29 17:38:57 2010 +0200
+++ b/src/HOL/Tools/SMT/smt_normalize.ML	Fri Oct 29 18:17:04 2010 +0200
@@ -40,15 +40,18 @@
    three elements in the argument list) *)
 
 local
-  fun is_trivial_distinct (Const (@{const_name distinct}, _) $ t) =
-        length (HOLogic.dest_list t) <= 2
+  fun is_trivial_distinct (Const (@{const_name SMT.distinct}, _) $ t) =
+       (length (HOLogic.dest_list t) <= 2
+        handle TERM _ => error ("SMT: constant " ^
+          quote @{const_name SMT.distinct} ^ " must be applied to " ^
+          "an explicit list."))
     | is_trivial_distinct _ = false
 
   val thms = map mk_meta_eq @{lemma
-    "distinct [] = True"
-    "distinct [x] = True"
-    "distinct [x, y] = (x ~= y)"
-    by simp_all}
+    "SMT.distinct [] = True"
+    "SMT.distinct [x] = True"
+    "SMT.distinct [x, y] = (x ~= y)"
+    by (simp_all add: distinct_def)}
   fun distinct_conv _ =
     if_true_conv is_trivial_distinct (Conv.rewrs_conv thms)
 in
--- a/src/HOL/Tools/SMT/smt_translate.ML	Fri Oct 29 17:38:57 2010 +0200
+++ b/src/HOL/Tools/SMT/smt_translate.ML	Fri Oct 29 18:17:04 2010 +0200
@@ -233,7 +233,7 @@
         (q as Const (qn, _), [Abs (n, T, t')]) =>
           if is_some (quantifier qn) then q $ Abs (n, T, in_trig t')
           else as_term (in_term t)
-      | (Const (c as (@{const_name distinct}, T)), [t']) =>
+      | (Const (c as (@{const_name SMT.distinct}, T)), [t']) =>
           if is_builtin_distinct then Const (pred c) $ in_list T in_term t'
           else as_term (in_term t)
       | (Const c, ts) =>
@@ -377,7 +377,7 @@
       | (Const (@{const_name Let}, _), [t1, Abs (_, T, t2)]) =>
           transT T ##>> trans t1 ##>> trans t2 #>>
           (fn ((U, u1), u2) => SLet (U, u1, u2))
-      | (h as Const (c as (@{const_name distinct}, T)), [t1]) =>
+      | (h as Const (c as (@{const_name SMT.distinct}, T)), [t1]) =>
           (case builtin_fun ctxt c (HOLogic.dest_list t1) of
             SOME (n, ts) => fold_map trans ts #>> app n
           | NONE => transs h T [t1])
--- a/src/HOL/Tools/SMT/smtlib_interface.ML	Fri Oct 29 17:38:57 2010 +0200
+++ b/src/HOL/Tools/SMT/smtlib_interface.ML	Fri Oct 29 18:17:04 2010 +0200
@@ -167,7 +167,7 @@
   | conn @{const_name If} = SOME "if_then_else"
   | conn _ = NONE
 
-fun pred @{const_name distinct} _ = SOME "distinct"
+fun pred @{const_name SMT.distinct} _ = SOME "distinct"
   | pred @{const_name HOL.eq} _ = SOME "="
   | pred @{const_name term_eq} _ = SOME "="
   | pred @{const_name less} T = if_int_type T "<"
--- a/src/HOL/Tools/SMT/z3_interface.ML	Fri Oct 29 17:38:57 2010 +0200
+++ b/src/HOL/Tools/SMT/z3_interface.ML	Fri Oct 29 18:17:04 2010 +0200
@@ -65,7 +65,7 @@
 (** interface **)
 
 local
-  val {extra_norm, translate} = SMTLIB_Interface.interface
+  val {translate, ...} = SMTLIB_Interface.interface
   val {prefixes, strict, header, builtins, serialize} = translate
   val {is_builtin_pred, ...}= the strict
   val {builtin_typ, builtin_num, builtin_fun, ...} = builtins
@@ -189,7 +189,7 @@
 fun mk_list cT cts =
   fold_rev (Thm.mk_binop (instT cT cons_term)) cts (instT cT nil_term)
 
-val distinct = mk_inst_pair (destT1 o destT1) @{cpat distinct}
+val distinct = mk_inst_pair (destT1 o destT1) @{cpat SMT.distinct}
 fun mk_distinct [] = mk_true
   | mk_distinct (cts as (ct :: _)) =
       Thm.capply (instT' ct distinct) (mk_list (Thm.ctyp_of_term ct) cts)
--- a/src/HOL/Tools/SMT/z3_proof_reconstruction.ML	Fri Oct 29 17:38:57 2010 +0200
+++ b/src/HOL/Tools/SMT/z3_proof_reconstruction.ML	Fri Oct 29 18:17:04 2010 +0200
@@ -303,14 +303,14 @@
           prove disjI3 (Thm.capply @{cterm Not} ct2, false) (ct1, false)
       | @{term HOL.disj} $ _ $ _ =>
           prove disjI2 (Thm.capply @{cterm Not} ct1, false) (ct2, true)
-      | Const (@{const_name distinct}, _) $ _ =>
+      | Const (@{const_name SMT.distinct}, _) $ _ =>
           let
             fun dis_conv cv = Conv.arg_conv (Conv.arg1_conv cv)
             fun prv cu =
               let val (cu1, cu2) = Thm.dest_binop (Thm.dest_arg cu)
               in prove disjI4 (Thm.dest_arg cu2, true) (cu1, true) end
           in T.with_conv (dis_conv T.unfold_distinct_conv) prv ct end
-      | @{term Not} $ (Const (@{const_name distinct}, _) $ _) =>
+      | @{term Not} $ (Const (@{const_name SMT.distinct}, _) $ _) =>
           let
             fun dis_conv cv = Conv.arg_conv (Conv.arg1_conv (Conv.arg_conv cv))
             fun prv cu =
@@ -476,7 +476,7 @@
     (case Term.head_of (Thm.term_of cl) of
       @{term HOL.conj} => prove_nary L.is_conj (prove_eq_exn f)
     | @{term HOL.disj} => prove_nary L.is_disj (prove_eq_exn f)
-    | Const (@{const_name distinct}, _) => prove_distinct (prove_eq_safe f)
+    | Const (@{const_name SMT.distinct}, _) => prove_distinct (prove_eq_safe f)
     | _ => prove (prove_eq_safe f)) cp
 in
 fun monotonicity eqs ct =
--- a/src/HOL/Tools/SMT/z3_proof_tools.ML	Fri Oct 29 17:38:57 2010 +0200
+++ b/src/HOL/Tools/SMT/z3_proof_tools.ML	Fri Oct 29 18:17:04 2010 +0200
@@ -204,7 +204,7 @@
       | @{term HOL.disj} $ _ $ _ => abstr2 cvs ct
       | @{term HOL.implies} $ _ $ _ => abstr2 cvs ct
       | Const (@{const_name HOL.eq}, _) $ _ $ _ => abstr2 cvs ct
-      | Const (@{const_name distinct}, _) $ _ =>
+      | Const (@{const_name SMT.distinct}, _) $ _ =>
           if ext_logic then abs_arg (abs_list abstr fresh_abstraction) cvs ct
           else fresh_abstraction cvs ct
       | Const (@{const_name If}, _) $ _ $ _ $ _ =>
@@ -263,10 +263,10 @@
     (Conv.rewrs_conv [set1, set2, set3, set4] else_conv
     (Conv.rewr_conv set5 then_conv Conv.arg_conv set_conv)) ct
 
-  val dist1 = @{lemma "distinct [] == ~False" by simp}
-  val dist2 = @{lemma "distinct [x] == ~False" by simp}
-  val dist3 = @{lemma "distinct (x # xs) == x ~: set xs & distinct xs"
-    by simp}
+  val dist1 = @{lemma "SMT.distinct [] == ~False" by (simp add: distinct_def)}
+  val dist2 = @{lemma "SMT.distinct [x] == ~False" by (simp add: distinct_def)}
+  val dist3 = @{lemma "SMT.distinct (x # xs) == x ~: set xs & distinct xs"
+    by (simp add: distinct_def)}
 
   fun binop_conv cv1 cv2 = Conv.combination_conv (Conv.arg_conv cv1) cv2
 in