hide constants and types introduced by SMT,
authorboehmes
Wed, 26 May 2010 15:34:47 +0200
changeset 37124 fe22fc54b876
parent 37123 9cce71cd4bf0
child 37125 66b0ae11a358
hide constants and types introduced by SMT, simplified SMT patterns syntax, added examples for SMT patterns
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_translate.ML
src/HOL/ex/Meson_Test.thy
--- a/src/HOL/Boogie/Tools/boogie_loader.ML	Wed May 26 11:59:06 2010 +0200
+++ b/src/HOL/Boogie/Tools/boogie_loader.ML	Wed May 26 15:34:47 2010 +0200
@@ -380,9 +380,11 @@
   fun mk_nary _ t [] = t
     | mk_nary f _ ts = uncurry (fold_rev f) (split_last ts)
 
+  fun mk_list T = HOLogic.mk_list T
+
   fun mk_distinct T ts =
-    Const (@{const_name distinct}, HOLogic.listT T --> @{typ bool}) $ 
-      HOLogic.mk_list T ts
+    Const (@{const_name distinct}, HOLogic.listT T --> @{typ bool}) $
+      mk_list T ts
 
   fun quant name f = scan_line name (num -- num -- num) >> pair f
   val quants =
@@ -391,20 +393,20 @@
     scan_fail "illegal quantifier kind"
   fun mk_quant q (n, T) t = q T $ Term.absfree (n, T, t)
 
-  val patternT = @{typ pattern}
+  val patternT = @{typ "SMT.pattern"}
   fun mk_pattern _ [] = raise TERM ("mk_pattern", [])
-    | mk_pattern n [t] = Const (n, Term.fastype_of t --> patternT) $ t
-    | mk_pattern n (t :: ts) =
-        let val T = patternT --> Term.fastype_of t --> patternT
-        in Const (@{const_name andpat}, T) $ mk_pattern n ts $ t end
+    | mk_pattern n ts =
+        let fun mk_pat t = Const (n, Term.fastype_of t --> patternT) $ t
+        in mk_list patternT (map mk_pat ts) end
   fun patt n c scan =
     scan_line n num :|-- scan_count scan >> (mk_pattern c)
   fun pattern scan =
-    patt "pat" @{const_name pat} scan ||
-    patt "nopat" @{const_name nopat} scan ||
+    patt "pat" @{const_name "SMT.pat"} scan ||
+    patt "nopat" @{const_name "SMT.nopat"} scan ||
     scan_fail "illegal pattern kind"
   fun mk_trigger [] t = t
-    | mk_trigger ps t = @{term trigger} $ HOLogic.mk_list patternT ps $ t
+    | mk_trigger ps t =
+        @{term "SMT.trigger"} $ mk_list @{typ "SMT.pattern list"} ps $ t
 
   fun make_label (line, col) = Free (label_name line col, @{typ bool})
   fun labelled_by kind pos t = kind $ make_label pos $ t
--- a/src/HOL/SMT.thy	Wed May 26 11:59:06 2010 +0200
+++ b/src/HOL/SMT.thy	Wed May 26 15:34:47 2010 +0200
@@ -31,24 +31,22 @@
 text {*
 Some SMT solvers support triggers for quantifier instantiation.
 Each trigger consists of one ore more patterns.  A pattern may either
-be a list of positive subterms (the first being tagged by "pat" and
-the consecutive subterms tagged by "andpat"), or a list of negative
-subterms (the first being tagged by "nopat" and the consecutive
-subterms tagged by "andpat").
+be a list of positive subterms (each being tagged by "pat"), or a
+list of negative subterms (each being tagged by "nopat").
+
+When an SMT solver finds a term matching a positive pattern (a
+pattern with positive subterms only), it instantiates the
+corresponding quantifier accordingly.  Negative patterns inhibit
+quantifier instantiations.  Each pattern should mention all preceding
+bound variables.
 *}
 
 datatype pattern = Pattern
 
-definition pat :: "'a \<Rightarrow> pattern"
-where "pat _ = Pattern"
+definition pat :: "'a \<Rightarrow> pattern" where "pat _ = Pattern"
+definition nopat :: "'a \<Rightarrow> pattern" where "nopat _ = Pattern"
 
-definition nopat :: "'a \<Rightarrow> pattern"
-where "nopat _ = Pattern"
-
-definition andpat :: "pattern \<Rightarrow> 'a \<Rightarrow> pattern" (infixl "andpat" 60)
-where "_ andpat _ = Pattern"
-
-definition trigger :: "pattern list \<Rightarrow> bool \<Rightarrow> bool"
+definition trigger :: "pattern list list \<Rightarrow> bool \<Rightarrow> bool"
 where "trigger _ P = P"
 
 
@@ -86,8 +84,7 @@
 following term-level equation symbol.
 *}
 
-definition term_eq :: "bool \<Rightarrow> bool \<Rightarrow> bool" (infix "term'_eq" 50)
-  where "(x term_eq y) = (x = y)"
+definition term_eq :: "bool \<Rightarrow> bool \<Rightarrow> bool" where "term_eq x y = (x = y)"
 
 
 
@@ -291,4 +288,10 @@
   "x + y = y + x"
   by auto
 
+
+
+hide_type (open) pattern
+hide_const Pattern "apply" term_eq
+hide_const (open) trigger pat nopat
+
 end
--- a/src/HOL/SMT_Examples/SMT_Examples.thy	Wed May 26 11:59:06 2010 +0200
+++ b/src/HOL/SMT_Examples/SMT_Examples.thy	Wed May 26 15:34:47 2010 +0200
@@ -395,7 +395,7 @@
 
 lemma "\<exists>x::int. (\<forall>y. y \<ge> x \<longrightarrow> y > 0) \<longrightarrow> x > 0" by smt
 
-lemma "\<forall>x::int. trigger [pat x] (x < a \<longrightarrow> 2 * x < 2 * a)" by smt
+lemma "\<forall>x::int. SMT.trigger [[SMT.pat x]] (x < a \<longrightarrow> 2 * x < 2 * a)" by smt
 
 
 subsection {* Non-linear arithmetic over integers and reals *}
--- a/src/HOL/SMT_Examples/SMT_Tests.thy	Wed May 26 11:59:06 2010 +0200
+++ b/src/HOL/SMT_Examples/SMT_Tests.thy	Wed May 26 15:34:47 2010 +0200
@@ -190,6 +190,16 @@
   "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
+  assumes "\<forall>x. SMT.trigger [[SMT.pat (f x)]] (f x = x)"
+  shows "f 1 = 1"
+  using assms by smt
+
+lemma
+  assumes "\<forall>x y. SMT.trigger [[SMT.pat (f x), SMT.pat (g y)]] (f x = g y)"
+  shows "f 1 = g 2"
+  using assms by smt
+
 
 
 section {* Meta logical connectives *}
--- a/src/HOL/Tools/SMT/smt_translate.ML	Wed May 26 11:59:06 2010 +0200
+++ b/src/HOL/Tools/SMT/smt_translate.ML	Wed May 26 15:34:47 2010 +0200
@@ -119,13 +119,19 @@
       if q = qname then group_quant qname (T :: Ts) u else (Ts, t)
   | group_quant _ Ts t = (Ts, t)
 
-fun dest_pat ts (Const (@{const_name pat}, _) $ t) = SPat (rev (t :: ts))
-  | dest_pat ts (Const (@{const_name nopat}, _) $ t) = SNoPat (rev (t :: ts))
-  | dest_pat ts (Const (@{const_name andpat}, _) $ p $ t) = dest_pat (t::ts) p
-  | dest_pat _ t = raise TERM ("dest_pat", [t])
+fun dest_pat (Const (@{const_name pat}, _) $ t) = (t, true)
+  | dest_pat (Const (@{const_name nopat}, _) $ t) = (t, false)
+  | dest_pat t = raise TERM ("dest_pat", [t])
+
+fun dest_pats [] = I
+  | dest_pats ts =
+      (case map dest_pat ts |> split_list ||> distinct (op =) of
+        (ps, [true]) => cons (SPat ps)
+      | (ps, [false]) => cons (SNoPat ps)
+      | _ => raise TERM ("dest_pats", ts))
 
 fun dest_trigger (@{term trigger} $ tl $ t) =
-      (map (dest_pat []) (HOLogic.dest_list tl), t)
+      (rev (fold (dest_pats o HOLogic.dest_list) (HOLogic.dest_list tl) []), t)
   | dest_trigger t = ([], t)
 
 fun dest_quant qn T t = quantifier qn |> Option.map (fn q =>
@@ -143,9 +149,9 @@
 
 (* enforce a strict separation between formulas and terms *)
 
-val term_eq_rewr = @{lemma "x term_eq y == x = y" by (simp add: term_eq_def)}
+val term_eq_rewr = @{lemma "term_eq x y == x = y" by (simp add: term_eq_def)}
 
-val term_bool = @{lemma "~(True term_eq False)" by (simp add: term_eq_def)}
+val term_bool = @{lemma "~(term_eq True False)" by (simp add: term_eq_def)}
 val term_bool' = Simplifier.rewrite_rule [term_eq_rewr] term_bool
 
 
@@ -210,11 +216,10 @@
 
     and in_pat ((c as Const (@{const_name pat}, _)) $ t) = c $ in_term t
       | in_pat ((c as Const (@{const_name nopat}, _)) $ t) = c $ in_term t
-      | in_pat ((c as Const (@{const_name andpat}, _)) $ p $ t) =
-          c $ in_pat p $ in_term t
       | in_pat t = raise TERM ("in_pat", [t])
 
-    and in_pats p = in_list @{typ pattern} in_pat p
+    and in_pats ps =
+      in_list @{typ "pattern list"} (in_list @{typ pattern} in_pat) ps
 
     and in_trig ((c as @{term trigger}) $ p $ t) = c $ in_pats p $ in_form t
       | in_trig t = in_form t
--- a/src/HOL/ex/Meson_Test.thy	Wed May 26 11:59:06 2010 +0200
+++ b/src/HOL/ex/Meson_Test.thy	Wed May 26 15:34:47 2010 +0200
@@ -16,7 +16,7 @@
   below and constants declared in HOL!
 *}
 
-hide_const (open) subset member quotient union inter "apply"
+hide_const (open) subset member quotient union inter
 
 text {*
   Test data for the MESON proof procedure