src/HOL/Predicate_Compile_Examples/Predicate_Compile_Examples.thy
author wenzelm
Thu, 16 Sep 2010 15:37:12 +0200
changeset 39747 c5ece2a7a86e
parent 39559 41ce0b56d858
child 39752 cf61ec140c4d
permissions -rw-r--r--
Isar "default" step needs to fail for solved problems, for clear distinction of '.' and '..' for example -- amending lapse introduced in 9de4d64eee3b (April 2004);
     1 theory Predicate_Compile_Examples
     2 imports Predicate_Compile_Alternative_Defs
     3 begin
     4 
     5 subsection {* Basic predicates *}
     6 
     7 inductive False' :: "bool"
     8 
     9 code_pred (expected_modes: bool) False' .
    10 code_pred [dseq] False' .
    11 code_pred [random_dseq] False' .
    12 
    13 values [expected "{}" pred] "{x. False'}"
    14 values [expected "{}" dseq 1] "{x. False'}"
    15 values [expected "{}" random_dseq 1, 1, 1] "{x. False'}"
    16 
    17 value "False'"
    18 
    19 inductive True' :: "bool"
    20 where
    21   "True ==> True'"
    22 
    23 code_pred True' .
    24 code_pred [dseq] True' .
    25 code_pred [random_dseq] True' .
    26 
    27 thm True'.equation
    28 thm True'.dseq_equation
    29 thm True'.random_dseq_equation
    30 values [expected "{()}" ]"{x. True'}"
    31 values [expected "{}" dseq 0] "{x. True'}"
    32 values [expected "{()}" dseq 1] "{x. True'}"
    33 values [expected "{()}" dseq 2] "{x. True'}"
    34 values [expected "{}" random_dseq 1, 1, 0] "{x. True'}"
    35 values [expected "{}" random_dseq 1, 1, 1] "{x. True'}"
    36 values [expected "{()}" random_dseq 1, 1, 2] "{x. True'}"
    37 values [expected "{()}" random_dseq 1, 1, 3] "{x. True'}"
    38 
    39 inductive EmptySet :: "'a \<Rightarrow> bool"
    40 
    41 code_pred (expected_modes: o => bool, i => bool) EmptySet .
    42 
    43 definition EmptySet' :: "'a \<Rightarrow> bool"
    44 where "EmptySet' = {}"
    45 
    46 code_pred (expected_modes: o => bool, i => bool) [inductify] EmptySet' .
    47 
    48 inductive EmptyRel :: "'a \<Rightarrow> 'b \<Rightarrow> bool"
    49 
    50 code_pred (expected_modes: o => o => bool, i => o => bool, o => i => bool, i => i => bool) EmptyRel .
    51 
    52 inductive EmptyClosure :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"
    53 for r :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
    54 
    55 code_pred
    56   (expected_modes: (o => o => bool) => o => o => bool, (o => o => bool) => i => o => bool,
    57          (o => o => bool) => o => i => bool, (o => o => bool) => i => i => bool,
    58          (i => o => bool) => o => o => bool, (i => o => bool) => i => o => bool,
    59          (i => o => bool) => o => i => bool, (i => o => bool) => i => i => bool,
    60          (o => i => bool) => o => o => bool, (o => i => bool) => i => o => bool,
    61          (o => i => bool) => o => i => bool, (o => i => bool) => i => i => bool,
    62          (i => i => bool) => o => o => bool, (i => i => bool) => i => o => bool,
    63          (i => i => bool) => o => i => bool, (i => i => bool) => i => i => bool)
    64   EmptyClosure .
    65 
    66 thm EmptyClosure.equation
    67 
    68 (* TODO: inductive package is broken!
    69 inductive False'' :: "bool"
    70 where
    71   "False \<Longrightarrow> False''"
    72 
    73 code_pred (expected_modes: []) False'' .
    74 
    75 inductive EmptySet'' :: "'a \<Rightarrow> bool"
    76 where
    77   "False \<Longrightarrow> EmptySet'' x"
    78 
    79 code_pred (expected_modes: [1]) EmptySet'' .
    80 code_pred (expected_modes: [], [1]) [inductify] EmptySet'' .
    81 *)
    82 
    83 consts a' :: 'a
    84 
    85 inductive Fact :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
    86 where
    87 "Fact a' a'"
    88 
    89 code_pred (expected_modes: o => o => bool, i => o => bool, o => i => bool, i => i => bool) Fact .
    90 
    91 inductive zerozero :: "nat * nat => bool"
    92 where
    93   "zerozero (0, 0)"
    94 
    95 code_pred (expected_modes: i => bool, i * o => bool, o * i => bool, o => bool) zerozero .
    96 code_pred [dseq] zerozero .
    97 code_pred [random_dseq] zerozero .
    98 
    99 thm zerozero.equation
   100 thm zerozero.dseq_equation
   101 thm zerozero.random_dseq_equation
   102 
   103 text {* We expect the user to expand the tuples in the values command.
   104 The following values command is not supported. *}
   105 (*values "{x. zerozero x}" *)
   106 text {* Instead, the user must type *}
   107 values "{(x, y). zerozero (x, y)}"
   108 
   109 values [expected "{}" dseq 0] "{(x, y). zerozero (x, y)}"
   110 values [expected "{(0::nat, 0::nat)}" dseq 1] "{(x, y). zerozero (x, y)}"
   111 values [expected "{(0::nat, 0::nat)}" dseq 2] "{(x, y). zerozero (x, y)}"
   112 values [expected "{}" random_dseq 1, 1, 2] "{(x, y). zerozero (x, y)}"
   113 values [expected "{(0::nat, 0:: nat)}" random_dseq 1, 1, 3] "{(x, y). zerozero (x, y)}"
   114 
   115 inductive nested_tuples :: "((int * int) * int * int) => bool"
   116 where
   117   "nested_tuples ((0, 1), 2, 3)"
   118 
   119 code_pred nested_tuples .
   120 
   121 inductive JamesBond :: "nat => int => code_numeral => bool"
   122 where
   123   "JamesBond 0 0 7"
   124 
   125 code_pred JamesBond .
   126 
   127 values [expected "{(0::nat, 0::int , 7::code_numeral)}"] "{(a, b, c). JamesBond a b c}"
   128 values [expected "{(0::nat, 7::code_numeral, 0:: int)}"] "{(a, c, b). JamesBond a b c}"
   129 values [expected "{(0::int, 0::nat, 7::code_numeral)}"] "{(b, a, c). JamesBond a b c}"
   130 values [expected "{(0::int, 7::code_numeral, 0::nat)}"] "{(b, c, a). JamesBond a b c}"
   131 values [expected "{(7::code_numeral, 0::nat, 0::int)}"] "{(c, a, b). JamesBond a b c}"
   132 values [expected "{(7::code_numeral, 0::int, 0::nat)}"] "{(c, b, a). JamesBond a b c}"
   133 
   134 values [expected "{(7::code_numeral, 0::int)}"] "{(a, b). JamesBond 0 b a}"
   135 values [expected "{(7::code_numeral, 0::nat)}"] "{(c, a). JamesBond a 0 c}"
   136 values [expected "{(0::nat, 7::code_numeral)}"] "{(a, c). JamesBond a 0 c}"
   137 
   138 
   139 subsection {* Alternative Rules *}
   140 
   141 datatype char = C | D | E | F | G | H
   142 
   143 inductive is_C_or_D
   144 where
   145   "(x = C) \<or> (x = D) ==> is_C_or_D x"
   146 
   147 code_pred (expected_modes: i => bool) is_C_or_D .
   148 thm is_C_or_D.equation
   149 
   150 inductive is_D_or_E
   151 where
   152   "(x = D) \<or> (x = E) ==> is_D_or_E x"
   153 
   154 lemma [code_pred_intro]:
   155   "is_D_or_E D"
   156 by (auto intro: is_D_or_E.intros)
   157 
   158 lemma [code_pred_intro]:
   159   "is_D_or_E E"
   160 by (auto intro: is_D_or_E.intros)
   161 
   162 code_pred (expected_modes: o => bool, i => bool) is_D_or_E
   163 proof -
   164   case is_D_or_E
   165   from this(1) show thesis
   166   proof
   167     fix xa
   168     assume x: "x = xa"
   169     assume "xa = D \<or> xa = E"
   170     from this show thesis
   171     proof
   172       assume "xa = D" from this x is_D_or_E(2) show thesis by simp
   173     next
   174       assume "xa = E" from this x is_D_or_E(3) show thesis by simp
   175     qed
   176   qed
   177 qed
   178 
   179 thm is_D_or_E.equation
   180 
   181 inductive is_F_or_G
   182 where
   183   "x = F \<or> x = G ==> is_F_or_G x"
   184 
   185 lemma [code_pred_intro]:
   186   "is_F_or_G F"
   187 by (auto intro: is_F_or_G.intros)
   188 
   189 lemma [code_pred_intro]:
   190   "is_F_or_G G"
   191 by (auto intro: is_F_or_G.intros)
   192 
   193 inductive is_FGH
   194 where
   195   "is_F_or_G x ==> is_FGH x"
   196 | "is_FGH H"
   197 
   198 text {* Compilation of is_FGH requires elimination rule for is_F_or_G *}
   199 
   200 code_pred (expected_modes: o => bool, i => bool) is_FGH
   201 proof -
   202   case is_F_or_G
   203   from this(1) show thesis
   204   proof
   205     fix xa
   206     assume x: "x = xa"
   207     assume "xa = F \<or> xa = G"
   208     from this show thesis
   209     proof
   210       assume "xa = F"
   211       from this x is_F_or_G(2) show thesis by simp
   212     next
   213       assume "xa = G"
   214       from this x is_F_or_G(3) show thesis by simp
   215     qed
   216   qed
   217 qed
   218 
   219 subsection {* Preprocessor Inlining  *}
   220 
   221 definition "equals == (op =)"
   222  
   223 inductive zerozero' :: "nat * nat => bool" where
   224   "equals (x, y) (0, 0) ==> zerozero' (x, y)"
   225 
   226 code_pred (expected_modes: i => bool) zerozero' .
   227 
   228 lemma zerozero'_eq: "zerozero' x == zerozero x"
   229 proof -
   230   have "zerozero' = zerozero"
   231     apply (auto simp add: mem_def)
   232     apply (cases rule: zerozero'.cases)
   233     apply (auto simp add: equals_def intro: zerozero.intros)
   234     apply (cases rule: zerozero.cases)
   235     apply (auto simp add: equals_def intro: zerozero'.intros)
   236     done
   237   from this show "zerozero' x == zerozero x" by auto
   238 qed
   239 
   240 declare zerozero'_eq [code_pred_inline]
   241 
   242 definition "zerozero'' x == zerozero' x"
   243 
   244 text {* if preprocessing fails, zerozero'' will not have all modes. *}
   245 
   246 code_pred (expected_modes: i * i => bool, i * o => bool, o * i => bool, o => bool) [inductify] zerozero'' .
   247 
   248 subsection {* Sets and Numerals *}
   249 
   250 definition
   251   "one_or_two = {Suc 0, (Suc (Suc 0))}"
   252 
   253 code_pred [inductify] one_or_two .
   254 
   255 code_pred [dseq] one_or_two .
   256 code_pred [random_dseq] one_or_two .
   257 thm one_or_two.dseq_equation
   258 values [expected "{Suc 0::nat, 2::nat}"] "{x. one_or_two x}"
   259 values [random_dseq 0,0,10] 3 "{x. one_or_two x}"
   260 
   261 inductive one_or_two' :: "nat => bool"
   262 where
   263   "one_or_two' 1"
   264 | "one_or_two' 2"
   265 
   266 code_pred one_or_two' .
   267 thm one_or_two'.equation
   268 
   269 values "{x. one_or_two' x}"
   270 
   271 definition one_or_two'':
   272   "one_or_two'' == {1, (2::nat)}"
   273 
   274 code_pred [inductify] one_or_two'' .
   275 thm one_or_two''.equation
   276 
   277 values "{x. one_or_two'' x}"
   278 
   279 subsection {* even predicate *}
   280 
   281 inductive even :: "nat \<Rightarrow> bool" and odd :: "nat \<Rightarrow> bool" where
   282     "even 0"
   283   | "even n \<Longrightarrow> odd (Suc n)"
   284   | "odd n \<Longrightarrow> even (Suc n)"
   285 
   286 code_pred (expected_modes: i => bool, o => bool) even .
   287 code_pred [dseq] even .
   288 code_pred [random_dseq] even .
   289 
   290 thm odd.equation
   291 thm even.equation
   292 thm odd.dseq_equation
   293 thm even.dseq_equation
   294 thm odd.random_dseq_equation
   295 thm even.random_dseq_equation
   296 
   297 values "{x. even 2}"
   298 values "{x. odd 2}"
   299 values 10 "{n. even n}"
   300 values 10 "{n. odd n}"
   301 values [expected "{}" dseq 2] "{x. even 6}"
   302 values [expected "{}" dseq 6] "{x. even 6}"
   303 values [expected "{()}" dseq 7] "{x. even 6}"
   304 values [dseq 2] "{x. odd 7}"
   305 values [dseq 6] "{x. odd 7}"
   306 values [dseq 7] "{x. odd 7}"
   307 values [expected "{()}" dseq 8] "{x. odd 7}"
   308 
   309 values [expected "{}" dseq 0] 8 "{x. even x}"
   310 values [expected "{0::nat}" dseq 1] 8 "{x. even x}"
   311 values [expected "{0::nat, 2}" dseq 3] 8 "{x. even x}"
   312 values [expected "{0::nat, 2}" dseq 4] 8 "{x. even x}"
   313 values [expected "{0::nat, 2, 4}" dseq 6] 8 "{x. even x}"
   314 
   315 values [random_dseq 1, 1, 0] 8 "{x. even x}"
   316 values [random_dseq 1, 1, 1] 8 "{x. even x}"
   317 values [random_dseq 1, 1, 2] 8 "{x. even x}"
   318 values [random_dseq 1, 1, 3] 8 "{x. even x}"
   319 values [random_dseq 1, 1, 6] 8 "{x. even x}"
   320 
   321 values [expected "{}" random_dseq 1, 1, 7] "{x. odd 7}"
   322 values [random_dseq 1, 1, 8] "{x. odd 7}"
   323 values [random_dseq 1, 1, 9] "{x. odd 7}"
   324 
   325 definition odd' where "odd' x == \<not> even x"
   326 
   327 code_pred (expected_modes: i => bool) [inductify] odd' .
   328 code_pred [dseq inductify] odd' .
   329 code_pred [random_dseq inductify] odd' .
   330 
   331 values [expected "{}" dseq 2] "{x. odd' 7}"
   332 values [expected "{()}" dseq 9] "{x. odd' 7}"
   333 values [expected "{}" dseq 2] "{x. odd' 8}"
   334 values [expected "{}" dseq 10] "{x. odd' 8}"
   335 
   336 
   337 inductive is_even :: "nat \<Rightarrow> bool"
   338 where
   339   "n mod 2 = 0 \<Longrightarrow> is_even n"
   340 
   341 code_pred (expected_modes: i => bool) is_even .
   342 
   343 subsection {* append predicate *}
   344 
   345 inductive append :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool" where
   346     "append [] xs xs"
   347   | "append xs ys zs \<Longrightarrow> append (x # xs) ys (x # zs)"
   348 
   349 code_pred (modes: i => i => o => bool as "concat", o => o => i => bool as "slice", o => i => i => bool as prefix,
   350   i => o => i => bool as suffix, i => i => i => bool) append .
   351 code_pred (modes: i \<Rightarrow> i \<Rightarrow> o \<Rightarrow> bool as "concat", o \<Rightarrow> o \<Rightarrow> i \<Rightarrow> bool as "slice", o \<Rightarrow> i \<Rightarrow> i \<Rightarrow> bool as prefix,
   352   i \<Rightarrow> o \<Rightarrow> i \<Rightarrow> bool as suffix, i \<Rightarrow> i \<Rightarrow> i \<Rightarrow> bool) append .
   353 
   354 code_pred [dseq] append .
   355 code_pred [random_dseq] append .
   356 
   357 thm append.equation
   358 thm append.dseq_equation
   359 thm append.random_dseq_equation
   360 
   361 values "{(ys, xs). append xs ys [0, Suc 0, 2]}"
   362 values "{zs. append [0, Suc 0, 2] [17, 8] zs}"
   363 values "{ys. append [0, Suc 0, 2] ys [0, Suc 0, 2, 17, 0, 5]}"
   364 
   365 values [expected "{}" dseq 0] 10 "{(xs, ys). append xs ys [1, 2, 3, 4, (5::nat)]}"
   366 values [expected "{(([]::nat list), [Suc 0, 2, 3, 4, (5::nat)])}" dseq 1] 10 "{(xs, ys). append xs ys [1, 2, 3, 4, (5::nat)]}"
   367 values [dseq 4] 10 "{(xs, ys). append xs ys [1, 2, 3, 4, (5::nat)]}"
   368 values [dseq 6] 10 "{(xs, ys). append xs ys [1, 2, 3, 4, (5::nat)]}"
   369 values [random_dseq 1, 1, 4] 10 "{(xs, ys). append xs ys [1, 2, 3, 4, (5::nat)]}"
   370 values [random_dseq 1, 1, 1] 10 "{(xs, ys, zs::int list). append xs ys zs}"
   371 values [random_dseq 1, 1, 3] 10 "{(xs, ys, zs::int list). append xs ys zs}"
   372 values [random_dseq 3, 1, 3] 10 "{(xs, ys, zs::int list). append xs ys zs}"
   373 values [random_dseq 1, 3, 3] 10 "{(xs, ys, zs::int list). append xs ys zs}"
   374 values [random_dseq 1, 1, 4] 10 "{(xs, ys, zs::int list). append xs ys zs}"
   375 
   376 value [code] "Predicate.the (concat [0::int, 1, 2] [3, 4, 5])"
   377 value [code] "Predicate.the (slice ([]::int list))"
   378 
   379 
   380 text {* tricky case with alternative rules *}
   381 
   382 inductive append2
   383 where
   384   "append2 [] xs xs"
   385 | "append2 xs ys zs \<Longrightarrow> append2 (x # xs) ys (x # zs)"
   386 
   387 lemma append2_Nil: "append2 [] (xs::'b list) xs"
   388   by (simp add: append2.intros(1))
   389 
   390 lemmas [code_pred_intro] = append2_Nil append2.intros(2)
   391 
   392 code_pred (expected_modes: i => i => o => bool, o => o => i => bool, o => i => i => bool,
   393   i => o => i => bool, i => i => i => bool) append2
   394 proof -
   395   case append2
   396   from append2(1) show thesis
   397   proof
   398     fix xs
   399     assume "xa = []" "xb = xs" "xc = xs"
   400     from this append2(2) show thesis by simp
   401   next
   402     fix xs ys zs x
   403     assume "xa = x # xs" "xb = ys" "xc = x # zs" "append2 xs ys zs"
   404     from this append2(3) show thesis by fastsimp
   405   qed
   406 qed
   407 
   408 inductive tupled_append :: "'a list \<times> 'a list \<times> 'a list \<Rightarrow> bool"
   409 where
   410   "tupled_append ([], xs, xs)"
   411 | "tupled_append (xs, ys, zs) \<Longrightarrow> tupled_append (x # xs, ys, x # zs)"
   412 
   413 code_pred (expected_modes: i * i * o => bool, o * o * i => bool, o * i * i => bool,
   414   i * o * i => bool, i * i * i => bool) tupled_append .
   415 
   416 code_pred (expected_modes: i \<times> i \<times> o \<Rightarrow> bool, o \<times> o \<times> i \<Rightarrow> bool, o \<times> i \<times> i \<Rightarrow> bool,
   417   i \<times> o \<times> i \<Rightarrow> bool, i \<times> i \<times> i \<Rightarrow> bool) tupled_append .
   418 
   419 code_pred [random_dseq] tupled_append .
   420 thm tupled_append.equation
   421 
   422 values "{xs. tupled_append ([(1::nat), 2, 3], [4, 5], xs)}"
   423 
   424 inductive tupled_append'
   425 where
   426 "tupled_append' ([], xs, xs)"
   427 | "[| ys = fst (xa, y); x # zs = snd (xa, y);
   428  tupled_append' (xs, ys, zs) |] ==> tupled_append' (x # xs, xa, y)"
   429 
   430 code_pred (expected_modes: i * i * o => bool, o * o * i => bool, o * i * i => bool,
   431   i * o * i => bool, i * i * i => bool) tupled_append' .
   432 thm tupled_append'.equation
   433 
   434 inductive tupled_append'' :: "'a list \<times> 'a list \<times> 'a list \<Rightarrow> bool"
   435 where
   436   "tupled_append'' ([], xs, xs)"
   437 | "ys = fst yszs ==> x # zs = snd yszs ==> tupled_append'' (xs, ys, zs) \<Longrightarrow> tupled_append'' (x # xs, yszs)"
   438 
   439 code_pred (expected_modes: i * i * o => bool, o * o * i => bool, o * i * i => bool,
   440   i * o * i => bool, i * i * i => bool) tupled_append'' .
   441 thm tupled_append''.equation
   442 
   443 inductive tupled_append''' :: "'a list \<times> 'a list \<times> 'a list \<Rightarrow> bool"
   444 where
   445   "tupled_append''' ([], xs, xs)"
   446 | "yszs = (ys, zs) ==> tupled_append''' (xs, yszs) \<Longrightarrow> tupled_append''' (x # xs, ys, x # zs)"
   447 
   448 code_pred (expected_modes: i * i * o => bool, o * o * i => bool, o * i * i => bool,
   449   i * o * i => bool, i * i * i => bool) tupled_append''' .
   450 thm tupled_append'''.equation
   451 
   452 subsection {* map_ofP predicate *}
   453 
   454 inductive map_ofP :: "('a \<times> 'b) list \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> bool"
   455 where
   456   "map_ofP ((a, b)#xs) a b"
   457 | "map_ofP xs a b \<Longrightarrow> map_ofP (x#xs) a b"
   458 
   459 code_pred (expected_modes: i => o => o => bool, i => i => o => bool, i => o => i => bool, i => i => i => bool) map_ofP .
   460 thm map_ofP.equation
   461 
   462 subsection {* filter predicate *}
   463 
   464 inductive filter1
   465 for P
   466 where
   467   "filter1 P [] []"
   468 | "P x ==> filter1 P xs ys ==> filter1 P (x#xs) (x#ys)"
   469 | "\<not> P x ==> filter1 P xs ys ==> filter1 P (x#xs) ys"
   470 
   471 code_pred (expected_modes: (i => bool) => i => o => bool, (i => bool) => i => i => bool) filter1 .
   472 code_pred [dseq] filter1 .
   473 code_pred [random_dseq] filter1 .
   474 
   475 thm filter1.equation
   476 
   477 values [expected "{[0::nat, 2, 4]}"] "{xs. filter1 even [0, 1, 2, 3, 4] xs}"
   478 values [expected "{}" dseq 9] "{xs. filter1 even [0, 1, 2, 3, 4] xs}"
   479 values [expected "{[0::nat, 2, 4]}" dseq 10] "{xs. filter1 even [0, 1, 2, 3, 4] xs}"
   480 
   481 inductive filter2
   482 where
   483   "filter2 P [] []"
   484 | "P x ==> filter2 P xs ys ==> filter2 P (x#xs) (x#ys)"
   485 | "\<not> P x ==> filter2 P xs ys ==> filter2 P (x#xs) ys"
   486 
   487 code_pred (expected_modes: (i => bool) => i => i => bool, (i => bool) => i => o => bool) filter2 .
   488 code_pred [dseq] filter2 .
   489 code_pred [random_dseq] filter2 .
   490 
   491 thm filter2.equation
   492 thm filter2.random_dseq_equation
   493 
   494 (*
   495 inductive filter3
   496 for P
   497 where
   498   "List.filter P xs = ys ==> filter3 P xs ys"
   499 
   500 code_pred (expected_modes: (o => bool) => i => o => bool, (o => bool) => i => i => bool , (i => bool) => i => o => bool, (i => bool) => i => i => bool) [skip_proof] filter3 .
   501 
   502 code_pred [dseq] filter3 .
   503 thm filter3.dseq_equation
   504 *)
   505 (*
   506 inductive filter4
   507 where
   508   "List.filter P xs = ys ==> filter4 P xs ys"
   509 
   510 code_pred (expected_modes: i => i => o => bool, i => i => i => bool) filter4 .
   511 (*code_pred [depth_limited] filter4 .*)
   512 (*code_pred [random] filter4 .*)
   513 *)
   514 subsection {* reverse predicate *}
   515 
   516 inductive rev where
   517     "rev [] []"
   518   | "rev xs xs' ==> append xs' [x] ys ==> rev (x#xs) ys"
   519 
   520 code_pred (expected_modes: i => o => bool, o => i => bool, i => i => bool) rev .
   521 
   522 thm rev.equation
   523 
   524 values "{xs. rev [0, 1, 2, 3::nat] xs}"
   525 
   526 inductive tupled_rev where
   527   "tupled_rev ([], [])"
   528 | "tupled_rev (xs, xs') \<Longrightarrow> tupled_append (xs', [x], ys) \<Longrightarrow> tupled_rev (x#xs, ys)"
   529 
   530 code_pred (expected_modes: i * o => bool, o * i => bool, i * i => bool) tupled_rev .
   531 thm tupled_rev.equation
   532 
   533 subsection {* partition predicate *}
   534 
   535 inductive partition :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool"
   536   for f where
   537     "partition f [] [] []"
   538   | "f x \<Longrightarrow> partition f xs ys zs \<Longrightarrow> partition f (x # xs) (x # ys) zs"
   539   | "\<not> f x \<Longrightarrow> partition f xs ys zs \<Longrightarrow> partition f (x # xs) ys (x # zs)"
   540 
   541 code_pred (expected_modes: (i => bool) => i => o => o => bool, (i => bool) => o => i => i => bool,
   542   (i => bool) => i => i => o => bool, (i => bool) => i => o => i => bool, (i => bool) => i => i => i => bool)
   543   partition .
   544 code_pred [dseq] partition .
   545 code_pred [random_dseq] partition .
   546 
   547 values 10 "{(ys, zs). partition is_even
   548   [0, Suc 0, 2, 3, 4, 5, 6, 7] ys zs}"
   549 values 10 "{zs. partition is_even zs [0, 2] [3, 5]}"
   550 values 10 "{zs. partition is_even zs [0, 7] [3, 5]}"
   551 
   552 inductive tupled_partition :: "('a \<Rightarrow> bool) \<Rightarrow> ('a list \<times> 'a list \<times> 'a list) \<Rightarrow> bool"
   553   for f where
   554    "tupled_partition f ([], [], [])"
   555   | "f x \<Longrightarrow> tupled_partition f (xs, ys, zs) \<Longrightarrow> tupled_partition f (x # xs, x # ys, zs)"
   556   | "\<not> f x \<Longrightarrow> tupled_partition f (xs, ys, zs) \<Longrightarrow> tupled_partition f (x # xs, ys, x # zs)"
   557 
   558 code_pred (expected_modes: (i => bool) => i => bool, (i => bool) => (i * i * o) => bool, (i => bool) => (i * o * i) => bool,
   559   (i => bool) => (o * i * i) => bool, (i => bool) => (i * o * o) => bool) tupled_partition .
   560 
   561 thm tupled_partition.equation
   562 
   563 lemma [code_pred_intro]:
   564   "r a b \<Longrightarrow> tranclp r a b"
   565   "r a b \<Longrightarrow> tranclp r b c \<Longrightarrow> tranclp r a c"
   566   by auto
   567 
   568 subsection {* transitive predicate *}
   569 
   570 text {* Also look at the tabled transitive closure in the Library *}
   571 
   572 code_pred (modes: (i => o => bool) => i => i => bool, (i => o => bool) => i => o => bool as forwards_trancl,
   573   (o => i => bool) => i => i => bool, (o => i => bool) => o => i => bool as backwards_trancl, (o => o => bool) => i => i => bool, (o => o => bool) => i => o => bool,
   574   (o => o => bool) => o => i => bool, (o => o => bool) => o => o => bool) tranclp
   575 proof -
   576   case tranclp
   577   from this converse_tranclpE[OF this(1)] show thesis by metis
   578 qed
   579 
   580 
   581 code_pred [dseq] tranclp .
   582 code_pred [random_dseq] tranclp .
   583 thm tranclp.equation
   584 thm tranclp.random_dseq_equation
   585 
   586 inductive rtrancl' :: "'a => 'a => ('a => 'a => bool) => bool" 
   587 where
   588   "rtrancl' x x r"
   589 | "r x y ==> rtrancl' y z r ==> rtrancl' x z r"
   590 
   591 code_pred [random_dseq] rtrancl' .
   592 
   593 thm rtrancl'.random_dseq_equation
   594 
   595 inductive rtrancl'' :: "('a * 'a * ('a \<Rightarrow> 'a \<Rightarrow> bool)) \<Rightarrow> bool"  
   596 where
   597   "rtrancl'' (x, x, r)"
   598 | "r x y \<Longrightarrow> rtrancl'' (y, z, r) \<Longrightarrow> rtrancl'' (x, z, r)"
   599 
   600 code_pred rtrancl'' .
   601 
   602 inductive rtrancl''' :: "('a * ('a * 'a) * ('a * 'a => bool)) => bool" 
   603 where
   604   "rtrancl''' (x, (x, x), r)"
   605 | "r (x, y) ==> rtrancl''' (y, (z, z), r) ==> rtrancl''' (x, (z, z), r)"
   606 
   607 code_pred rtrancl''' .
   608 
   609 
   610 inductive succ :: "nat \<Rightarrow> nat \<Rightarrow> bool" where
   611     "succ 0 1"
   612   | "succ m n \<Longrightarrow> succ (Suc m) (Suc n)"
   613 
   614 code_pred (modes: i => i => bool, i => o => bool, o => i => bool, o => o => bool) succ .
   615 code_pred [random_dseq] succ .
   616 thm succ.equation
   617 thm succ.random_dseq_equation
   618 
   619 values 10 "{(m, n). succ n m}"
   620 values "{m. succ 0 m}"
   621 values "{m. succ m 0}"
   622 
   623 text {* values command needs mode annotation of the parameter succ
   624 to disambiguate which mode is to be chosen. *} 
   625 
   626 values [mode: i => o => bool] 20 "{n. tranclp succ 10 n}"
   627 values [mode: o => i => bool] 10 "{n. tranclp succ n 10}"
   628 values 20 "{(n, m). tranclp succ n m}"
   629 
   630 inductive example_graph :: "int => int => bool"
   631 where
   632   "example_graph 0 1"
   633 | "example_graph 1 2"
   634 | "example_graph 1 3"
   635 | "example_graph 4 7"
   636 | "example_graph 4 5"
   637 | "example_graph 5 6"
   638 | "example_graph 7 6"
   639 | "example_graph 7 8"
   640  
   641 inductive not_reachable_in_example_graph :: "int => int => bool"
   642 where "\<not> (tranclp example_graph x y) ==> not_reachable_in_example_graph x y"
   643 
   644 code_pred (expected_modes: i => i => bool) not_reachable_in_example_graph .
   645 
   646 thm not_reachable_in_example_graph.equation
   647 thm tranclp.equation
   648 value "not_reachable_in_example_graph 0 3"
   649 value "not_reachable_in_example_graph 4 8"
   650 value "not_reachable_in_example_graph 5 6"
   651 text {* rtrancl compilation is strange! *}
   652 (*
   653 value "not_reachable_in_example_graph 0 4"
   654 value "not_reachable_in_example_graph 1 6"
   655 value "not_reachable_in_example_graph 8 4"*)
   656 
   657 code_pred [dseq] not_reachable_in_example_graph .
   658 
   659 values [dseq 6] "{x. tranclp example_graph 0 3}"
   660 
   661 values [dseq 0] "{x. not_reachable_in_example_graph 0 3}"
   662 values [dseq 0] "{x. not_reachable_in_example_graph 0 4}"
   663 values [dseq 20] "{x. not_reachable_in_example_graph 0 4}"
   664 values [dseq 6] "{x. not_reachable_in_example_graph 0 3}"
   665 values [dseq 3] "{x. not_reachable_in_example_graph 4 2}"
   666 values [dseq 6] "{x. not_reachable_in_example_graph 4 2}"
   667 
   668 
   669 inductive not_reachable_in_example_graph' :: "int => int => bool"
   670 where "\<not> (rtranclp example_graph x y) ==> not_reachable_in_example_graph' x y"
   671 
   672 code_pred not_reachable_in_example_graph' .
   673 
   674 value "not_reachable_in_example_graph' 0 3"
   675 (* value "not_reachable_in_example_graph' 0 5" would not terminate *)
   676 
   677 
   678 (*values [depth_limited 0] "{x. not_reachable_in_example_graph' 0 3}"*)
   679 (*values [depth_limited 3] "{x. not_reachable_in_example_graph' 0 3}"*) (* fails with undefined *)
   680 (*values [depth_limited 5] "{x. not_reachable_in_example_graph' 0 3}"*)
   681 (*values [depth_limited 1] "{x. not_reachable_in_example_graph' 0 4}"*)
   682 (*values [depth_limit = 4] "{x. not_reachable_in_example_graph' 0 4}"*) (* fails with undefined *)
   683 (*values [depth_limit = 20] "{x. not_reachable_in_example_graph' 0 4}"*) (* fails with undefined *)
   684 
   685 code_pred [dseq] not_reachable_in_example_graph' .
   686 
   687 (*thm not_reachable_in_example_graph'.dseq_equation*)
   688 
   689 (*values [dseq 0] "{x. not_reachable_in_example_graph' 0 3}"*)
   690 (*values [depth_limited 3] "{x. not_reachable_in_example_graph' 0 3}"*) (* fails with undefined *)
   691 (*values [depth_limited 5] "{x. not_reachable_in_example_graph' 0 3}"
   692 values [depth_limited 1] "{x. not_reachable_in_example_graph' 0 4}"*)
   693 (*values [depth_limit = 4] "{x. not_reachable_in_example_graph' 0 4}"*) (* fails with undefined *)
   694 (*values [depth_limit = 20] "{x. not_reachable_in_example_graph' 0 4}"*) (* fails with undefined *)
   695 
   696 subsection {* Free function variable *}
   697 
   698 inductive FF :: "nat => nat => bool"
   699 where
   700   "f x = y ==> FF x y"
   701 
   702 code_pred FF .
   703 
   704 subsection {* IMP *}
   705 
   706 types
   707   var = nat
   708   state = "int list"
   709 
   710 datatype com =
   711   Skip |
   712   Ass var "state => int" |
   713   Seq com com |
   714   IF "state => bool" com com |
   715   While "state => bool" com
   716 
   717 inductive exec :: "com => state => state => bool" where
   718 "exec Skip s s" |
   719 "exec (Ass x e) s (s[x := e(s)])" |
   720 "exec c1 s1 s2 ==> exec c2 s2 s3 ==> exec (Seq c1 c2) s1 s3" |
   721 "b s ==> exec c1 s t ==> exec (IF b c1 c2) s t" |
   722 "~b s ==> exec c2 s t ==> exec (IF b c1 c2) s t" |
   723 "~b s ==> exec (While b c) s s" |
   724 "b s1 ==> exec c s1 s2 ==> exec (While b c) s2 s3 ==> exec (While b c) s1 s3"
   725 
   726 code_pred exec .
   727 
   728 values "{t. exec
   729  (While (%s. s!0 > 0) (Seq (Ass 0 (%s. s!0 - 1)) (Ass 1 (%s. s!1 + 1))))
   730  [3,5] t}"
   731 
   732 
   733 inductive tupled_exec :: "(com \<times> state \<times> state) \<Rightarrow> bool" where
   734 "tupled_exec (Skip, s, s)" |
   735 "tupled_exec (Ass x e, s, s[x := e(s)])" |
   736 "tupled_exec (c1, s1, s2) ==> tupled_exec (c2, s2, s3) ==> tupled_exec (Seq c1 c2, s1, s3)" |
   737 "b s ==> tupled_exec (c1, s, t) ==> tupled_exec (IF b c1 c2, s, t)" |
   738 "~b s ==> tupled_exec (c2, s, t) ==> tupled_exec (IF b c1 c2, s, t)" |
   739 "~b s ==> tupled_exec (While b c, s, s)" |
   740 "b s1 ==> tupled_exec (c, s1, s2) ==> tupled_exec (While b c, s2, s3) ==> tupled_exec (While b c, s1, s3)"
   741 
   742 code_pred tupled_exec .
   743 
   744 values "{s. tupled_exec (While (%s. s!0 > 0) (Seq (Ass 0 (%s. s!0 - 1)) (Ass 1 (%s. s!1 + 1))), [3, 5], s)}"
   745 
   746 subsection {* CCS *}
   747 
   748 text{* This example formalizes finite CCS processes without communication or
   749 recursion. For simplicity, labels are natural numbers. *}
   750 
   751 datatype proc = nil | pre nat proc | or proc proc | par proc proc
   752 
   753 inductive step :: "proc \<Rightarrow> nat \<Rightarrow> proc \<Rightarrow> bool" where
   754 "step (pre n p) n p" |
   755 "step p1 a q \<Longrightarrow> step (or p1 p2) a q" |
   756 "step p2 a q \<Longrightarrow> step (or p1 p2) a q" |
   757 "step p1 a q \<Longrightarrow> step (par p1 p2) a (par q p2)" |
   758 "step p2 a q \<Longrightarrow> step (par p1 p2) a (par p1 q)"
   759 
   760 code_pred step .
   761 
   762 inductive steps where
   763 "steps p [] p" |
   764 "step p a q \<Longrightarrow> steps q as r \<Longrightarrow> steps p (a#as) r"
   765 
   766 code_pred steps .
   767 
   768 values 3 
   769  "{as . steps (par (or (pre 0 nil) (pre 1 nil)) (pre 2 nil)) as (par nil nil)}"
   770 
   771 values 5
   772  "{as . steps (par (or (pre 0 nil) (pre 1 nil)) (pre 2 nil)) as (par nil nil)}"
   773 
   774 values 3 "{(a,q). step (par nil nil) a q}"
   775 
   776 
   777 inductive tupled_step :: "(proc \<times> nat \<times> proc) \<Rightarrow> bool"
   778 where
   779 "tupled_step (pre n p, n, p)" |
   780 "tupled_step (p1, a, q) \<Longrightarrow> tupled_step (or p1 p2, a, q)" |
   781 "tupled_step (p2, a, q) \<Longrightarrow> tupled_step (or p1 p2, a, q)" |
   782 "tupled_step (p1, a, q) \<Longrightarrow> tupled_step (par p1 p2, a, par q p2)" |
   783 "tupled_step (p2, a, q) \<Longrightarrow> tupled_step (par p1 p2, a, par p1 q)"
   784 
   785 code_pred tupled_step .
   786 thm tupled_step.equation
   787 
   788 subsection {* divmod *}
   789 
   790 inductive divmod_rel :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool" where
   791     "k < l \<Longrightarrow> divmod_rel k l 0 k"
   792   | "k \<ge> l \<Longrightarrow> divmod_rel (k - l) l q r \<Longrightarrow> divmod_rel k l (Suc q) r"
   793 
   794 code_pred divmod_rel .
   795 thm divmod_rel.equation
   796 value [code] "Predicate.the (divmod_rel_i_i_o_o 1705 42)"
   797 
   798 subsection {* Transforming predicate logic into logic programs *}
   799 
   800 subsection {* Transforming functions into logic programs *}
   801 definition
   802   "case_f xs ys = (case (xs @ ys) of [] => [] | (x # xs) => xs)"
   803 
   804 code_pred [inductify, skip_proof] case_f .
   805 thm case_fP.equation
   806 
   807 fun fold_map_idx where
   808   "fold_map_idx f i y [] = (y, [])"
   809 | "fold_map_idx f i y (x # xs) =
   810  (let (y', x') = f i y x; (y'', xs') = fold_map_idx f (Suc i) y' xs
   811  in (y'', x' # xs'))"
   812 
   813 code_pred [inductify] fold_map_idx .
   814 
   815 subsection {* Minimum *}
   816 
   817 definition Min
   818 where "Min s r x \<equiv> s x \<and> (\<forall>y. r x y \<longrightarrow> x = y)"
   819 
   820 code_pred [inductify] Min .
   821 thm Min.equation
   822 
   823 subsection {* Lexicographic order *}
   824 
   825 declare lexord_def[code_pred_def]
   826 code_pred [inductify] lexord .
   827 code_pred [random_dseq inductify] lexord .
   828 
   829 thm lexord.equation
   830 thm lexord.random_dseq_equation
   831 
   832 inductive less_than_nat :: "nat * nat => bool"
   833 where
   834   "less_than_nat (0, x)"
   835 | "less_than_nat (x, y) ==> less_than_nat (Suc x, Suc y)"
   836  
   837 code_pred less_than_nat .
   838 
   839 code_pred [dseq] less_than_nat .
   840 code_pred [random_dseq] less_than_nat .
   841 
   842 inductive test_lexord :: "nat list * nat list => bool"
   843 where
   844   "lexord less_than_nat (xs, ys) ==> test_lexord (xs, ys)"
   845 
   846 code_pred test_lexord .
   847 code_pred [dseq] test_lexord .
   848 code_pred [random_dseq] test_lexord .
   849 thm test_lexord.dseq_equation
   850 thm test_lexord.random_dseq_equation
   851 
   852 values "{x. test_lexord ([1, 2, 3], [1, 2, 5])}"
   853 (*values [depth_limited 5] "{x. test_lexord ([1, 2, 3], [1, 2, 5])}"*)
   854 
   855 lemmas [code_pred_def] = lexn_conv lex_conv lenlex_conv
   856 (*
   857 code_pred [inductify] lexn .
   858 thm lexn.equation
   859 *)
   860 (*
   861 code_pred [random_dseq inductify] lexn .
   862 thm lexn.random_dseq_equation
   863 
   864 values [random_dseq 4, 4, 6] 100 "{(n, xs, ys::int list). lexn (%(x, y). x <= y) n (xs, ys)}"
   865 *)
   866 inductive has_length
   867 where
   868   "has_length [] 0"
   869 | "has_length xs i ==> has_length (x # xs) (Suc i)" 
   870 
   871 lemma has_length:
   872   "has_length xs n = (length xs = n)"
   873 proof (rule iffI)
   874   assume "has_length xs n"
   875   from this show "length xs = n"
   876     by (rule has_length.induct) auto
   877 next
   878   assume "length xs = n"
   879   from this show "has_length xs n"
   880     by (induct xs arbitrary: n) (auto intro: has_length.intros)
   881 qed
   882 
   883 lemma lexn_intros [code_pred_intro]:
   884   "has_length xs i ==> has_length ys i ==> r (x, y) ==> lexn r (Suc i) (x # xs, y # ys)"
   885   "lexn r i (xs, ys) ==> lexn r (Suc i) (x # xs, x # ys)"
   886 proof -
   887   assume "has_length xs i" "has_length ys i" "r (x, y)"
   888   from this has_length show "lexn r (Suc i) (x # xs, y # ys)"
   889     unfolding lexn_conv Collect_def mem_def
   890     by fastsimp
   891 next
   892   assume "lexn r i (xs, ys)"
   893   thm lexn_conv
   894   from this show "lexn r (Suc i) (x#xs, x#ys)"
   895     unfolding Collect_def mem_def lexn_conv
   896     apply auto
   897     apply (rule_tac x="x # xys" in exI)
   898     by auto
   899 qed
   900 
   901 code_pred [random_dseq] lexn
   902 proof -
   903   fix r n xs ys
   904   assume 1: "lexn r n (xs, ys)"
   905   assume 2: "\<And>r' i x xs' y ys'. r = r' ==> n = Suc i ==> (xs, ys) = (x # xs', y # ys') ==> has_length xs' i ==> has_length ys' i ==> r' (x, y) ==> thesis"
   906   assume 3: "\<And>r' i x xs' ys'. r = r' ==> n = Suc i ==> (xs, ys) = (x # xs', x # ys') ==> lexn r' i (xs', ys') ==> thesis"
   907   from 1 2 3 show thesis
   908     unfolding lexn_conv Collect_def mem_def
   909     apply (auto simp add: has_length)
   910     apply (case_tac xys)
   911     apply auto
   912     apply fastsimp
   913     apply fastsimp done
   914 qed
   915 
   916 values [random_dseq 1, 2, 5] 10 "{(n, xs, ys::int list). lexn (%(x, y). x <= y) n (xs, ys)}"
   917 
   918 code_pred [inductify, skip_proof] lex .
   919 thm lex.equation
   920 thm lex_def
   921 declare lenlex_conv[code_pred_def]
   922 code_pred [inductify, skip_proof] lenlex .
   923 thm lenlex.equation
   924 
   925 code_pred [random_dseq inductify] lenlex .
   926 thm lenlex.random_dseq_equation
   927 
   928 values [random_dseq 4, 2, 4] 100 "{(xs, ys::int list). lenlex (%(x, y). x <= y) (xs, ys)}"
   929 
   930 thm lists.intros
   931 code_pred [inductify] lists .
   932 thm lists.equation
   933 
   934 subsection {* AVL Tree *}
   935 
   936 datatype 'a tree = ET | MKT 'a "'a tree" "'a tree" nat
   937 fun height :: "'a tree => nat" where
   938 "height ET = 0"
   939 | "height (MKT x l r h) = max (height l) (height r) + 1"
   940 
   941 primrec avl :: "'a tree => bool"
   942 where
   943   "avl ET = True"
   944 | "avl (MKT x l r h) = ((height l = height r \<or> height l = 1 + height r \<or> height r = 1+height l) \<and> 
   945   h = max (height l) (height r) + 1 \<and> avl l \<and> avl r)"
   946 (*
   947 code_pred [inductify] avl .
   948 thm avl.equation*)
   949 
   950 code_pred [new_random_dseq inductify] avl .
   951 thm avl.new_random_dseq_equation
   952 
   953 values [new_random_dseq 2, 1, 7] 5 "{t:: int tree. avl t}"
   954 
   955 fun set_of
   956 where
   957 "set_of ET = {}"
   958 | "set_of (MKT n l r h) = insert n (set_of l \<union> set_of r)"
   959 
   960 fun is_ord :: "nat tree => bool"
   961 where
   962 "is_ord ET = True"
   963 | "is_ord (MKT n l r h) =
   964  ((\<forall>n' \<in> set_of l. n' < n) \<and> (\<forall>n' \<in> set_of r. n < n') \<and> is_ord l \<and> is_ord r)"
   965 
   966 code_pred (expected_modes: i => o => bool, i => i => bool) [inductify] set_of .
   967 thm set_of.equation
   968 
   969 code_pred (expected_modes: i => bool) [inductify] is_ord .
   970 thm is_ord_aux.equation
   971 thm is_ord.equation
   972 
   973 subsection {* Definitions about Relations *}
   974 
   975 term "converse"
   976 code_pred (modes:
   977   (i * i => bool) => i * i => bool,
   978   (i * o => bool) => o * i => bool,
   979   (i * o => bool) => i * i => bool,
   980   (o * i => bool) => i * o => bool,
   981   (o * i => bool) => i * i => bool,
   982   (o * o => bool) => o * o => bool,
   983   (o * o => bool) => i * o => bool,
   984   (o * o => bool) => o * i => bool,
   985   (o * o => bool) => i * i => bool) [inductify] converse .
   986 
   987 thm converse.equation
   988 code_pred [inductify] rel_comp .
   989 thm rel_comp.equation
   990 code_pred [inductify] Image .
   991 thm Image.equation
   992 declare singleton_iff[code_pred_inline]
   993 declare Id_on_def[unfolded Bex_def UNION_def singleton_iff, code_pred_def]
   994 
   995 code_pred (expected_modes:
   996   (o => bool) => o => bool,
   997   (o => bool) => i * o => bool,
   998   (o => bool) => o * i => bool,
   999   (o => bool) => i => bool,
  1000   (i => bool) => i * o => bool,
  1001   (i => bool) => o * i => bool,
  1002   (i => bool) => i => bool) [inductify] Id_on .
  1003 thm Id_on.equation
  1004 thm Domain_def
  1005 code_pred (modes:
  1006   (o * o => bool) => o => bool,
  1007   (o * o => bool) => i => bool,
  1008   (i * o => bool) => i => bool) [inductify] Domain .
  1009 thm Domain.equation
  1010 
  1011 thm Range_def
  1012 code_pred (modes:
  1013   (o * o => bool) => o => bool,
  1014   (o * o => bool) => i => bool,
  1015   (o * i => bool) => i => bool) [inductify] Range .
  1016 thm Range.equation
  1017 
  1018 code_pred [inductify] Field .
  1019 thm Field.equation
  1020 
  1021 thm refl_on_def
  1022 code_pred [inductify] refl_on .
  1023 thm refl_on.equation
  1024 code_pred [inductify] total_on .
  1025 thm total_on.equation
  1026 code_pred [inductify] antisym .
  1027 thm antisym.equation
  1028 code_pred [inductify] trans .
  1029 thm trans.equation
  1030 code_pred [inductify] single_valued .
  1031 thm single_valued.equation
  1032 thm inv_image_def
  1033 code_pred [inductify] inv_image .
  1034 thm inv_image.equation
  1035 
  1036 subsection {* Inverting list functions *}
  1037 
  1038 code_pred [inductify] size_list .
  1039 code_pred [new_random_dseq inductify] size_list .
  1040 thm size_listP.equation
  1041 thm size_listP.new_random_dseq_equation
  1042 
  1043 values [new_random_dseq 2,3,10] 3 "{xs. size_listP (xs::nat list) (5::nat)}"
  1044 
  1045 code_pred (expected_modes: i => o => bool, o => i => bool, i => i => bool) [inductify, skip_proof] List.concat .
  1046 thm concatP.equation
  1047 
  1048 values "{ys. concatP [[1, 2], [3, (4::int)]] ys}"
  1049 values "{ys. concatP [[1, 2], [3]] [1, 2, (3::nat)]}"
  1050 
  1051 code_pred [dseq inductify] List.concat .
  1052 thm concatP.dseq_equation
  1053 
  1054 values [dseq 3] 3
  1055   "{xs. concatP xs ([0] :: nat list)}"
  1056 
  1057 values [dseq 5] 3
  1058   "{xs. concatP xs ([1] :: int list)}"
  1059 
  1060 values [dseq 5] 3
  1061   "{xs. concatP xs ([1] :: nat list)}"
  1062 
  1063 values [dseq 5] 3
  1064   "{xs. concatP xs [(1::int), 2]}"
  1065 
  1066 code_pred (expected_modes: i => o => bool, i => i => bool) [inductify] hd .
  1067 thm hdP.equation
  1068 values "{x. hdP [1, 2, (3::int)] x}"
  1069 values "{(xs, x). hdP [1, 2, (3::int)] 1}"
  1070  
  1071 code_pred (expected_modes: i => o => bool, i => i => bool) [inductify] tl .
  1072 thm tlP.equation
  1073 values "{x. tlP [1, 2, (3::nat)] x}"
  1074 values "{x. tlP [1, 2, (3::int)] [3]}"
  1075 
  1076 code_pred [inductify, skip_proof] last .
  1077 thm lastP.equation
  1078 
  1079 code_pred [inductify, skip_proof] butlast .
  1080 thm butlastP.equation
  1081 
  1082 code_pred [inductify, skip_proof] take .
  1083 thm takeP.equation
  1084 
  1085 code_pred [inductify, skip_proof] drop .
  1086 thm dropP.equation
  1087 code_pred [inductify, skip_proof] zip .
  1088 thm zipP.equation
  1089 
  1090 code_pred [inductify, skip_proof] upt .
  1091 code_pred [inductify, skip_proof] remdups .
  1092 thm remdupsP.equation
  1093 code_pred [dseq inductify] remdups .
  1094 values [dseq 4] 5 "{xs. remdupsP xs [1, (2::int)]}"
  1095 
  1096 code_pred [inductify, skip_proof] remove1 .
  1097 thm remove1P.equation
  1098 values "{xs. remove1P 1 xs [2, (3::int)]}"
  1099 
  1100 code_pred [inductify, skip_proof] removeAll .
  1101 thm removeAllP.equation
  1102 code_pred [dseq inductify] removeAll .
  1103 
  1104 values [dseq 4] 10 "{xs. removeAllP 1 xs [(2::nat)]}"
  1105 
  1106 code_pred [inductify] distinct .
  1107 thm distinct.equation
  1108 code_pred [inductify, skip_proof] replicate .
  1109 thm replicateP.equation
  1110 values 5 "{(n, xs). replicateP n (0::int) xs}"
  1111 
  1112 code_pred [inductify, skip_proof] splice .
  1113 thm splice.simps
  1114 thm spliceP.equation
  1115 
  1116 values "{xs. spliceP xs [1, 2, 3] [1, 1, 1, 2, 1, (3::nat)]}"
  1117 
  1118 code_pred [inductify, skip_proof] List.rev .
  1119 code_pred [inductify] map .
  1120 code_pred [inductify] foldr .
  1121 code_pred [inductify] foldl .
  1122 code_pred [inductify] filter .
  1123 code_pred [random_dseq inductify] filter .
  1124 
  1125 subsection {* Context Free Grammar *}
  1126 
  1127 datatype alphabet = a | b
  1128 
  1129 inductive_set S\<^isub>1 and A\<^isub>1 and B\<^isub>1 where
  1130   "[] \<in> S\<^isub>1"
  1131 | "w \<in> A\<^isub>1 \<Longrightarrow> b # w \<in> S\<^isub>1"
  1132 | "w \<in> B\<^isub>1 \<Longrightarrow> a # w \<in> S\<^isub>1"
  1133 | "w \<in> S\<^isub>1 \<Longrightarrow> a # w \<in> A\<^isub>1"
  1134 | "w \<in> S\<^isub>1 \<Longrightarrow> b # w \<in> S\<^isub>1"
  1135 | "\<lbrakk>v \<in> B\<^isub>1; v \<in> B\<^isub>1\<rbrakk> \<Longrightarrow> a # v @ w \<in> B\<^isub>1"
  1136 
  1137 code_pred [inductify] S\<^isub>1p .
  1138 code_pred [random_dseq inductify] S\<^isub>1p .
  1139 thm S\<^isub>1p.equation
  1140 thm S\<^isub>1p.random_dseq_equation
  1141 
  1142 values [random_dseq 5, 5, 5] 5 "{x. S\<^isub>1p x}"
  1143 
  1144 inductive_set S\<^isub>2 and A\<^isub>2 and B\<^isub>2 where
  1145   "[] \<in> S\<^isub>2"
  1146 | "w \<in> A\<^isub>2 \<Longrightarrow> b # w \<in> S\<^isub>2"
  1147 | "w \<in> B\<^isub>2 \<Longrightarrow> a # w \<in> S\<^isub>2"
  1148 | "w \<in> S\<^isub>2 \<Longrightarrow> a # w \<in> A\<^isub>2"
  1149 | "w \<in> S\<^isub>2 \<Longrightarrow> b # w \<in> B\<^isub>2"
  1150 | "\<lbrakk>v \<in> B\<^isub>2; v \<in> B\<^isub>2\<rbrakk> \<Longrightarrow> a # v @ w \<in> B\<^isub>2"
  1151 
  1152 code_pred [random_dseq inductify] S\<^isub>2p .
  1153 thm S\<^isub>2p.random_dseq_equation
  1154 thm A\<^isub>2p.random_dseq_equation
  1155 thm B\<^isub>2p.random_dseq_equation
  1156 
  1157 values [random_dseq 5, 5, 5] 10 "{x. S\<^isub>2p x}"
  1158 
  1159 inductive_set S\<^isub>3 and A\<^isub>3 and B\<^isub>3 where
  1160   "[] \<in> S\<^isub>3"
  1161 | "w \<in> A\<^isub>3 \<Longrightarrow> b # w \<in> S\<^isub>3"
  1162 | "w \<in> B\<^isub>3 \<Longrightarrow> a # w \<in> S\<^isub>3"
  1163 | "w \<in> S\<^isub>3 \<Longrightarrow> a # w \<in> A\<^isub>3"
  1164 | "w \<in> S\<^isub>3 \<Longrightarrow> b # w \<in> B\<^isub>3"
  1165 | "\<lbrakk>v \<in> B\<^isub>3; w \<in> B\<^isub>3\<rbrakk> \<Longrightarrow> a # v @ w \<in> B\<^isub>3"
  1166 
  1167 code_pred [inductify, skip_proof] S\<^isub>3p .
  1168 thm S\<^isub>3p.equation
  1169 
  1170 values 10 "{x. S\<^isub>3p x}"
  1171 
  1172 inductive_set S\<^isub>4 and A\<^isub>4 and B\<^isub>4 where
  1173   "[] \<in> S\<^isub>4"
  1174 | "w \<in> A\<^isub>4 \<Longrightarrow> b # w \<in> S\<^isub>4"
  1175 | "w \<in> B\<^isub>4 \<Longrightarrow> a # w \<in> S\<^isub>4"
  1176 | "w \<in> S\<^isub>4 \<Longrightarrow> a # w \<in> A\<^isub>4"
  1177 | "\<lbrakk>v \<in> A\<^isub>4; w \<in> A\<^isub>4\<rbrakk> \<Longrightarrow> b # v @ w \<in> A\<^isub>4"
  1178 | "w \<in> S\<^isub>4 \<Longrightarrow> b # w \<in> B\<^isub>4"
  1179 | "\<lbrakk>v \<in> B\<^isub>4; w \<in> B\<^isub>4\<rbrakk> \<Longrightarrow> a # v @ w \<in> B\<^isub>4"
  1180 
  1181 code_pred (expected_modes: o => bool, i => bool) S\<^isub>4p .
  1182 
  1183 hide_const a b
  1184 
  1185 subsection {* Lambda *}
  1186 
  1187 datatype type =
  1188     Atom nat
  1189   | Fun type type    (infixr "\<Rightarrow>" 200)
  1190 
  1191 datatype dB =
  1192     Var nat
  1193   | App dB dB (infixl "\<degree>" 200)
  1194   | Abs type dB
  1195 
  1196 primrec
  1197   nth_el :: "'a list \<Rightarrow> nat \<Rightarrow> 'a option" ("_\<langle>_\<rangle>" [90, 0] 91)
  1198 where
  1199   "[]\<langle>i\<rangle> = None"
  1200 | "(x # xs)\<langle>i\<rangle> = (case i of 0 \<Rightarrow> Some x | Suc j \<Rightarrow> xs \<langle>j\<rangle>)"
  1201 
  1202 inductive nth_el' :: "'a list \<Rightarrow> nat \<Rightarrow> 'a \<Rightarrow> bool"
  1203 where
  1204   "nth_el' (x # xs) 0 x"
  1205 | "nth_el' xs i y \<Longrightarrow> nth_el' (x # xs) (Suc i) y"
  1206 
  1207 inductive typing :: "type list \<Rightarrow> dB \<Rightarrow> type \<Rightarrow> bool"  ("_ \<turnstile> _ : _" [50, 50, 50] 50)
  1208   where
  1209     Var [intro!]: "nth_el' env x T \<Longrightarrow> env \<turnstile> Var x : T"
  1210   | Abs [intro!]: "T # env \<turnstile> t : U \<Longrightarrow> env \<turnstile> Abs T t : (T \<Rightarrow> U)"
  1211   | App [intro!]: "env \<turnstile> s : T \<Rightarrow> U \<Longrightarrow> env \<turnstile> t : T \<Longrightarrow> env \<turnstile> (s \<degree> t) : U"
  1212 
  1213 primrec
  1214   lift :: "[dB, nat] => dB"
  1215 where
  1216     "lift (Var i) k = (if i < k then Var i else Var (i + 1))"
  1217   | "lift (s \<degree> t) k = lift s k \<degree> lift t k"
  1218   | "lift (Abs T s) k = Abs T (lift s (k + 1))"
  1219 
  1220 primrec
  1221   subst :: "[dB, dB, nat] => dB"  ("_[_'/_]" [300, 0, 0] 300)
  1222 where
  1223     subst_Var: "(Var i)[s/k] =
  1224       (if k < i then Var (i - 1) else if i = k then s else Var i)"
  1225   | subst_App: "(t \<degree> u)[s/k] = t[s/k] \<degree> u[s/k]"
  1226   | subst_Abs: "(Abs T t)[s/k] = Abs T (t[lift s 0 / k+1])"
  1227 
  1228 inductive beta :: "[dB, dB] => bool"  (infixl "\<rightarrow>\<^sub>\<beta>" 50)
  1229   where
  1230     beta [simp, intro!]: "Abs T s \<degree> t \<rightarrow>\<^sub>\<beta> s[t/0]"
  1231   | appL [simp, intro!]: "s \<rightarrow>\<^sub>\<beta> t ==> s \<degree> u \<rightarrow>\<^sub>\<beta> t \<degree> u"
  1232   | appR [simp, intro!]: "s \<rightarrow>\<^sub>\<beta> t ==> u \<degree> s \<rightarrow>\<^sub>\<beta> u \<degree> t"
  1233   | abs [simp, intro!]: "s \<rightarrow>\<^sub>\<beta> t ==> Abs T s \<rightarrow>\<^sub>\<beta> Abs T t"
  1234 
  1235 code_pred (expected_modes: i => i => o => bool, i => i => i => bool) typing .
  1236 thm typing.equation
  1237 
  1238 code_pred (modes: i => i => bool,  i => o => bool as reduce') beta .
  1239 thm beta.equation
  1240 
  1241 values "{x. App (Abs (Atom 0) (Var 0)) (Var 1) \<rightarrow>\<^sub>\<beta> x}"
  1242 
  1243 definition "reduce t = Predicate.the (reduce' t)"
  1244 
  1245 value "reduce (App (Abs (Atom 0) (Var 0)) (Var 1))"
  1246 
  1247 code_pred [dseq] typing .
  1248 code_pred [random_dseq] typing .
  1249 
  1250 values [random_dseq 1,1,5] 10 "{(\<Gamma>, t, T). \<Gamma> \<turnstile> t : T}"
  1251 
  1252 subsection {* A minimal example of yet another semantics *}
  1253 
  1254 text {* thanks to Elke Salecker *}
  1255 
  1256 types
  1257   vname = nat
  1258   vvalue = int
  1259   var_assign = "vname \<Rightarrow> vvalue"  --"variable assignment"
  1260 
  1261 datatype ir_expr = 
  1262   IrConst vvalue
  1263 | ObjAddr vname
  1264 | Add ir_expr ir_expr
  1265 
  1266 datatype val =
  1267   IntVal  vvalue
  1268 
  1269 record  configuration =
  1270   Env :: var_assign
  1271 
  1272 inductive eval_var ::
  1273   "ir_expr \<Rightarrow> configuration \<Rightarrow> val \<Rightarrow> bool"
  1274 where
  1275   irconst: "eval_var (IrConst i) conf (IntVal i)"
  1276 | objaddr: "\<lbrakk> Env conf n = i \<rbrakk> \<Longrightarrow> eval_var (ObjAddr n) conf (IntVal i)"
  1277 | plus: "\<lbrakk> eval_var l conf (IntVal vl); eval_var r conf (IntVal vr) \<rbrakk> \<Longrightarrow> eval_var (Add l r) conf (IntVal (vl+vr))"
  1278 
  1279 
  1280 code_pred eval_var .
  1281 thm eval_var.equation
  1282 
  1283 values "{val. eval_var (Add (IrConst 1) (IrConst 2)) (| Env = (\<lambda>x. 0)|) val}"
  1284 
  1285 section {* Function predicate replacement *}
  1286 
  1287 text {*
  1288 If the mode analysis uses the functional mode, we
  1289 replace predicates that resulted from functions again by their functions.
  1290 *}
  1291 
  1292 inductive test_append
  1293 where
  1294   "List.append xs ys = zs ==> test_append xs ys zs"
  1295 
  1296 code_pred [inductify, skip_proof] test_append .
  1297 thm test_append.equation
  1298 
  1299 text {* If append is not turned into a predicate, then the mode
  1300   o => o => i => bool could not be inferred. *}
  1301 
  1302 values 4 "{(xs::int list, ys). test_append xs ys [1, 2, 3, 4]}"
  1303 
  1304 text {* If appendP is not reverted back to a function, then mode i => i => o => bool
  1305   fails after deleting the predicate equation. *}
  1306 
  1307 declare appendP.equation[code del]
  1308 
  1309 values "{xs::int list. test_append [1,2] [3,4] xs}"
  1310 values "{xs::int list. test_append (replicate 1000 1) (replicate 1000 2) xs}"
  1311 values "{xs::int list. test_append (replicate 2000 1) (replicate 2000 2) xs}"
  1312 
  1313 subsection {* Function with tuples *}
  1314 
  1315 fun append'
  1316 where
  1317   "append' ([], ys) = ys"
  1318 | "append' (x # xs, ys) = x # append' (xs, ys)"
  1319 
  1320 inductive test_append'
  1321 where
  1322   "append' (xs, ys) = zs ==> test_append' xs ys zs"
  1323 
  1324 code_pred [inductify, skip_proof] test_append' .
  1325 
  1326 thm test_append'.equation
  1327 
  1328 values "{(xs::int list, ys). test_append' xs ys [1, 2, 3, 4]}"
  1329 
  1330 declare append'P.equation[code del]
  1331 
  1332 values "{zs :: int list. test_append' [1,2,3] [4,5] zs}"
  1333 
  1334 section {* Arithmetic examples *}
  1335 
  1336 subsection {* Examples on nat *}
  1337 
  1338 inductive plus_nat_test :: "nat => nat => nat => bool"
  1339 where
  1340   "x + y = z ==> plus_nat_test x y z"
  1341 
  1342 code_pred [inductify, skip_proof] plus_nat_test .
  1343 code_pred [new_random_dseq inductify] plus_nat_test .
  1344 
  1345 thm plus_nat_test.equation
  1346 thm plus_nat_test.new_random_dseq_equation
  1347 
  1348 values [expected "{9::nat}"] "{z. plus_nat_test 4 5 z}"
  1349 values [expected "{9::nat}"] "{z. plus_nat_test 7 2 z}"
  1350 values [expected "{4::nat}"] "{y. plus_nat_test 5 y 9}"
  1351 values [expected "{}"] "{y. plus_nat_test 9 y 8}"
  1352 values [expected "{6::nat}"] "{y. plus_nat_test 1 y 7}"
  1353 values [expected "{2::nat}"] "{x. plus_nat_test x 7 9}"
  1354 values [expected "{}"] "{x. plus_nat_test x 9 7}"
  1355 values [expected "{(0::nat,0::nat)}"] "{(x, y). plus_nat_test x y 0}"
  1356 values [expected "{(0, Suc 0), (Suc 0, 0)}"] "{(x, y). plus_nat_test x y 1}"
  1357 values [expected "{(0, 5), (4, Suc 0), (3, 2), (2, 3), (Suc 0, 4), (5, 0)}"]
  1358   "{(x, y). plus_nat_test x y 5}"
  1359 
  1360 inductive minus_nat_test :: "nat => nat => nat => bool"
  1361 where
  1362   "x - y = z ==> minus_nat_test x y z"
  1363 
  1364 code_pred [inductify, skip_proof] minus_nat_test .
  1365 code_pred [new_random_dseq inductify] minus_nat_test .
  1366 
  1367 thm minus_nat_test.equation
  1368 thm minus_nat_test.new_random_dseq_equation
  1369 
  1370 values [expected "{0::nat}"] "{z. minus_nat_test 4 5 z}"
  1371 values [expected "{5::nat}"] "{z. minus_nat_test 7 2 z}"
  1372 values [expected "{16::nat}"] "{x. minus_nat_test x 7 9}"
  1373 values [expected "{16::nat}"] "{x. minus_nat_test x 9 7}"
  1374 values [expected "{0, Suc 0, 2, 3}"] "{x. minus_nat_test x 3 0}"
  1375 values [expected "{0::nat}"] "{x. minus_nat_test x 0 0}"
  1376 
  1377 subsection {* Examples on int *}
  1378 
  1379 inductive plus_int_test :: "int => int => int => bool"
  1380 where
  1381   "a + b = c ==> plus_int_test a b c"
  1382 
  1383 code_pred [inductify, skip_proof] plus_int_test .
  1384 code_pred [new_random_dseq inductify] plus_int_test .
  1385 
  1386 thm plus_int_test.equation
  1387 thm plus_int_test.new_random_dseq_equation
  1388 
  1389 values [expected "{1::int}"] "{a. plus_int_test a 6 7}"
  1390 values [expected "{1::int}"] "{b. plus_int_test 6 b 7}"
  1391 values [expected "{11::int}"] "{c. plus_int_test 5 6 c}"
  1392 
  1393 inductive minus_int_test :: "int => int => int => bool"
  1394 where
  1395   "a - b = c ==> minus_int_test a b c"
  1396 
  1397 code_pred [inductify, skip_proof] minus_int_test .
  1398 code_pred [new_random_dseq inductify] minus_int_test .
  1399 
  1400 thm minus_int_test.equation
  1401 thm minus_int_test.new_random_dseq_equation
  1402 
  1403 values [expected "{4::int}"] "{c. minus_int_test 9 5 c}"
  1404 values [expected "{9::int}"] "{a. minus_int_test a 4 5}"
  1405 values [expected "{- 1::int}"] "{b. minus_int_test 4 b 5}"
  1406 
  1407 subsection {* minus on bool *}
  1408 
  1409 inductive All :: "nat => bool"
  1410 where
  1411   "All x"
  1412 
  1413 inductive None :: "nat => bool"
  1414 
  1415 definition "test_minus_bool x = (None x - All x)"
  1416 
  1417 code_pred [inductify] test_minus_bool .
  1418 thm test_minus_bool.equation
  1419 
  1420 values "{x. test_minus_bool x}"
  1421 
  1422 subsection {* Functions *}
  1423 
  1424 fun partial_hd :: "'a list => 'a option"
  1425 where
  1426   "partial_hd [] = Option.None"
  1427 | "partial_hd (x # xs) = Some x"
  1428 
  1429 inductive hd_predicate
  1430 where
  1431   "partial_hd xs = Some x ==> hd_predicate xs x"
  1432 
  1433 code_pred (expected_modes: i => i => bool, i => o => bool) hd_predicate .
  1434 
  1435 thm hd_predicate.equation
  1436 
  1437 subsection {* Locales *}
  1438 
  1439 inductive hd_predicate2 :: "('a list => 'a option) => 'a list => 'a => bool"
  1440 where
  1441   "partial_hd' xs = Some x ==> hd_predicate2 partial_hd' xs x"
  1442 
  1443 
  1444 thm hd_predicate2.intros
  1445 
  1446 code_pred (expected_modes: i => i => i => bool, i => i => o => bool) hd_predicate2 .
  1447 thm hd_predicate2.equation
  1448 
  1449 locale A = fixes partial_hd :: "'a list => 'a option" begin
  1450 
  1451 inductive hd_predicate_in_locale :: "'a list => 'a => bool"
  1452 where
  1453   "partial_hd xs = Some x ==> hd_predicate_in_locale xs x"
  1454 
  1455 end
  1456 
  1457 text {* The global introduction rules must be redeclared as introduction rules and then 
  1458   one could invoke code_pred. *}
  1459 
  1460 declare A.hd_predicate_in_locale.intros [unfolded Predicate.eq_is_eq[symmetric], code_pred_intro]
  1461 
  1462 code_pred (expected_modes: i => i => i => bool, i => i => o => bool) A.hd_predicate_in_locale
  1463 unfolding eq_is_eq by (auto elim: A.hd_predicate_in_locale.cases)
  1464     
  1465 interpretation A partial_hd .
  1466 thm hd_predicate_in_locale.intros
  1467 text {* A locally compliant solution with a trivial interpretation fails, because
  1468 the predicate compiler has very strict assumptions about the terms and their structure. *}
  1469  
  1470 (*code_pred hd_predicate_in_locale .*)
  1471 
  1472 section {* Integer example *}
  1473 
  1474 definition three :: int
  1475 where "three = 3"
  1476 
  1477 inductive is_three
  1478 where
  1479   "is_three three"
  1480 
  1481 code_pred is_three .
  1482 
  1483 thm is_three.equation
  1484 
  1485 section {* String.literal example *}
  1486 
  1487 definition Error_1
  1488 where
  1489   "Error_1 = STR ''Error 1''"
  1490 
  1491 definition Error_2
  1492 where
  1493   "Error_2 = STR ''Error 2''"
  1494 
  1495 inductive "is_error" :: "String.literal \<Rightarrow> bool"
  1496 where
  1497   "is_error Error_1"
  1498 | "is_error Error_2"
  1499 
  1500 code_pred is_error .
  1501 
  1502 thm is_error.equation
  1503 
  1504 inductive is_error' :: "String.literal \<Rightarrow> bool"
  1505 where
  1506   "is_error' (STR ''Error1'')"
  1507 | "is_error' (STR ''Error2'')"
  1508 
  1509 code_pred is_error' .
  1510 
  1511 thm is_error'.equation
  1512 
  1513 datatype ErrorObject = Error String.literal int
  1514 
  1515 inductive is_error'' :: "ErrorObject \<Rightarrow> bool"
  1516 where
  1517   "is_error'' (Error Error_1 3)"
  1518 | "is_error'' (Error Error_2 4)"
  1519 
  1520 code_pred is_error'' .
  1521 
  1522 thm is_error''.equation
  1523 
  1524 section {* Another function example *}
  1525 
  1526 consts f :: "'a \<Rightarrow> 'a"
  1527 
  1528 inductive fun_upd :: "(('a * 'b) * ('a \<Rightarrow> 'b)) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool"
  1529 where
  1530   "fun_upd ((x, a), s) (s(x := f a))"
  1531 
  1532 code_pred fun_upd .
  1533 
  1534 thm fun_upd.equation
  1535 
  1536 section {* Another semantics *}
  1537 
  1538 types
  1539   name = nat --"For simplicity in examples"
  1540   state' = "name \<Rightarrow> nat"
  1541 
  1542 datatype aexp = N nat | V name | Plus aexp aexp
  1543 
  1544 fun aval :: "aexp \<Rightarrow> state' \<Rightarrow> nat" where
  1545 "aval (N n) _ = n" |
  1546 "aval (V x) st = st x" |
  1547 "aval (Plus e\<^isub>1 e\<^isub>2) st = aval e\<^isub>1 st + aval e\<^isub>2 st"
  1548 
  1549 datatype bexp = B bool | Not bexp | And bexp bexp | Less aexp aexp
  1550 
  1551 primrec bval :: "bexp \<Rightarrow> state' \<Rightarrow> bool" where
  1552 "bval (B b) _ = b" |
  1553 "bval (Not b) st = (\<not> bval b st)" |
  1554 "bval (And b1 b2) st = (bval b1 st \<and> bval b2 st)" |
  1555 "bval (Less a\<^isub>1 a\<^isub>2) st = (aval a\<^isub>1 st < aval a\<^isub>2 st)"
  1556 
  1557 datatype
  1558   com' = SKIP 
  1559       | Assign name aexp         ("_ ::= _" [1000, 61] 61)
  1560       | Semi   com'  com'          ("_; _"  [60, 61] 60)
  1561       | If     bexp com' com'     ("IF _ THEN _ ELSE _"  [0, 0, 61] 61)
  1562       | While  bexp com'         ("WHILE _ DO _"  [0, 61] 61)
  1563 
  1564 inductive
  1565   big_step :: "com' * state' \<Rightarrow> state' \<Rightarrow> bool" (infix "\<Rightarrow>" 55)
  1566 where
  1567   Skip:    "(SKIP,s) \<Rightarrow> s"
  1568 | Assign:  "(x ::= a,s) \<Rightarrow> s(x := aval a s)"
  1569 
  1570 | Semi:    "(c\<^isub>1,s\<^isub>1) \<Rightarrow> s\<^isub>2  \<Longrightarrow>  (c\<^isub>2,s\<^isub>2) \<Rightarrow> s\<^isub>3  \<Longrightarrow> (c\<^isub>1;c\<^isub>2, s\<^isub>1) \<Rightarrow> s\<^isub>3"
  1571 
  1572 | IfTrue:  "bval b s  \<Longrightarrow>  (c\<^isub>1,s) \<Rightarrow> t  \<Longrightarrow>  (IF b THEN c\<^isub>1 ELSE c\<^isub>2, s) \<Rightarrow> t"
  1573 | IfFalse: "\<not>bval b s  \<Longrightarrow>  (c\<^isub>2,s) \<Rightarrow> t  \<Longrightarrow>  (IF b THEN c\<^isub>1 ELSE c\<^isub>2, s) \<Rightarrow> t"
  1574 
  1575 | WhileFalse: "\<not>bval b s \<Longrightarrow> (WHILE b DO c,s) \<Rightarrow> s"
  1576 | WhileTrue:  "bval b s\<^isub>1  \<Longrightarrow>  (c,s\<^isub>1) \<Rightarrow> s\<^isub>2  \<Longrightarrow>  (WHILE b DO c, s\<^isub>2) \<Rightarrow> s\<^isub>3
  1577                \<Longrightarrow> (WHILE b DO c, s\<^isub>1) \<Rightarrow> s\<^isub>3"
  1578 
  1579 code_pred big_step .
  1580 
  1581 thm big_step.equation
  1582 
  1583 section {* Examples for detecting switches *}
  1584 
  1585 inductive detect_switches1 where
  1586   "detect_switches1 [] []"
  1587 | "detect_switches1 (x # xs) (y # ys)"
  1588 
  1589 code_pred [detect_switches, skip_proof] detect_switches1 .
  1590 
  1591 thm detect_switches1.equation
  1592 
  1593 inductive detect_switches2 :: "('a => bool) => bool"
  1594 where
  1595   "detect_switches2 P"
  1596 
  1597 code_pred [detect_switches, skip_proof] detect_switches2 .
  1598 thm detect_switches2.equation
  1599 
  1600 inductive detect_switches3 :: "('a => bool) => 'a list => bool"
  1601 where
  1602   "detect_switches3 P []"
  1603 | "detect_switches3 P (x # xs)" 
  1604 
  1605 code_pred [detect_switches, skip_proof] detect_switches3 .
  1606 
  1607 thm detect_switches3.equation
  1608 
  1609 inductive detect_switches4 :: "('a => bool) => 'a list => 'a list => bool"
  1610 where
  1611   "detect_switches4 P [] []"
  1612 | "detect_switches4 P (x # xs) (y # ys)"
  1613 
  1614 code_pred [detect_switches, skip_proof] detect_switches4 .
  1615 thm detect_switches4.equation
  1616 
  1617 inductive detect_switches5 :: "('a => 'a => bool) => 'a list => 'a list => bool"
  1618 where
  1619   "detect_switches5 P [] []"
  1620 | "detect_switches5 P xs ys ==> P x y ==> detect_switches5 P (x # xs) (y # ys)"
  1621 
  1622 code_pred [detect_switches, skip_proof] detect_switches5 .
  1623 
  1624 thm detect_switches5.equation
  1625 
  1626 inductive detect_switches6 :: "(('a => 'b => bool) * 'a list * 'b list) => bool"
  1627 where
  1628   "detect_switches6 (P, [], [])"
  1629 | "detect_switches6 (P, xs, ys) ==> P x y ==> detect_switches6 (P, x # xs, y # ys)"
  1630 
  1631 code_pred [detect_switches, skip_proof] detect_switches6 .
  1632 
  1633 inductive detect_switches7 :: "('a => bool) => ('b => bool) => ('a * 'b list) => bool"
  1634 where
  1635   "detect_switches7 P Q (a, [])"
  1636 | "P a ==> Q x ==> detect_switches7 P Q (a, x#xs)"
  1637 
  1638 code_pred [skip_proof] detect_switches7 .
  1639 
  1640 thm detect_switches7.equation
  1641 
  1642 inductive detect_switches8 :: "nat => bool"
  1643 where
  1644   "detect_switches8 0"
  1645 | "x mod 2 = 0 ==> detect_switches8 (Suc x)"
  1646 
  1647 code_pred [detect_switches, skip_proof] detect_switches8 .
  1648 
  1649 thm detect_switches8.equation
  1650 
  1651 inductive detect_switches9 :: "nat => nat => bool"
  1652 where
  1653   "detect_switches9 0 0"
  1654 | "detect_switches9 0 (Suc x)"
  1655 | "detect_switches9 (Suc x) 0"
  1656 | "x = y ==> detect_switches9 (Suc x) (Suc y)"
  1657 | "c1 = c2 ==> detect_switches9 c1 c2"
  1658 
  1659 code_pred [detect_switches, skip_proof] detect_switches9 .
  1660 
  1661 thm detect_switches9.equation
  1662 
  1663 
  1664 
  1665 end