src/HOL/Library/Quickcheck_Narrowing.thy
changeset 41961 fdd37cfcd4a3
parent 41943 12f24ad566ea
child 41962 27a61a3266d8
equal deleted inserted replaced
41960:8a399da4cde1 41961:fdd37cfcd4a3
    84   (Haskell infix 4 "<")
    84   (Haskell infix 4 "<")
    85 
    85 
    86 code_type code_int
    86 code_type code_int
    87   (Haskell "Int")
    87   (Haskell "Int")
    88 
    88 
    89 subsubsection {* LSC's deep representation of types of terms *}
    89 subsubsection {* Narrowing's deep representation of types and terms *}
    90 
    90 
    91 datatype type = SumOfProd "type list list"
    91 datatype type = SumOfProd "type list list"
    92 
    92 
    93 datatype "term" = Var "code_int list" type | Ctr code_int "term list"
    93 datatype "term" = Var "code_int list" type | Ctr code_int "term list"
    94 
    94 
    95 datatype 'a cons = C type "(term list => 'a) list"
    95 datatype 'a cons = C type "(term list => 'a) list"
    96 
    96 
    97 subsubsection {* auxilary functions for LSC *}
    97 subsubsection {* auxilary functions for Narrowing *}
    98 
    98 
    99 consts nth :: "'a list => code_int => 'a"
    99 consts nth :: "'a list => code_int => 'a"
   100 
   100 
   101 code_const nth ("Haskell" infixl 9  "!!")
   101 code_const nth ("Haskell" infixl 9  "!!")
   102 
   102 
   110 
   110 
   111 consts map_index :: "(code_int * 'a => 'b) => 'a list => 'b list"  
   111 consts map_index :: "(code_int * 'a => 'b) => 'a list => 'b list"  
   112 
   112 
   113 consts split_At :: "code_int => 'a list => 'a list * 'a list"
   113 consts split_At :: "code_int => 'a list => 'a list * 'a list"
   114  
   114  
   115 subsubsection {* LSC's basic operations *}
   115 subsubsection {* Narrowing's basic operations *}
   116 
   116 
   117 type_synonym 'a series = "code_int => 'a cons"
   117 type_synonym 'a narrowing = "code_int => 'a cons"
   118 
   118 
   119 definition empty :: "'a series"
   119 definition empty :: "'a narrowing"
   120 where
   120 where
   121   "empty d = C (SumOfProd []) []"
   121   "empty d = C (SumOfProd []) []"
   122   
   122   
   123 definition cons :: "'a => 'a series"
   123 definition cons :: "'a => 'a narrowing"
   124 where
   124 where
   125   "cons a d = (C (SumOfProd [[]]) [(%_. a)])"
   125   "cons a d = (C (SumOfProd [[]]) [(%_. a)])"
   126 
   126 
   127 fun conv :: "(term list => 'a) list => term => 'a"
   127 fun conv :: "(term list => 'a) list => term => 'a"
   128 where
   128 where
   131 
   131 
   132 fun nonEmpty :: "type => bool"
   132 fun nonEmpty :: "type => bool"
   133 where
   133 where
   134   "nonEmpty (SumOfProd ps) = (\<not> (List.null ps))"
   134   "nonEmpty (SumOfProd ps) = (\<not> (List.null ps))"
   135 
   135 
   136 definition "apply" :: "('a => 'b) series => 'a series => 'b series"
   136 definition "apply" :: "('a => 'b) narrowing => 'a narrowing => 'b narrowing"
   137 where
   137 where
   138   "apply f a d =
   138   "apply f a d =
   139      (case f d of C (SumOfProd ps) cfs =>
   139      (case f d of C (SumOfProd ps) cfs =>
   140        case a (d - 1) of C ta cas =>
   140        case a (d - 1) of C ta cas =>
   141        let
   141        let
   142          shallow = (d > 0 \<and> nonEmpty ta);
   142          shallow = (d > 0 \<and> nonEmpty ta);
   143          cs = [(%xs'. (case xs' of [] => undefined | x # xs => cf xs (conv cas x))). shallow, cf <- cfs]
   143          cs = [(%xs'. (case xs' of [] => undefined | x # xs => cf xs (conv cas x))). shallow, cf <- cfs]
   144        in C (SumOfProd [ta # p. shallow, p <- ps]) cs)"
   144        in C (SumOfProd [ta # p. shallow, p <- ps]) cs)"
   145 
   145 
   146 definition sum :: "'a series => 'a series => 'a series"
   146 definition sum :: "'a narrowing => 'a narrowing => 'a narrowing"
   147 where
   147 where
   148   "sum a b d =
   148   "sum a b d =
   149     (case a d of C (SumOfProd ssa) ca => 
   149     (case a d of C (SumOfProd ssa) ca => 
   150       case b d of C (SumOfProd ssb) cb =>
   150       case b d of C (SumOfProd ssb) cb =>
   151       C (SumOfProd (ssa @ ssb)) (ca @ cb))"
   151       C (SumOfProd (ssa @ ssb)) (ca @ cb))"
   168     by (simp add: of_int_inverse)
   168     by (simp add: of_int_inverse)
   169   ultimately show ?thesis
   169   ultimately show ?thesis
   170     unfolding apply_def by (auto split: cons.split type.split simp add: Let_def)
   170     unfolding apply_def by (auto split: cons.split type.split simp add: Let_def)
   171 qed
   171 qed
   172 
   172 
   173 definition cons0 :: "'a => 'a series"
   173 definition cons0 :: "'a => 'a narrowing"
   174 where
   174 where
   175   "cons0 f = cons f"
   175   "cons0 f = cons f"
   176 
   176 
   177 type_synonym pos = "code_int list"
   177 type_synonym pos = "code_int list"
   178 (*
   178 (*
   196 | "total (Var p (SumOfProd ss)) = [y. x <- new p ss, y <- total x]"
   196 | "total (Var p (SumOfProd ss)) = [y. x <- new p ss, y <- total x]"
   197 by pat_completeness auto
   197 by pat_completeness auto
   198 
   198 
   199 termination sorry
   199 termination sorry
   200 *)
   200 *)
   201 subsubsection {* LSC's type class for enumeration *}
   201 subsubsection {* Narrowing generator type class *}
   202 
   202 
   203 class serial =
   203 class narrowing =
   204   fixes series :: "code_int => 'a cons"
   204   fixes narrowing :: "code_int => 'a cons"
   205 
   205 
   206 definition cons1 :: "('a::serial => 'b) => 'b series"
   206 definition cons1 :: "('a::narrowing => 'b) => 'b narrowing"
   207 where
   207 where
   208   "cons1 f = apply (cons f) series"
   208   "cons1 f = apply (cons f) narrowing"
   209 
   209 
   210 definition cons2 :: "('a :: serial => 'b :: serial => 'c) => 'c series"
   210 definition cons2 :: "('a :: narrowing => 'b :: narrowing => 'c) => 'c narrowing"
   211 where
   211 where
   212   "cons2 f = apply (apply (cons f) series) series"
   212   "cons2 f = apply (apply (cons f) narrowing) narrowing"
   213   
   213   
   214 instantiation unit :: serial
   214 instantiation unit :: narrowing
   215 begin
   215 begin
   216 
   216 
   217 definition
   217 definition
   218   "series = cons0 ()"
   218   "narrowing = cons0 ()"
   219 
   219 
   220 instance ..
   220 instance ..
   221 
   221 
   222 end
   222 end
   223 
   223 
   224 instantiation bool :: serial
   224 instantiation bool :: narrowing
   225 begin
   225 begin
   226 
   226 
   227 definition
   227 definition
   228   "series = sum (cons0 True) (cons0 False)" 
   228   "narrowing = sum (cons0 True) (cons0 False)" 
   229 
   229 
   230 instance ..
   230 instance ..
   231 
   231 
   232 end
   232 end
   233 
   233 
   234 instantiation option :: (serial) serial
   234 instantiation option :: (narrowing) narrowing
   235 begin
   235 begin
   236 
   236 
   237 definition
   237 definition
   238   "series = sum (cons0 None) (cons1 Some)"
   238   "narrowing = sum (cons0 None) (cons1 Some)"
   239 
   239 
   240 instance ..
   240 instance ..
   241 
   241 
   242 end
   242 end
   243 
   243 
   244 instantiation sum :: (serial, serial) serial
   244 instantiation sum :: (narrowing, narrowing) narrowing
   245 begin
   245 begin
   246 
   246 
   247 definition
   247 definition
   248   "series = sum (cons1 Inl) (cons1 Inr)"
   248   "narrowing = sum (cons1 Inl) (cons1 Inr)"
   249 
   249 
   250 instance ..
   250 instance ..
   251 
   251 
   252 end
   252 end
   253 
   253 
   254 instantiation list :: (serial) serial
   254 instantiation list :: (narrowing) narrowing
   255 begin
   255 begin
   256 
   256 
   257 function series_list :: "'a list series"
   257 function narrowing_list :: "'a list narrowing"
   258 where
   258 where
   259   "series_list d = sum (cons []) (apply (apply (cons Cons) series) series_list) d"
   259   "narrowing_list d = sum (cons []) (apply (apply (cons Cons) narrowing) narrowing_list) d"
   260 by pat_completeness auto
   260 by pat_completeness auto
   261 
   261 
   262 termination proof (relation "measure nat_of")
   262 termination proof (relation "measure nat_of")
   263 qed (auto simp add: of_int_inverse nat_of_def)
   263 qed (auto simp add: of_int_inverse nat_of_def)
   264     
   264     
   265 instance ..
   265 instance ..
   266 
   266 
   267 end
   267 end
   268 
   268 
   269 instantiation nat :: serial
   269 instantiation nat :: narrowing
   270 begin
   270 begin
   271 
   271 
   272 function series_nat :: "nat series"
   272 function narrowing_nat :: "nat narrowing"
   273 where
   273 where
   274   "series_nat d = sum (cons 0) (apply (cons Suc) series_nat) d"
   274   "narrowing_nat d = sum (cons 0) (apply (cons Suc) narrowing_nat) d"
   275 by pat_completeness auto
   275 by pat_completeness auto
   276 
   276 
   277 termination proof (relation "measure nat_of")
   277 termination proof (relation "measure nat_of")
   278 qed (auto simp add: of_int_inverse nat_of_def)
   278 qed (auto simp add: of_int_inverse nat_of_def)
   279 
   279 
   280 instance ..
   280 instance ..
   281 
   281 
   282 end
   282 end
   283 
   283 
   284 instantiation Enum.finite_1 :: serial
   284 instantiation Enum.finite_1 :: narrowing
   285 begin
   285 begin
   286 
   286 
   287 definition series_finite_1 :: "Enum.finite_1 series"
   287 definition narrowing_finite_1 :: "Enum.finite_1 narrowing"
   288 where
   288 where
   289   "series_finite_1 = cons (Enum.finite_1.a\<^isub>1 :: Enum.finite_1)"
   289   "narrowing_finite_1 = cons (Enum.finite_1.a\<^isub>1 :: Enum.finite_1)"
   290 
   290 
   291 instance ..
   291 instance ..
   292 
   292 
   293 end
   293 end
   294 
   294 
   295 instantiation Enum.finite_2 :: serial
   295 instantiation Enum.finite_2 :: narrowing
   296 begin
   296 begin
   297 
   297 
   298 definition series_finite_2 :: "Enum.finite_2 series"
   298 definition narrowing_finite_2 :: "Enum.finite_2 narrowing"
   299 where
   299 where
   300   "series_finite_2 = sum (cons (Enum.finite_2.a\<^isub>1 :: Enum.finite_2)) (cons (Enum.finite_2.a\<^isub>2 :: Enum.finite_2))"
   300   "narrowing_finite_2 = sum (cons (Enum.finite_2.a\<^isub>1 :: Enum.finite_2)) (cons (Enum.finite_2.a\<^isub>2 :: Enum.finite_2))"
   301 
   301 
   302 instance ..
   302 instance ..
   303 
   303 
   304 end
   304 end
   305 
   305 
   306 instantiation Enum.finite_3 :: serial
   306 instantiation Enum.finite_3 :: narrowing
   307 begin
   307 begin
   308 
   308 
   309 definition series_finite_3 :: "Enum.finite_3 series"
   309 definition narrowing_finite_3 :: "Enum.finite_3 narrowing"
   310 where
   310 where
   311   "series_finite_3 = sum (cons (Enum.finite_3.a\<^isub>1 :: Enum.finite_3)) (sum (cons (Enum.finite_3.a\<^isub>2 :: Enum.finite_3)) (cons (Enum.finite_3.a\<^isub>3 :: Enum.finite_3)))"
   311   "narrowing_finite_3 = sum (cons (Enum.finite_3.a\<^isub>1 :: Enum.finite_3)) (sum (cons (Enum.finite_3.a\<^isub>2 :: Enum.finite_3)) (cons (Enum.finite_3.a\<^isub>3 :: Enum.finite_3)))"
   312 
   312 
   313 instance ..
   313 instance ..
   314 
   314 
   315 end
   315 end
   316 
   316 
   317 instantiation Enum.finite_4 :: serial
   317 instantiation Enum.finite_4 :: narrowing
   318 begin
   318 begin
   319 
   319 
   320 definition series_finite_4 :: "Enum.finite_4 series"
   320 definition narrowing_finite_4 :: "Enum.finite_4 narrowing"
   321 where
   321 where
   322   "series_finite_4 = sum (cons Enum.finite_4.a\<^isub>1) (sum (cons Enum.finite_4.a\<^isub>2) (sum (cons Enum.finite_4.a\<^isub>3) (cons Enum.finite_4.a\<^isub>4)))"
   322   "narrowing_finite_4 = sum (cons Enum.finite_4.a\<^isub>1) (sum (cons Enum.finite_4.a\<^isub>2) (sum (cons Enum.finite_4.a\<^isub>3) (cons Enum.finite_4.a\<^isub>4)))"
   323 
   323 
   324 instance ..
   324 instance ..
   325 
   325 
   326 end
   326 end
   327 
   327 
   331 
   331 
   332 class is_testable
   332 class is_testable
   333 
   333 
   334 instance bool :: is_testable ..
   334 instance bool :: is_testable ..
   335 
   335 
   336 instance "fun" :: ("{term_of, serial}", is_testable) is_testable ..
   336 instance "fun" :: ("{term_of, narrowing}", is_testable) is_testable ..
   337 
   337 
   338 definition ensure_testable :: "'a :: is_testable => 'a :: is_testable"
   338 definition ensure_testable :: "'a :: is_testable => 'a :: is_testable"
   339 where
   339 where
   340   "ensure_testable f = f"
   340   "ensure_testable f = f"
   341 
   341