added generator_dseq compilation for a sound depth-limited compilation with small value generators
authorbulwahn
Thu, 21 Oct 2010 19:13:09 +0200
changeset 40051 b6acda4d1c29
parent 40050 638ce4dabe53
child 40052 ea46574ca815
added generator_dseq compilation for a sound depth-limited compilation with small value generators
src/HOL/Lazy_Sequence.thy
src/HOL/Tools/Predicate_Compile/predicate_compile_aux.ML
src/HOL/Tools/Predicate_Compile/predicate_compile_compilations.ML
src/HOL/Tools/Predicate_Compile/predicate_compile_core.ML
--- a/src/HOL/Lazy_Sequence.thy	Thu Oct 21 19:13:08 2010 +0200
+++ b/src/HOL/Lazy_Sequence.thy	Thu Oct 21 19:13:09 2010 +0200
@@ -140,6 +140,71 @@
   datatypes lazy_sequence = Lazy_Sequence
   functions map yield yieldn
 
+subsection {* Generator Sequences *}
+
+
+subsubsection {* General lazy sequence operation *}
+
+definition product :: "'a Lazy_Sequence.lazy_sequence \<Rightarrow> 'b Lazy_Sequence.lazy_sequence \<Rightarrow> ('a * 'b) Lazy_Sequence.lazy_sequence"
+where
+  "product s1 s2 = Lazy_Sequence.bind s1 (%a. Lazy_Sequence.bind s2 (%b. Lazy_Sequence.single (a, b)))"
+
+
+subsubsection {* small_lazy typeclasses *}
+
+class small_lazy =
+  fixes small_lazy :: "int \<Rightarrow> 'a Lazy_Sequence.lazy_sequence"
+
+instantiation unit :: small_lazy
+begin
+
+definition "small_lazy d = Lazy_Sequence.single ()"
+
+instance ..
+
+end
+
+instantiation int :: small_lazy
+begin
+
+text {* maybe optimise this expression -> append (single x) xs == cons x xs 
+Performance difference? *}
+
+function small_lazy' :: "int => int => int Lazy_Sequence.lazy_sequence"
+where "small_lazy' d i = (if d < i then Lazy_Sequence.empty else
+  Lazy_Sequence.append (Lazy_Sequence.single i) (small_lazy' d (i + 1)))"
+by pat_completeness auto
+
+termination 
+  by (relation "measure (%(d, i). nat (d + 1 - i))") auto
+
+definition "small_lazy d = small_lazy' d (- d)"
+
+instance ..
+
+end
+
+instantiation prod :: (small_lazy, small_lazy) small_lazy
+begin
+
+definition
+  "small_lazy d = product (small_lazy d) (small_lazy d)"
+
+instance ..
+
+end
+
+instantiation list :: (small_lazy) small_lazy
+begin
+
+fun small_lazy_list :: "int => 'a list Lazy_Sequence.lazy_sequence"
+where
+  "small_lazy_list d = Lazy_Sequence.append (Lazy_Sequence.single []) (if d > 0 then Lazy_Sequence.bind (product (small_lazy (d - 1)) (small_lazy (d - 1))) (%(x, xs). Lazy_Sequence.single (x # xs)) else Lazy_Sequence.empty)"
+
+instance ..
+
+end
+
 subsection {* With Hit Bound Value *}
 text {* assuming in negative context *}
 
@@ -149,7 +214,6 @@
 where
   [code]: "hit_bound = Lazy_Sequence (%u. Some (None, empty))"
 
-
 definition hb_single :: "'a => 'a hit_bound_lazy_sequence"
 where
   [code]: "hb_single x = Lazy_Sequence (%u. Some (Some x, empty))"
@@ -194,7 +258,10 @@
   "hb_not_seq xq = (case yield xq of None => single () | Some (x, xq) => empty)"
 
 hide_type (open) lazy_sequence
-hide_const (open) Empty Insert Lazy_Sequence yield empty single append flat map bind if_seq iterate_upto not_seq
-hide_fact yield.simps empty_def single_def append.simps flat.simps map.simps bind_def iterate_upto.simps if_seq_def not_seq_def
+hide_const (open) Empty Insert Lazy_Sequence yield empty single append flat map bind if_seq
+  iterate_upto not_seq product
+  
+hide_fact yield.simps empty_def single_def append.simps flat.simps map.simps bind_def
+  iterate_upto.simps product_def if_seq_def not_seq_def
 
 end
--- a/src/HOL/Tools/Predicate_Compile/predicate_compile_aux.ML	Thu Oct 21 19:13:08 2010 +0200
+++ b/src/HOL/Tools/Predicate_Compile/predicate_compile_aux.ML	Thu Oct 21 19:13:09 2010 +0200
@@ -90,6 +90,7 @@
   (* Different compilations *)
   datatype compilation = Pred | Depth_Limited | Random | Depth_Limited_Random | DSeq | Annotated
     | Pos_Random_DSeq | Neg_Random_DSeq | New_Pos_Random_DSeq | New_Neg_Random_DSeq
+    | Pos_Generator_DSeq | Neg_Generator_DSeq
   val negative_compilation_of : compilation -> compilation
   val compilation_for_polarity : bool -> compilation -> compilation
   val is_depth_limited_compilation : compilation -> bool 
@@ -635,12 +636,15 @@
 (* Different compilations *)
 
 datatype compilation = Pred | Depth_Limited | Random | Depth_Limited_Random | DSeq | Annotated
-  | Pos_Random_DSeq | Neg_Random_DSeq | New_Pos_Random_DSeq | New_Neg_Random_DSeq
+  | Pos_Random_DSeq | Neg_Random_DSeq | New_Pos_Random_DSeq | New_Neg_Random_DSeq |
+    Pos_Generator_DSeq | Neg_Generator_DSeq
 
 fun negative_compilation_of Pos_Random_DSeq = Neg_Random_DSeq
   | negative_compilation_of Neg_Random_DSeq = Pos_Random_DSeq
   | negative_compilation_of New_Pos_Random_DSeq = New_Neg_Random_DSeq
   | negative_compilation_of New_Neg_Random_DSeq = New_Pos_Random_DSeq
+  | negative_compilation_of Pos_Generator_DSeq = Neg_Generator_DSeq
+  | negative_compilation_of Pos_Generator_DSeq = Pos_Generator_DSeq
   | negative_compilation_of c = c
   
 fun compilation_for_polarity false Pos_Random_DSeq = Neg_Random_DSeq
@@ -648,7 +652,8 @@
   | compilation_for_polarity _ c = c
 
 fun is_depth_limited_compilation c =
-  (c = New_Pos_Random_DSeq) orelse (c = New_Neg_Random_DSeq)
+  (c = New_Pos_Random_DSeq) orelse (c = New_Neg_Random_DSeq) orelse
+  (c = Pos_Generator_DSeq) orelse (c = Pos_Generator_DSeq)
 
 fun string_of_compilation c =
   case c of
@@ -662,6 +667,8 @@
   | Neg_Random_DSeq => "neg_random_dseq"
   | New_Pos_Random_DSeq => "new_pos_random dseq"
   | New_Neg_Random_DSeq => "new_neg_random_dseq"
+  | Pos_Generator_DSeq => "pos_generator_dseq"
+  | Neg_Generator_DSeq => "neg_generator_dseq"
 
 val compilation_names = [("pred", Pred),
   ("random", Random),
@@ -669,7 +676,8 @@
   ("depth_limited_random", Depth_Limited_Random),
   (*("annotated", Annotated),*)
   ("dseq", DSeq), ("random_dseq", Pos_Random_DSeq),
-  ("new_random_dseq", New_Pos_Random_DSeq)]
+  ("new_random_dseq", New_Pos_Random_DSeq),
+  ("generator_dseq", Pos_Generator_DSeq)]
 
 val non_random_compilations = [Pred, Depth_Limited, DSeq, Annotated]
 
--- a/src/HOL/Tools/Predicate_Compile/predicate_compile_compilations.ML	Thu Oct 21 19:13:08 2010 +0200
+++ b/src/HOL/Tools/Predicate_Compile/predicate_compile_compilations.ML	Thu Oct 21 19:13:09 2010 +0200
@@ -157,6 +157,170 @@
 
 end;
 
+structure DSequence_CompFuns =
+struct
+
+fun mk_dseqT T = Type ("fun", [@{typ code_numeral}, Type ("fun", [@{typ bool},
+  Type (@{type_name Option.option}, [Type  (@{type_name Lazy_Sequence.lazy_sequence}, [T])])])])
+
+fun dest_dseqT (Type ("fun", [@{typ code_numeral}, Type ("fun", [@{typ bool},
+  Type (@{type_name Option.option}, [Type (@{type_name Lazy_Sequence.lazy_sequence}, [T])])])])) = T
+  | dest_dseqT T = raise TYPE ("dest_dseqT", [T], []);
+
+fun mk_bot T = Const (@{const_name DSequence.empty}, mk_dseqT T);
+
+fun mk_single t =
+  let val T = fastype_of t
+  in Const(@{const_name DSequence.single}, T --> mk_dseqT T) $ t end;
+
+fun mk_bind (x, f) =
+  let val T as Type ("fun", [_, U]) = fastype_of f
+  in
+    Const (@{const_name DSequence.bind}, fastype_of x --> T --> U) $ x $ f
+  end;
+
+val mk_sup = HOLogic.mk_binop @{const_name DSequence.union};
+
+fun mk_if cond = Const (@{const_name DSequence.if_seq},
+  HOLogic.boolT --> mk_dseqT HOLogic.unitT) $ cond;
+
+fun mk_iterate_upto T (f, from, to) = raise Fail "No iterate_upto compilation"
+
+fun mk_not t = let val T = mk_dseqT HOLogic.unitT
+  in Const (@{const_name DSequence.not_seq}, T --> T) $ t end
+
+fun mk_map T1 T2 tf tp = Const (@{const_name DSequence.map},
+  (T1 --> T2) --> mk_dseqT T1 --> mk_dseqT T2) $ tf $ tp
+
+val compfuns = Predicate_Compile_Aux.CompilationFuns
+    {mk_predT = mk_dseqT, dest_predT = dest_dseqT,
+    mk_bot = mk_bot, mk_single = mk_single, mk_bind = mk_bind, mk_sup = mk_sup, mk_if = mk_if,
+    mk_iterate_upto = mk_iterate_upto, mk_not = mk_not, mk_map = mk_map}
+
+end;
+
+structure New_Pos_DSequence_CompFuns =
+struct
+
+fun mk_pos_dseqT T =
+    @{typ code_numeral} --> Type (@{type_name Lazy_Sequence.lazy_sequence}, [T])
+
+fun dest_pos_dseqT (Type ("fun", [@{typ code_numeral},
+    Type (@{type_name Lazy_Sequence.lazy_sequence}, [T])])) = T
+  | dest_pos_dseqT T = raise TYPE ("dest_pos_dseqT", [T], []);
+
+fun mk_bot T = Const (@{const_name New_DSequence.pos_empty}, mk_pos_dseqT T);
+
+fun mk_single t =
+  let
+    val T = fastype_of t
+  in Const(@{const_name New_DSequence.pos_single}, T --> mk_pos_dseqT T) $ t end;
+
+fun mk_bind (x, f) =
+  let
+    val T as Type ("fun", [_, U]) = fastype_of f
+  in
+    Const (@{const_name New_DSequence.pos_bind}, fastype_of x --> T --> U) $ x $ f
+  end;
+  
+fun mk_decr_bind (x, f) =
+  let
+    val T as Type ("fun", [_, U]) = fastype_of f
+  in
+    Const (@{const_name New_DSequence.pos_decr_bind}, fastype_of x --> T --> U) $ x $ f
+  end;
+
+val mk_sup = HOLogic.mk_binop @{const_name New_DSequence.pos_union};
+
+fun mk_if cond = Const (@{const_name New_DSequence.pos_if_seq},
+  HOLogic.boolT --> mk_pos_dseqT HOLogic.unitT) $ cond;
+
+fun mk_iterate_upto T (f, from, to) = raise Fail "No iterate_upto compilation"
+
+fun mk_not t =
+  let
+    val pT = mk_pos_dseqT HOLogic.unitT
+    val nT =
+      @{typ code_numeral} --> Type (@{type_name Lazy_Sequence.lazy_sequence},
+        [Type (@{type_name Option.option}, [@{typ unit}])])
+  in Const (@{const_name New_DSequence.pos_not_seq}, nT --> pT) $ t end
+
+fun mk_map T1 T2 tf tp = Const (@{const_name New_DSequence.pos_map},
+  (T1 --> T2) --> mk_pos_dseqT T1 --> mk_pos_dseqT T2) $ tf $ tp
+
+val depth_limited_compfuns = Predicate_Compile_Aux.CompilationFuns
+    {mk_predT = mk_pos_dseqT, dest_predT = dest_pos_dseqT,
+    mk_bot = mk_bot, mk_single = mk_single, mk_bind = mk_decr_bind, mk_sup = mk_sup, mk_if = mk_if,
+    mk_iterate_upto = mk_iterate_upto, mk_not = mk_not, mk_map = mk_map}
+
+val depth_unlimited_compfuns = Predicate_Compile_Aux.CompilationFuns
+    {mk_predT = mk_pos_dseqT, dest_predT = dest_pos_dseqT,
+    mk_bot = mk_bot, mk_single = mk_single, mk_bind = mk_bind, mk_sup = mk_sup, mk_if = mk_if,
+    mk_iterate_upto = mk_iterate_upto, mk_not = mk_not, mk_map = mk_map}
+
+end;
+
+structure New_Neg_DSequence_CompFuns =
+struct
+
+fun mk_neg_dseqT T = @{typ code_numeral} -->
+  Type (@{type_name Lazy_Sequence.lazy_sequence}, [Type (@{type_name Option.option}, [T])])
+
+fun dest_neg_dseqT (Type ("fun", [@{typ code_numeral},
+    Type (@{type_name Lazy_Sequence.lazy_sequence}, [Type (@{type_name Option.option}, [T])])])) = T
+  | dest_neg_dseqT T = raise TYPE ("dest_neg_dseqT", [T], []);
+
+fun mk_bot T = Const (@{const_name New_DSequence.neg_empty}, mk_neg_dseqT T);
+
+fun mk_single t =
+  let
+    val T = fastype_of t
+  in Const(@{const_name New_DSequence.neg_single}, T --> mk_neg_dseqT T) $ t end;
+
+fun mk_bind (x, f) =
+  let
+    val T as Type ("fun", [_, U]) = fastype_of f
+  in
+    Const (@{const_name New_DSequence.neg_bind}, fastype_of x --> T --> U) $ x $ f
+  end;
+  
+fun mk_decr_bind (x, f) =
+  let
+    val T as Type ("fun", [_, U]) = fastype_of f
+  in
+    Const (@{const_name New_DSequence.neg_decr_bind}, fastype_of x --> T --> U) $ x $ f
+  end;
+
+val mk_sup = HOLogic.mk_binop @{const_name New_DSequence.neg_union};
+
+fun mk_if cond = Const (@{const_name New_DSequence.neg_if_seq},
+  HOLogic.boolT --> mk_neg_dseqT HOLogic.unitT) $ cond;
+
+fun mk_iterate_upto T (f, from, to) = raise Fail "No iterate_upto compilation"
+
+fun mk_not t =
+  let
+    val nT = mk_neg_dseqT HOLogic.unitT
+    val pT =
+      @{typ code_numeral} --> Type (@{type_name Lazy_Sequence.lazy_sequence},
+        [@{typ unit}])
+  in Const (@{const_name New_DSequence.neg_not_seq}, pT --> nT) $ t end
+
+fun mk_map T1 T2 tf tp = Const (@{const_name New_DSequence.neg_map},
+  (T1 --> T2) --> mk_neg_dseqT T1 --> mk_neg_dseqT T2) $ tf $ tp
+
+val depth_limited_compfuns = Predicate_Compile_Aux.CompilationFuns
+    {mk_predT = mk_neg_dseqT, dest_predT = dest_neg_dseqT,
+    mk_bot = mk_bot, mk_single = mk_single, mk_bind = mk_decr_bind, mk_sup = mk_sup, mk_if = mk_if,
+    mk_iterate_upto = mk_iterate_upto, mk_not = mk_not, mk_map = mk_map}
+
+val depth_unlimited_compfuns = Predicate_Compile_Aux.CompilationFuns
+    {mk_predT = mk_neg_dseqT, dest_predT = dest_neg_dseqT,
+    mk_bot = mk_bot, mk_single = mk_single, mk_bind = mk_bind, mk_sup = mk_sup, mk_if = mk_if,
+    mk_iterate_upto = mk_iterate_upto, mk_not = mk_not, mk_map = mk_map}
+
+end;
+
 structure New_Pos_Random_Sequence_CompFuns =
 struct
 
@@ -182,7 +346,7 @@
   in
     Const (@{const_name New_Random_Sequence.pos_bind}, fastype_of x --> T --> U) $ x $ f
   end;
-  
+
 fun mk_decr_bind (x, f) =
   let
     val T as Type ("fun", [_, U]) = fastype_of f
@@ -222,7 +386,6 @@
     {mk_predT = mk_pos_random_dseqT, dest_predT = dest_pos_random_dseqT,
     mk_bot = mk_bot, mk_single = mk_single, mk_bind = mk_bind, mk_sup = mk_sup, mk_if = mk_if,
     mk_iterate_upto = mk_iterate_upto, mk_not = mk_not, mk_map = mk_map}
-
 end;
 
 structure New_Neg_Random_Sequence_CompFuns =
--- a/src/HOL/Tools/Predicate_Compile/predicate_compile_core.ML	Thu Oct 21 19:13:08 2010 +0200
+++ b/src/HOL/Tools/Predicate_Compile/predicate_compile_core.ML	Thu Oct 21 19:13:09 2010 +0200
@@ -278,7 +278,7 @@
 fun function_names_of compilation ctxt name =
   case AList.lookup (op =) (#function_names (the_pred_data ctxt name)) compilation of
     NONE => error ("No " ^ string_of_compilation compilation
-      ^ "functions defined for predicate " ^ quote name)
+      ^ " functions defined for predicate " ^ quote name)
   | SOME fun_names => fun_names
 
 fun function_name_of compilation ctxt name mode =
@@ -848,16 +848,27 @@
 
 end;
 
-fun unlimited_compfuns_of true Predicate_Compile_Aux.New_Pos_Random_DSeq =
+fun unlimited_compfuns_of true New_Pos_Random_DSeq =
     New_Pos_Random_Sequence_CompFuns.depth_unlimited_compfuns
-  | unlimited_compfuns_of false Predicate_Compile_Aux.New_Pos_Random_DSeq =
+  | unlimited_compfuns_of false New_Pos_Random_DSeq =
     New_Neg_Random_Sequence_CompFuns.depth_unlimited_compfuns
-  
+  | unlimited_compfuns_of true Pos_Generator_DSeq =
+    New_Pos_DSequence_CompFuns.depth_unlimited_compfuns
+  | unlimited_compfuns_of false Pos_Generator_DSeq =
+    New_Neg_DSequence_CompFuns.depth_unlimited_compfuns
+  | unlimited_compfuns_of _ c =
+    raise Fail ("No unlimited compfuns for compilation " ^ string_of_compilation c)
+
 fun limited_compfuns_of true Predicate_Compile_Aux.New_Pos_Random_DSeq =
     New_Pos_Random_Sequence_CompFuns.depth_limited_compfuns
   | limited_compfuns_of false Predicate_Compile_Aux.New_Pos_Random_DSeq =
     New_Neg_Random_Sequence_CompFuns.depth_limited_compfuns
-
+  | limited_compfuns_of true Pos_Generator_DSeq =
+    New_Pos_DSequence_CompFuns.depth_limited_compfuns
+  | limited_compfuns_of false Pos_Generator_DSeq =
+    New_Neg_DSequence_CompFuns.depth_limited_compfuns
+  | limited_compfuns_of _ c =
+    raise Fail ("No limited compfuns for compilation " ^ string_of_compilation c)
 
 val depth_limited_comp_modifiers = Comp_Mod.Comp_Modifiers
   {
@@ -997,7 +1008,7 @@
   compilation = DSeq,
   function_name_prefix = "dseq_",
   compfuns = DSequence_CompFuns.compfuns,
-  mk_random = (fn _ => error "no random generation"),
+  mk_random = (fn _ => error "no random generation in dseq"),
   modify_funT = I,
   additional_arguments = K [],
   wrap_compilation = K (K (K (K (K I))))
@@ -1077,12 +1088,49 @@
   transform_additional_arguments = K I : (indprem -> term list -> term list)
   }
 
+val pos_generator_dseq_comp_modifiers = Comp_Mod.Comp_Modifiers
+  {
+  compilation = Pos_Generator_DSeq,
+  function_name_prefix = "generator_dseq_",
+  compfuns = New_Pos_DSequence_CompFuns.depth_limited_compfuns,
+  mk_random =
+    (fn T => fn additional_arguments =>
+      let
+        val small_lazy =
+         Const (@{const_name "Lazy_Sequence.small_lazy_class.small_lazy"},
+         @{typ "Int.int"} --> Type (@{type_name "Lazy_Sequence.lazy_sequence"}, [T])) 
+      in
+        absdummy (@{typ code_numeral}, small_lazy $ HOLogic.mk_number @{typ int} 3)
+      end
+    ),
+  modify_funT = I,
+  additional_arguments = K [],
+  wrap_compilation = K (K (K (K (K I))))
+   : (compilation_funs -> string -> typ -> mode -> term list -> term -> term),
+  transform_additional_arguments = K I : (indprem -> term list -> term list)
+  }
+
+val neg_generator_dseq_comp_modifiers = Comp_Mod.Comp_Modifiers
+  {
+  compilation = Neg_Generator_DSeq,
+  function_name_prefix = "generator_dseq_neg_",
+  compfuns = New_Neg_DSequence_CompFuns.depth_limited_compfuns,
+  mk_random = (fn _ => error "no random generation"),
+  modify_funT = I,
+  additional_arguments = K [],
+  wrap_compilation = K (K (K (K (K I))))
+   : (compilation_funs -> string -> typ -> mode -> term list -> term -> term),
+  transform_additional_arguments = K I : (indprem -> term list -> term list)
+  }
+
 fun negative_comp_modifiers_of comp_modifiers =
     (case Comp_Mod.compilation comp_modifiers of
       Pos_Random_DSeq => neg_random_dseq_comp_modifiers
     | Neg_Random_DSeq => pos_random_dseq_comp_modifiers
     | New_Pos_Random_DSeq => new_neg_random_dseq_comp_modifiers
-    | New_Neg_Random_DSeq => new_pos_random_dseq_comp_modifiers
+    | New_Neg_Random_DSeq => new_pos_random_dseq_comp_modifiers 
+    | Pos_Generator_DSeq => neg_generator_dseq_comp_modifiers
+    | Neg_Generator_DSeq => pos_generator_dseq_comp_modifiers
     | c => comp_modifiers)
 
 (** mode analysis **)
@@ -3099,6 +3147,25 @@
   use_generators = true,
   qname = "new_random_dseq_equation"})
 
+val add_generator_dseq_equations = gen_add_equations
+  (Steps {
+  define_functions =
+  fn options => fn preds => fn (s, modes) =>
+    let
+      val pos_modes = map_filter (fn (true, m) => SOME m | _ => NONE) modes
+      val neg_modes = map_filter (fn (false, m) => SOME m | _ => NONE) modes
+    in 
+      define_functions pos_generator_dseq_comp_modifiers New_Pos_DSequence_CompFuns.depth_limited_compfuns
+        options preds (s, pos_modes)
+      #> define_functions neg_generator_dseq_comp_modifiers New_Neg_DSequence_CompFuns.depth_limited_compfuns
+        options preds (s, neg_modes)
+    end,
+  prove = prove_by_skip,
+  add_code_equations = K (K I),
+  comp_modifiers = pos_generator_dseq_comp_modifiers,
+  use_generators = true,
+  qname = "generator_dseq_equation"})
+
 (** user interface **)
 
 (* code_pred_intro attribute *)
@@ -3160,6 +3227,7 @@
            | Random => add_random_equations
            | Depth_Limited_Random => add_depth_limited_random_equations
            | New_Pos_Random_DSeq => add_new_random_dseq_equations
+           | Pos_Generator_DSeq => add_generator_dseq_equations
            | compilation => error ("Compilation not supported")
            ) options [const]))
       end