src/HOL/ex/Rewrite_Examples.thy
changeset 59739 4ed50ebf5d36
child 60047 58e5b16cbd94
equal deleted inserted replaced
59734:f41a2f77ab1b 59739:4ed50ebf5d36
       
     1 theory Rewrite_Examples
       
     2 imports Main "~~/src/HOL/Library/Rewrite"
       
     3 begin
       
     4 
       
     5 section \<open>The rewrite Proof Method by Example\<close>
       
     6 
       
     7 (* This file is intended to give an overview over
       
     8    the features of the pattern-based rewrite proof method.
       
     9 
       
    10    See also https://www21.in.tum.de/~noschinl/Pattern-2014/
       
    11 *)
       
    12 
       
    13 lemma
       
    14   fixes a::int and b::int and c::int
       
    15   assumes "P (b + a)"
       
    16   shows "P (a + b)"
       
    17 by (rewrite at "a + b" add.commute)
       
    18    (rule assms)
       
    19 
       
    20 (* Selecting a specific subterm in a large, ambiguous term. *)
       
    21 lemma
       
    22   fixes a b c :: int
       
    23   assumes "f (a - a + (a - a)) + f (   0    + c) = f 0 + f c"
       
    24   shows   "f (a - a + (a - a)) + f ((a - a) + c) = f 0 + f c"
       
    25   by (rewrite in "f _ + f \<box> = _" diff_self) fact
       
    26 
       
    27 lemma
       
    28   fixes a b c :: int
       
    29   assumes "f (a - a +    0   ) + f ((a - a) + c) = f 0 + f c"
       
    30   shows   "f (a - a + (a - a)) + f ((a - a) + c) = f 0 + f c"
       
    31   by (rewrite at "f (_ + \<box>) + f _ = _" diff_self) fact
       
    32 
       
    33 lemma
       
    34   fixes a b c :: int
       
    35   assumes "f (  0   + (a - a)) + f ((a - a) + c) = f 0 + f c"
       
    36   shows   "f (a - a + (a - a)) + f ((a - a) + c) = f 0 + f c"
       
    37   by (rewrite in "f (\<box> + _) + _ = _" diff_self) fact
       
    38 
       
    39 lemma
       
    40   fixes a b c :: int
       
    41   assumes "f (a - a +    0   ) + f ((a - a) + c) = f 0 + f c"
       
    42   shows   "f (a - a + (a - a)) + f ((a - a) + c) = f 0 + f c"
       
    43   by (rewrite in "f (_ + \<box>) + _ = _" diff_self) fact
       
    44 
       
    45 lemma
       
    46   fixes x y :: nat
       
    47   shows"x + y > c \<Longrightarrow> y + x > c"
       
    48   by (rewrite at "\<box> > c" add.commute) assumption
       
    49 
       
    50 (* We can also rewrite in the assumptions.  *)
       
    51 lemma
       
    52   fixes x y :: nat
       
    53   assumes "y + x > c \<Longrightarrow> y + x > c"
       
    54   shows   "x + y > c \<Longrightarrow> y + x > c"
       
    55   by (rewrite in asm add.commute) fact
       
    56 
       
    57 lemma
       
    58   fixes x y :: nat
       
    59   assumes "y + x > c \<Longrightarrow> y + x > c"
       
    60   shows   "x + y > c \<Longrightarrow> y + x > c"
       
    61   by (rewrite in "x + y > c" at asm add.commute) fact
       
    62 
       
    63 lemma
       
    64   fixes x y :: nat
       
    65   assumes "y + x > c \<Longrightarrow> y + x > c"
       
    66   shows   "x + y > c \<Longrightarrow> y + x > c"
       
    67   by (rewrite at "\<box> > c" at asm  add.commute) fact
       
    68 
       
    69 lemma
       
    70   assumes "P {x::int. y + 1 = 1 + x}"
       
    71   shows   "P {x::int. y + 1 = x + 1}"
       
    72   by (rewrite at "x+1" in "{x::int. \<box> }" add.commute) fact
       
    73 
       
    74 lemma
       
    75   assumes "P {x::int. y + 1 = 1 + x}"
       
    76   shows   "P {x::int. y + 1 = x + 1}"
       
    77   by (rewrite at "any_identifier_will_work+1" in "{any_identifier_will_work::int. \<box> }" add.commute)
       
    78    fact
       
    79 
       
    80 lemma
       
    81   assumes "P {(x::nat, y::nat, z). x + z * 3 = Q (\<lambda>s t. s * t + y - 3)}"
       
    82   shows   "P {(x::nat, y::nat, z). x + z * 3 = Q (\<lambda>s t. y + s * t - 3)}"
       
    83   by (rewrite at "b + d * e" in "\<lambda>(a, b, c). _ = Q (\<lambda>d e. \<box>)" add.commute) fact
       
    84 
       
    85 
       
    86 (* Rewriting with conditional rewriting rules works just as well. *)
       
    87 lemma test_theorem:
       
    88   fixes x :: nat
       
    89   shows "x \<le> y \<Longrightarrow> x \<ge> y \<Longrightarrow> x = y"
       
    90   by (rule Orderings.order_antisym)
       
    91 
       
    92 lemma
       
    93 fixes f :: "nat \<Rightarrow> nat"
       
    94   assumes "f x \<le> 0" "f x \<ge> 0"
       
    95   shows "f x = 0"
       
    96   apply (rewrite at "f x" to "0" test_theorem)
       
    97   apply fact
       
    98   apply fact
       
    99   apply (rule refl)
       
   100 done
       
   101 
       
   102 (*
       
   103    Instantiation.
       
   104 
       
   105    Since all rewriting is now done via conversions,
       
   106    instantiation becomes fairly easy to do.
       
   107 *)
       
   108 
       
   109 (* We first introduce a function f and an extended
       
   110    version of f that is annotated with an invariant. *)
       
   111 fun f :: "nat \<Rightarrow> nat" where "f n = n"
       
   112 definition "f_inv (I :: nat \<Rightarrow> bool) n \<equiv> f n"
       
   113 
       
   114 lemma annotate_f: "f = f_inv I"
       
   115   by (simp add: f_inv_def fun_eq_iff)
       
   116 
       
   117 (* We have a lemma with a bound variable n, and
       
   118    want to add an invariant to f. *)
       
   119 lemma
       
   120   assumes "P (\<lambda>n. f_inv (\<lambda>_. True) n + 1) = x"
       
   121   shows "P (\<lambda>n. f n + 1) = x"
       
   122   by (rewrite to "f_inv (\<lambda>_. True)" annotate_f) fact
       
   123 
       
   124 (* We can also add an invariant that contains the variable n bound in the outer context.
       
   125    For this, we need to bind this variable to an identifier. *)
       
   126 lemma
       
   127   assumes "P (\<lambda>n. f_inv (\<lambda>x. n < x + 1) n + 1) = x"
       
   128   shows "P (\<lambda>n. f n + 1) = x"
       
   129   by (rewrite in "\<lambda>n. \<box>" to "f_inv (\<lambda>x. n < x + 1)" annotate_f) fact
       
   130 
       
   131 (* Any identifier will work *)
       
   132 lemma
       
   133   assumes "P (\<lambda>n. f_inv (\<lambda>x. n < x + 1) n + 1) = x"
       
   134   shows "P (\<lambda>n. f n + 1) = x"
       
   135   by (rewrite in "\<lambda>abc. \<box>" to "f_inv (\<lambda>x. abc < x + 1)" annotate_f) fact
       
   136 
       
   137 (* The "for" keyword. *)
       
   138 lemma
       
   139   assumes "P (2 + 1)"
       
   140   shows "\<And>x y. P (1 + 2 :: nat)"
       
   141 by (rewrite in "P (1 + 2)" at for (x) add.commute) fact
       
   142 
       
   143 lemma
       
   144   assumes "\<And>x y. P (y + x)"
       
   145   shows "\<And>x y. P (x + y :: nat)"
       
   146 by (rewrite in "P (x + _)" at for (x y) add.commute) fact
       
   147 
       
   148 lemma
       
   149   assumes "\<And>x y z. y + x + z = z + y + (x::int)"
       
   150   shows   "\<And>x y z. x + y + z = z + y + (x::int)"
       
   151 by (rewrite at "x + y" in "x + y + z" in concl at for (x y z) add.commute) fact
       
   152 
       
   153 lemma
       
   154   assumes "\<And>x y z. z + (x + y) = z + y + (x::int)"
       
   155   shows   "\<And>x y z. x + y + z = z + y + (x::int)"
       
   156 by (rewrite at "(_ + y) + z" in concl at for (y z) add.commute) fact
       
   157 
       
   158 lemma
       
   159   assumes "\<And>x y z. x + y + z = y + z + (x::int)"
       
   160   shows   "\<And>x y z. x + y + z = z + y + (x::int)"
       
   161 by (rewrite at "\<box> + _" at "_ = \<box>" in concl at for () add.commute) fact
       
   162 
       
   163 (* The all-keyword can be used anywhere in the pattern where there is an \<And>-Quantifier. *)
       
   164 lemma
       
   165   assumes "(\<And>(x::int). x < 1 + x)"
       
   166   and     "(x::int) + 1 > x"
       
   167   shows   "(\<And>(x::int). x + 1 > x) \<Longrightarrow> (x::int) + 1 > x"
       
   168 by (rewrite at "x + 1" in for (x) at asm add.commute)
       
   169    (rule assms)
       
   170 
       
   171 end
       
   172