blanchet@33197: (* Title: HOL/Nitpick_Examples/Manual_Nits.thy blanchet@33197: Author: Jasmin Blanchette, TU Muenchen blanchet@33197: Copyright 2009 blanchet@33197: blanchet@33197: Examples from the Nitpick manual. blanchet@33197: *) blanchet@33197: blanchet@33197: header {* Examples from the Nitpick Manual *} blanchet@33197: blanchet@33197: theory Manual_Nits blanchet@33197: imports Main Coinductive_List RealDef blanchet@33197: begin blanchet@33197: blanchet@33197: chapter {* 3. First Steps *} blanchet@33197: blanchet@33197: nitpick_params [sat_solver = MiniSatJNI, max_threads = 1] blanchet@33197: blanchet@33197: subsection {* 3.1. Propositional Logic *} blanchet@33197: blanchet@33197: lemma "P \ Q" blanchet@33197: nitpick blanchet@33197: apply auto blanchet@33197: nitpick 1 blanchet@33197: nitpick 2 blanchet@33197: oops blanchet@33197: blanchet@33197: subsection {* 3.2. Type Variables *} blanchet@33197: blanchet@33197: lemma "P x \ P (THE y. P y)" blanchet@33197: nitpick [verbose] blanchet@33197: oops blanchet@33197: blanchet@33197: subsection {* 3.3. Constants *} blanchet@33197: blanchet@33197: lemma "P x \ P (THE y. P y)" blanchet@33197: nitpick [show_consts] blanchet@33197: nitpick [full_descrs, show_consts] blanchet@33197: nitpick [dont_specialize, full_descrs, show_consts] blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "\!x. P x \ P (THE y. P y)" blanchet@33197: nitpick blanchet@33197: nitpick [card 'a = 1-50] blanchet@33197: (* sledgehammer *) blanchet@33197: apply (metis the_equality) blanchet@33197: done blanchet@33197: blanchet@33197: subsection {* 3.4. Skolemization *} blanchet@33197: blanchet@33197: lemma "\g. \x. g (f x) = x \ \y. \x. y = f x" blanchet@33197: nitpick blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "\x. \f. f x = x" blanchet@33197: nitpick blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "refl r \ sym r" blanchet@33197: nitpick blanchet@33197: oops blanchet@33197: blanchet@33197: subsection {* 3.5. Numbers *} blanchet@33197: blanchet@33197: lemma "\i \ j; n \ (m\int)\ \ i * n + j * m \ i * m + j * n" blanchet@33197: nitpick blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "\n. Suc n \ n \ P" blanchet@33197: nitpick [card nat = 100, check_potential] blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "P Suc" blanchet@33197: nitpick [card = 1-6] blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "P (op +\nat\nat\nat)" blanchet@33197: nitpick [card nat = 1] blanchet@33197: nitpick [card nat = 2] blanchet@33197: oops blanchet@33197: blanchet@33197: subsection {* 3.6. Inductive Datatypes *} blanchet@33197: blanchet@33197: lemma "hd (xs @ [y, y]) = hd xs" blanchet@33197: nitpick blanchet@33197: nitpick [show_consts, show_datatypes] blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "\length xs = 1; length ys = 1\ \ xs = ys" blanchet@33197: nitpick [show_datatypes] blanchet@33197: oops blanchet@33197: blanchet@33197: subsection {* 3.7. Typedefs, Records, Rationals, and Reals *} blanchet@33197: blanchet@33197: typedef three = "{0\nat, 1, 2}" blanchet@33197: by blast blanchet@33197: blanchet@33197: definition A :: three where "A \ Abs_three 0" blanchet@33197: definition B :: three where "B \ Abs_three 1" blanchet@33197: definition C :: three where "C \ Abs_three 2" blanchet@33197: blanchet@33197: lemma "\P A; P B\ \ P x" blanchet@33197: nitpick [show_datatypes] blanchet@33197: oops blanchet@33197: blanchet@33197: record point = blanchet@33197: Xcoord :: int blanchet@33197: Ycoord :: int blanchet@33197: blanchet@33197: lemma "Xcoord (p\point) = Xcoord (q\point)" blanchet@33197: nitpick [show_datatypes] blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "4 * x + 3 * (y\real) \ 1 / 2" blanchet@33197: nitpick [show_datatypes] blanchet@33197: oops blanchet@33197: blanchet@33197: subsection {* 3.8. Inductive and Coinductive Predicates *} blanchet@33197: blanchet@33197: inductive even where blanchet@33197: "even 0" | blanchet@33197: "even n \ even (Suc (Suc n))" blanchet@33197: blanchet@33197: lemma "\n. even n \ even (Suc n)" blanchet@33197: nitpick [card nat = 100, verbose] blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "\n \ 99. even n \ even (Suc n)" blanchet@33197: nitpick [card nat = 100] blanchet@33197: oops blanchet@33197: blanchet@33197: inductive even' where blanchet@33197: "even' (0\nat)" | blanchet@33197: "even' 2" | blanchet@33197: "\even' m; even' n\ \ even' (m + n)" blanchet@33197: blanchet@33197: lemma "\n \ {0, 2, 4, 6, 8}. \ even' n" blanchet@33197: nitpick [card nat = 10, verbose, show_consts] blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "even' (n - 2) \ even' n" blanchet@33197: nitpick [card nat = 10, show_consts] blanchet@33197: oops blanchet@33197: blanchet@33197: coinductive nats where blanchet@33197: "nats (x\nat) \ nats x" blanchet@33197: blanchet@33197: lemma "nats = {0, 1, 2, 3, 4}" blanchet@33197: nitpick [card nat = 10, show_consts] blanchet@33197: oops blanchet@33197: blanchet@33197: inductive odd where blanchet@33197: "odd 1" | blanchet@33197: "\odd m; even n\ \ odd (m + n)" blanchet@33197: blanchet@33197: lemma "odd n \ odd (n - 2)" blanchet@33197: nitpick [card nat = 10, show_consts] blanchet@33197: oops blanchet@33197: blanchet@33197: subsection {* 3.9. Coinductive Datatypes *} blanchet@33197: blanchet@33197: lemma "xs \ LCons a xs" blanchet@33197: nitpick blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "\xs = LCons a xs; ys = iterates (\b. a) b\ \ xs = ys" blanchet@33197: nitpick [verbose] blanchet@33197: nitpick [bisim_depth = -1, verbose] blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "\xs = LCons a xs; ys = LCons a ys\ \ xs = ys" blanchet@33197: nitpick [bisim_depth = -1, show_datatypes] blanchet@33197: nitpick blanchet@33197: sorry blanchet@33197: blanchet@33197: subsection {* 3.10. Boxing *} blanchet@33197: blanchet@33197: datatype tm = Var nat | Lam tm | App tm tm blanchet@33197: blanchet@33197: primrec lift where blanchet@33197: "lift (Var j) k = Var (if j < k then j else j + 1)" | blanchet@33197: "lift (Lam t) k = Lam (lift t (k + 1))" | blanchet@33197: "lift (App t u) k = App (lift t k) (lift u k)" blanchet@33197: blanchet@33197: primrec loose where blanchet@33197: "loose (Var j) k = (j \ k)" | blanchet@33197: "loose (Lam t) k = loose t (Suc k)" | blanchet@33197: "loose (App t u) k = (loose t k \ loose u k)" blanchet@33197: blanchet@33197: primrec subst\<^isub>1 where blanchet@33197: "subst\<^isub>1 \ (Var j) = \ j" | blanchet@33197: "subst\<^isub>1 \ (Lam t) = blanchet@33197: Lam (subst\<^isub>1 (\n. case n of 0 \ Var 0 | Suc m \ lift (\ m) 1) t)" | blanchet@33197: "subst\<^isub>1 \ (App t u) = App (subst\<^isub>1 \ t) (subst\<^isub>1 \ u)" blanchet@33197: blanchet@33197: lemma "\ loose t 0 \ subst\<^isub>1 \ t = t" blanchet@33197: nitpick [verbose] blanchet@33197: nitpick [eval = "subst\<^isub>1 \ t"] blanchet@33197: nitpick [dont_box] blanchet@33197: oops blanchet@33197: blanchet@33197: primrec subst\<^isub>2 where blanchet@33197: "subst\<^isub>2 \ (Var j) = \ j" | blanchet@33197: "subst\<^isub>2 \ (Lam t) = blanchet@33197: Lam (subst\<^isub>2 (\n. case n of 0 \ Var 0 | Suc m \ lift (\ m) 0) t)" | blanchet@33197: "subst\<^isub>2 \ (App t u) = App (subst\<^isub>2 \ t) (subst\<^isub>2 \ u)" blanchet@33197: blanchet@33197: lemma "\ loose t 0 \ subst\<^isub>2 \ t = t" blanchet@33197: nitpick blanchet@33197: sorry blanchet@33197: blanchet@33197: subsection {* 3.11. Scope Monotonicity *} blanchet@33197: blanchet@33197: lemma "length xs = length ys \ rev (zip xs ys) = zip xs (rev ys)" blanchet@33197: nitpick [verbose] blanchet@33197: nitpick [card = 8, verbose] blanchet@33197: oops blanchet@33197: blanchet@33197: lemma "\g. \x\'b. g (f x) = x \ \y\'a. \x. y = f x" blanchet@33197: nitpick [mono] blanchet@33197: nitpick blanchet@33197: oops blanchet@33197: blanchet@33197: section {* 4. Case Studies *} blanchet@33197: blanchet@33197: nitpick_params [max_potential = 0, max_threads = 2] blanchet@33197: blanchet@33197: subsection {* 4.1. A Context-Free Grammar *} blanchet@33197: blanchet@33197: datatype alphabet = a | b blanchet@33197: blanchet@33197: inductive_set S\<^isub>1 and A\<^isub>1 and B\<^isub>1 where blanchet@33197: "[] \ S\<^isub>1" blanchet@33197: | "w \ A\<^isub>1 \ b # w \ S\<^isub>1" blanchet@33197: | "w \ B\<^isub>1 \ a # w \ S\<^isub>1" blanchet@33197: | "w \ S\<^isub>1 \ a # w \ A\<^isub>1" blanchet@33197: | "w \ S\<^isub>1 \ b # w \ S\<^isub>1" blanchet@33197: | "\v \ B\<^isub>1; v \ B\<^isub>1\ \ a # v @ w \ B\<^isub>1" blanchet@33197: blanchet@33197: theorem S\<^isub>1_sound: blanchet@33197: "w \ S\<^isub>1 \ length [x \ w. x = a] = length [x \ w. x = b]" blanchet@33197: nitpick blanchet@33197: oops blanchet@33197: blanchet@33197: inductive_set S\<^isub>2 and A\<^isub>2 and B\<^isub>2 where blanchet@33197: "[] \ S\<^isub>2" blanchet@33197: | "w \ A\<^isub>2 \ b # w \ S\<^isub>2" blanchet@33197: | "w \ B\<^isub>2 \ a # w \ S\<^isub>2" blanchet@33197: | "w \ S\<^isub>2 \ a # w \ A\<^isub>2" blanchet@33197: | "w \ S\<^isub>2 \ b # w \ B\<^isub>2" blanchet@33197: | "\v \ B\<^isub>2; v \ B\<^isub>2\ \ a # v @ w \ B\<^isub>2" blanchet@33197: blanchet@33197: theorem S\<^isub>2_sound: blanchet@33197: "w \ S\<^isub>2 \ length [x \ w. x = a] = length [x \ w. x = b]" blanchet@33197: nitpick blanchet@33197: oops blanchet@33197: blanchet@33197: inductive_set S\<^isub>3 and A\<^isub>3 and B\<^isub>3 where blanchet@33197: "[] \ S\<^isub>3" blanchet@33197: | "w \ A\<^isub>3 \ b # w \ S\<^isub>3" blanchet@33197: | "w \ B\<^isub>3 \ a # w \ S\<^isub>3" blanchet@33197: | "w \ S\<^isub>3 \ a # w \ A\<^isub>3" blanchet@33197: | "w \ S\<^isub>3 \ b # w \ B\<^isub>3" blanchet@33197: | "\v \ B\<^isub>3; w \ B\<^isub>3\ \ a # v @ w \ B\<^isub>3" blanchet@33197: blanchet@33197: theorem S\<^isub>3_sound: blanchet@33197: "w \ S\<^isub>3 \ length [x \ w. x = a] = length [x \ w. x = b]" blanchet@33197: nitpick blanchet@33197: sorry blanchet@33197: blanchet@33197: theorem S\<^isub>3_complete: blanchet@33197: "length [x \ w. x = a] = length [x \ w. x = b] \ w \ S\<^isub>3" blanchet@33197: nitpick blanchet@33197: oops blanchet@33197: blanchet@33197: inductive_set S\<^isub>4 and A\<^isub>4 and B\<^isub>4 where blanchet@33197: "[] \ S\<^isub>4" blanchet@33197: | "w \ A\<^isub>4 \ b # w \ S\<^isub>4" blanchet@33197: | "w \ B\<^isub>4 \ a # w \ S\<^isub>4" blanchet@33197: | "w \ S\<^isub>4 \ a # w \ A\<^isub>4" blanchet@33197: | "\v \ A\<^isub>4; w \ A\<^isub>4\ \ b # v @ w \ A\<^isub>4" blanchet@33197: | "w \ S\<^isub>4 \ b # w \ B\<^isub>4" blanchet@33197: | "\v \ B\<^isub>4; w \ B\<^isub>4\ \ a # v @ w \ B\<^isub>4" blanchet@33197: blanchet@33197: theorem S\<^isub>4_sound: blanchet@33197: "w \ S\<^isub>4 \ length [x \ w. x = a] = length [x \ w. x = b]" blanchet@33197: nitpick blanchet@33197: sorry blanchet@33197: blanchet@33197: theorem S\<^isub>4_complete: blanchet@33197: "length [x \ w. x = a] = length [x \ w. x = b] \ w \ S\<^isub>4" blanchet@33197: nitpick blanchet@33197: sorry blanchet@33197: blanchet@33197: theorem S\<^isub>4_A\<^isub>4_B\<^isub>4_sound_and_complete: blanchet@33197: "w \ S\<^isub>4 \ length [x \ w. x = a] = length [x \ w. x = b]" blanchet@33197: "w \ A\<^isub>4 \ length [x \ w. x = a] = length [x \ w. x = b] + 1" blanchet@33197: "w \ B\<^isub>4 \ length [x \ w. x = b] = length [x \ w. x = a] + 1" blanchet@33197: nitpick blanchet@33197: sorry blanchet@33197: blanchet@33197: subsection {* 4.2. AA Trees *} blanchet@33197: blanchet@33197: datatype 'a tree = \ | N "'a\linorder" nat "'a tree" "'a tree" blanchet@33197: blanchet@33197: primrec data where blanchet@33197: "data \ = undefined" | blanchet@33197: "data (N x _ _ _) = x" blanchet@33197: blanchet@33197: primrec dataset where blanchet@33197: "dataset \ = {}" | blanchet@33197: "dataset (N x _ t u) = {x} \ dataset t \ dataset u" blanchet@33197: blanchet@33197: primrec level where blanchet@33197: "level \ = 0" | blanchet@33197: "level (N _ k _ _) = k" blanchet@33197: blanchet@33197: primrec left where blanchet@33197: "left \ = \" | blanchet@33197: "left (N _ _ t\<^isub>1 _) = t\<^isub>1" blanchet@33197: blanchet@33197: primrec right where blanchet@33197: "right \ = \" | blanchet@33197: "right (N _ _ _ t\<^isub>2) = t\<^isub>2" blanchet@33197: blanchet@33197: fun wf where blanchet@33197: "wf \ = True" | blanchet@33197: "wf (N _ k t u) = blanchet@33197: (if t = \ then blanchet@33197: k = 1 \ (u = \ \ (level u = 1 \ left u = \ \ right u = \)) blanchet@33197: else blanchet@33197: wf t \ wf u \ u \ \ \ level t < k \ level u \ k \ level (right u) < k)" blanchet@33197: blanchet@33197: fun skew where blanchet@33197: "skew \ = \" | blanchet@33197: "skew (N x k t u) = blanchet@33197: (if t \ \ \ k = level t then blanchet@33197: N (data t) k (left t) (N x k (right t) u) blanchet@33197: else blanchet@33197: N x k t u)" blanchet@33197: blanchet@33197: fun split where blanchet@33197: "split \ = \" | blanchet@33197: "split (N x k t u) = blanchet@33197: (if u \ \ \ k = level (right u) then blanchet@33197: N (data u) (Suc k) (N x k t (left u)) (right u) blanchet@33197: else blanchet@33197: N x k t u)" blanchet@33197: blanchet@33197: theorem dataset_skew_split: blanchet@33197: "dataset (skew t) = dataset t" blanchet@33197: "dataset (split t) = dataset t" blanchet@33197: nitpick blanchet@33197: sorry blanchet@33197: blanchet@33197: theorem wf_skew_split: blanchet@33197: "wf t \ skew t = t" blanchet@33197: "wf t \ split t = t" blanchet@33197: nitpick blanchet@33197: sorry blanchet@33197: blanchet@33197: primrec insort\<^isub>1 where blanchet@33197: "insort\<^isub>1 \ x = N x 1 \ \" | blanchet@33197: "insort\<^isub>1 (N y k t u) x = blanchet@33197: (* (split \ skew) *) (N y k (if x < y then insort\<^isub>1 t x else t) blanchet@33197: (if x > y then insort\<^isub>1 u x else u))" blanchet@33197: blanchet@33197: theorem wf_insort\<^isub>1: "wf t \ wf (insort\<^isub>1 t x)" blanchet@33197: nitpick blanchet@33197: oops blanchet@33197: blanchet@33197: theorem wf_insort\<^isub>1_nat: "wf t \ wf (insort\<^isub>1 t (x\nat))" blanchet@33197: nitpick [eval = "insort\<^isub>1 t x"] blanchet@33197: oops blanchet@33197: blanchet@33197: primrec insort\<^isub>2 where blanchet@33197: "insort\<^isub>2 \ x = N x 1 \ \" | blanchet@33197: "insort\<^isub>2 (N y k t u) x = blanchet@33197: (split \ skew) (N y k (if x < y then insort\<^isub>2 t x else t) blanchet@33197: (if x > y then insort\<^isub>2 u x else u))" blanchet@33197: blanchet@33197: theorem wf_insort\<^isub>2: "wf t \ wf (insort\<^isub>2 t x)" blanchet@33197: nitpick blanchet@33197: sorry blanchet@33197: blanchet@33197: theorem dataset_insort\<^isub>2: "dataset (insort\<^isub>2 t x) = {x} \ dataset t" blanchet@33197: nitpick blanchet@33197: sorry blanchet@33197: blanchet@33197: end