51 @{plugin quickcheck_full_exhaustive}, |
51 @{plugin quickcheck_full_exhaustive}, |
52 @{plugin quickcheck_narrowing}] |
52 @{plugin quickcheck_narrowing}] |
53 \<close> |
53 \<close> |
54 |
54 |
55 |
55 |
56 subsection {* Primitive logic *} |
56 subsection \<open>Primitive logic\<close> |
57 |
57 |
58 subsubsection {* Core syntax *} |
58 subsubsection \<open>Core syntax\<close> |
59 |
59 |
60 setup {* Axclass.class_axiomatization (@{binding type}, []) *} |
60 setup \<open>Axclass.class_axiomatization (@{binding type}, [])\<close> |
61 default_sort type |
61 default_sort type |
62 setup {* Object_Logic.add_base_sort @{sort type} *} |
62 setup \<open>Object_Logic.add_base_sort @{sort type}\<close> |
63 |
63 |
64 axiomatization where fun_arity: "OFCLASS('a \<Rightarrow> 'b, type_class)" |
64 axiomatization where fun_arity: "OFCLASS('a \<Rightarrow> 'b, type_class)" |
65 instance "fun" :: (type, type) type by (rule fun_arity) |
65 instance "fun" :: (type, type) type by (rule fun_arity) |
66 |
66 |
67 axiomatization where itself_arity: "OFCLASS('a itself, type_class)" |
67 axiomatization where itself_arity: "OFCLASS('a itself, type_class)" |
125 notation (xsymbols) |
125 notation (xsymbols) |
126 iff (infixr "\<longleftrightarrow>" 25) |
126 iff (infixr "\<longleftrightarrow>" 25) |
127 |
127 |
128 syntax "_The" :: "[pttrn, bool] => 'a" ("(3THE _./ _)" [0, 10] 10) |
128 syntax "_The" :: "[pttrn, bool] => 'a" ("(3THE _./ _)" [0, 10] 10) |
129 translations "THE x. P" == "CONST The (%x. P)" |
129 translations "THE x. P" == "CONST The (%x. P)" |
130 print_translation {* |
130 print_translation \<open> |
131 [(@{const_syntax The}, fn _ => fn [Abs abs] => |
131 [(@{const_syntax The}, fn _ => fn [Abs abs] => |
132 let val (x, t) = Syntax_Trans.atomic_abs_tr' abs |
132 let val (x, t) = Syntax_Trans.atomic_abs_tr' abs |
133 in Syntax.const @{syntax_const "_The"} $ x $ t end)] |
133 in Syntax.const @{syntax_const "_The"} $ x $ t end)] |
134 *} -- {* To avoid eta-contraction of body *} |
134 \<close> -- \<open>To avoid eta-contraction of body\<close> |
135 |
135 |
136 nonterminal letbinds and letbind |
136 nonterminal letbinds and letbind |
137 syntax |
137 syntax |
138 "_bind" :: "[pttrn, 'a] => letbind" ("(2_ =/ _)" 10) |
138 "_bind" :: "[pttrn, 'a] => letbind" ("(2_ =/ _)" 10) |
139 "" :: "letbind => letbinds" ("_") |
139 "" :: "letbind => letbinds" ("_") |
163 All (binder "! " 10) and |
163 All (binder "! " 10) and |
164 Ex (binder "? " 10) and |
164 Ex (binder "? " 10) and |
165 Ex1 (binder "?! " 10) |
165 Ex1 (binder "?! " 10) |
166 |
166 |
167 |
167 |
168 subsubsection {* Axioms and basic definitions *} |
168 subsubsection \<open>Axioms and basic definitions\<close> |
169 |
169 |
170 axiomatization where |
170 axiomatization where |
171 refl: "t = (t::'a)" and |
171 refl: "t = (t::'a)" and |
172 subst: "s = t \<Longrightarrow> P s \<Longrightarrow> P t" and |
172 subst: "s = t \<Longrightarrow> P s \<Longrightarrow> P t" and |
173 ext: "(!!x::'a. (f x ::'b) = g x) ==> (%x. f x) = (%x. g x)" |
173 ext: "(!!x::'a. (f x ::'b) = g x) ==> (%x. f x) = (%x. g x)" |
174 -- {*Extensionality is built into the meta-logic, and this rule expresses |
174 -- \<open>Extensionality is built into the meta-logic, and this rule expresses |
175 a related property. It is an eta-expanded version of the traditional |
175 a related property. It is an eta-expanded version of the traditional |
176 rule, and similar to the ABS rule of HOL*} and |
176 rule, and similar to the ABS rule of HOL\<close> and |
177 |
177 |
178 the_eq_trivial: "(THE x. x = a) = (a::'a)" |
178 the_eq_trivial: "(THE x. x = a) = (a::'a)" |
179 |
179 |
180 axiomatization where |
180 axiomatization where |
181 impI: "(P ==> Q) ==> P-->Q" and |
181 impI: "(P ==> Q) ==> P-->Q" and |
228 lemma meta_eq_to_obj_eq: |
228 lemma meta_eq_to_obj_eq: |
229 assumes meq: "A == B" |
229 assumes meq: "A == B" |
230 shows "A = B" |
230 shows "A = B" |
231 by (unfold meq) (rule refl) |
231 by (unfold meq) (rule refl) |
232 |
232 |
233 text {* Useful with @{text erule} for proving equalities from known equalities. *} |
233 text \<open>Useful with @{text erule} for proving equalities from known equalities.\<close> |
234 (* a = b |
234 (* a = b |
235 | | |
235 | | |
236 c = d *) |
236 c = d *) |
237 lemma box_equals: "[| a=b; a=c; b=d |] ==> c=d" |
237 lemma box_equals: "[| a=b; a=c; b=d |] ==> c=d" |
238 apply (rule trans) |
238 apply (rule trans) |
239 apply (rule trans) |
239 apply (rule trans) |
240 apply (rule sym) |
240 apply (rule sym) |
241 apply assumption+ |
241 apply assumption+ |
242 done |
242 done |
243 |
243 |
244 text {* For calculational reasoning: *} |
244 text \<open>For calculational reasoning:\<close> |
245 |
245 |
246 lemma forw_subst: "a = b ==> P b ==> P a" |
246 lemma forw_subst: "a = b ==> P b ==> P a" |
247 by (rule ssubst) |
247 by (rule ssubst) |
248 |
248 |
249 lemma back_subst: "P a ==> a = b ==> P b" |
249 lemma back_subst: "P a ==> a = b ==> P b" |
250 by (rule subst) |
250 by (rule subst) |
251 |
251 |
252 |
252 |
253 subsubsection {* Congruence rules for application *} |
253 subsubsection \<open>Congruence rules for application\<close> |
254 |
254 |
255 text {* Similar to @{text AP_THM} in Gordon's HOL. *} |
255 text \<open>Similar to @{text AP_THM} in Gordon's HOL.\<close> |
256 lemma fun_cong: "(f::'a=>'b) = g ==> f(x)=g(x)" |
256 lemma fun_cong: "(f::'a=>'b) = g ==> f(x)=g(x)" |
257 apply (erule subst) |
257 apply (erule subst) |
258 apply (rule refl) |
258 apply (rule refl) |
259 done |
259 done |
260 |
260 |
261 text {* Similar to @{text AP_TERM} in Gordon's HOL and FOL's @{text subst_context}. *} |
261 text \<open>Similar to @{text AP_TERM} in Gordon's HOL and FOL's @{text subst_context}.\<close> |
262 lemma arg_cong: "x=y ==> f(x)=f(y)" |
262 lemma arg_cong: "x=y ==> f(x)=f(y)" |
263 apply (erule subst) |
263 apply (erule subst) |
264 apply (rule refl) |
264 apply (rule refl) |
265 done |
265 done |
266 |
266 |
335 and minor: "[| P(x); ALL x. P(x) |] ==> R" |
335 and minor: "[| P(x); ALL x. P(x) |] ==> R" |
336 shows R |
336 shows R |
337 by (iprover intro: minor major major [THEN spec]) |
337 by (iprover intro: minor major major [THEN spec]) |
338 |
338 |
339 |
339 |
340 subsubsection {* False *} |
340 subsubsection \<open>False\<close> |
341 |
341 |
342 text {* |
342 text \<open> |
343 Depends upon @{text spec}; it is impossible to do propositional |
343 Depends upon @{text spec}; it is impossible to do propositional |
344 logic before quantifiers! |
344 logic before quantifiers! |
345 *} |
345 \<close> |
346 |
346 |
347 lemma FalseE: "False ==> P" |
347 lemma FalseE: "False ==> P" |
348 apply (unfold False_def) |
348 apply (unfold False_def) |
349 apply (erule spec) |
349 apply (erule spec) |
350 done |
350 done |
351 |
351 |
352 lemma False_neq_True: "False = True ==> P" |
352 lemma False_neq_True: "False = True ==> P" |
353 by (erule eqTrueE [THEN FalseE]) |
353 by (erule eqTrueE [THEN FalseE]) |
354 |
354 |
355 |
355 |
356 subsubsection {* Negation *} |
356 subsubsection \<open>Negation\<close> |
357 |
357 |
358 lemma notI: |
358 lemma notI: |
359 assumes "P ==> False" |
359 assumes "P ==> False" |
360 shows "~P" |
360 shows "~P" |
361 apply (unfold not_def) |
361 apply (unfold not_def) |
548 apply (rule exI) |
548 apply (rule exI) |
549 apply assumption |
549 apply assumption |
550 done |
550 done |
551 |
551 |
552 |
552 |
553 subsubsection {*Classical intro rules for disjunction and existential quantifiers*} |
553 subsubsection \<open>Classical intro rules for disjunction and existential quantifiers\<close> |
554 |
554 |
555 lemma disjCI: |
555 lemma disjCI: |
556 assumes "~Q ==> P" shows "P|Q" |
556 assumes "~Q ==> P" shows "P|Q" |
557 apply (rule classical) |
557 apply (rule classical) |
558 apply (iprover intro: assms disjI1 disjI2 notI elim: notE) |
558 apply (iprover intro: assms disjI1 disjI2 notI elim: notE) |
559 done |
559 done |
560 |
560 |
561 lemma excluded_middle: "~P | P" |
561 lemma excluded_middle: "~P | P" |
562 by (iprover intro: disjCI) |
562 by (iprover intro: disjCI) |
563 |
563 |
564 text {* |
564 text \<open> |
565 case distinction as a natural deduction rule. |
565 case distinction as a natural deduction rule. |
566 Note that @{term "~P"} is the second case, not the first |
566 Note that @{term "~P"} is the second case, not the first |
567 *} |
567 \<close> |
568 lemma case_split [case_names True False]: |
568 lemma case_split [case_names True False]: |
569 assumes prem1: "P ==> Q" |
569 assumes prem1: "P ==> Q" |
570 and prem2: "~P ==> Q" |
570 and prem2: "~P ==> Q" |
571 shows "Q" |
571 shows "Q" |
572 apply (rule excluded_middle [THEN disjE]) |
572 apply (rule excluded_middle [THEN disjE]) |
729 by rule iprover+ |
729 by rule iprover+ |
730 |
730 |
731 lemma atomize_elimL[atomize_elim]: "(!!B. (A ==> B) ==> B) == Trueprop A" .. |
731 lemma atomize_elimL[atomize_elim]: "(!!B. (A ==> B) ==> B) == Trueprop A" .. |
732 |
732 |
733 |
733 |
734 subsection {* Package setup *} |
734 subsection \<open>Package setup\<close> |
735 |
735 |
736 ML_file "Tools/hologic.ML" |
736 ML_file "Tools/hologic.ML" |
737 |
737 |
738 |
738 |
739 subsubsection {* Sledgehammer setup *} |
739 subsubsection \<open>Sledgehammer setup\<close> |
740 |
740 |
741 text {* |
741 text \<open> |
742 Theorems blacklisted to Sledgehammer. These theorems typically produce clauses |
742 Theorems blacklisted to Sledgehammer. These theorems typically produce clauses |
743 that are prolific (match too many equality or membership literals) and relate to |
743 that are prolific (match too many equality or membership literals) and relate to |
744 seldom-used facts. Some duplicate other rules. |
744 seldom-used facts. Some duplicate other rules. |
745 *} |
745 \<close> |
746 |
746 |
747 named_theorems no_atp "theorems that should be filtered out by Sledgehammer" |
747 named_theorems no_atp "theorems that should be filtered out by Sledgehammer" |
748 |
748 |
749 |
749 |
750 subsubsection {* Classical Reasoner setup *} |
750 subsubsection \<open>Classical Reasoner setup\<close> |
751 |
751 |
752 lemma imp_elim: "P --> Q ==> (~ R ==> P) ==> (Q ==> R) ==> R" |
752 lemma imp_elim: "P --> Q ==> (~ R ==> P) ==> (Q ==> R) ==> R" |
753 by (rule classical) iprover |
753 by (rule classical) iprover |
754 |
754 |
755 lemma swap: "~ P ==> (~ R ==> P) ==> R" |
755 lemma swap: "~ P ==> (~ R ==> P) ==> R" |
756 by (rule classical) iprover |
756 by (rule classical) iprover |
757 |
757 |
758 lemma thin_refl: |
758 lemma thin_refl: |
759 "\<And>X. \<lbrakk> x=x; PROP W \<rbrakk> \<Longrightarrow> PROP W" . |
759 "\<And>X. \<lbrakk> x=x; PROP W \<rbrakk> \<Longrightarrow> PROP W" . |
760 |
760 |
761 ML {* |
761 ML \<open> |
762 structure Hypsubst = Hypsubst |
762 structure Hypsubst = Hypsubst |
763 ( |
763 ( |
764 val dest_eq = HOLogic.dest_eq |
764 val dest_eq = HOLogic.dest_eq |
765 val dest_Trueprop = HOLogic.dest_Trueprop |
765 val dest_Trueprop = HOLogic.dest_Trueprop |
766 val dest_imp = HOLogic.dest_imp |
766 val dest_imp = HOLogic.dest_imp |
978 |
978 |
979 lemma imp_conjR: "(P --> (Q&R)) = ((P-->Q) & (P-->R))" by iprover |
979 lemma imp_conjR: "(P --> (Q&R)) = ((P-->Q) & (P-->R))" by iprover |
980 lemma imp_conjL: "((P&Q) -->R) = (P --> (Q --> R))" by iprover |
980 lemma imp_conjL: "((P&Q) -->R) = (P --> (Q --> R))" by iprover |
981 lemma imp_disjL: "((P|Q) --> R) = ((P-->R)&(Q-->R))" by iprover |
981 lemma imp_disjL: "((P|Q) --> R) = ((P-->R)&(Q-->R))" by iprover |
982 |
982 |
983 text {* These two are specialized, but @{text imp_disj_not1} is useful in @{text "Auth/Yahalom"}. *} |
983 text \<open>These two are specialized, but @{text imp_disj_not1} is useful in @{text "Auth/Yahalom"}.\<close> |
984 lemma imp_disj_not1: "(P --> Q | R) = (~Q --> P --> R)" by blast |
984 lemma imp_disj_not1: "(P --> Q | R) = (~Q --> P --> R)" by blast |
985 lemma imp_disj_not2: "(P --> Q | R) = (~R --> P --> Q)" by blast |
985 lemma imp_disj_not2: "(P --> Q | R) = (~R --> P --> Q)" by blast |
986 |
986 |
987 lemma imp_disj1: "((P-->Q)|R) = (P--> Q|R)" by blast |
987 lemma imp_disj1: "((P-->Q)|R) = (P--> Q|R)" by blast |
988 lemma imp_disj2: "(Q|(P-->R)) = (P--> Q|R)" by blast |
988 lemma imp_disj2: "(Q|(P-->R)) = (P--> Q|R)" by blast |
993 lemma de_Morgan_disj: "(~(P | Q)) = (~P & ~Q)" by iprover |
993 lemma de_Morgan_disj: "(~(P | Q)) = (~P & ~Q)" by iprover |
994 lemma de_Morgan_conj: "(~(P & Q)) = (~P | ~Q)" by blast |
994 lemma de_Morgan_conj: "(~(P & Q)) = (~P | ~Q)" by blast |
995 lemma not_imp: "(~(P --> Q)) = (P & ~Q)" by blast |
995 lemma not_imp: "(~(P --> Q)) = (P & ~Q)" by blast |
996 lemma not_iff: "(P~=Q) = (P = (~Q))" by blast |
996 lemma not_iff: "(P~=Q) = (P = (~Q))" by blast |
997 lemma disj_not1: "(~P | Q) = (P --> Q)" by blast |
997 lemma disj_not1: "(~P | Q) = (P --> Q)" by blast |
998 lemma disj_not2: "(P | ~Q) = (Q --> P)" -- {* changes orientation :-( *} |
998 lemma disj_not2: "(P | ~Q) = (Q --> P)" -- \<open>changes orientation :-(\<close> |
999 by blast |
999 by blast |
1000 lemma imp_conv_disj: "(P --> Q) = ((~P) | Q)" by blast |
1000 lemma imp_conv_disj: "(P --> Q) = ((~P) | Q)" by blast |
1001 |
1001 |
1002 lemma iff_conv_conj_imp: "(P = Q) = ((P --> Q) & (Q --> P))" by iprover |
1002 lemma iff_conv_conj_imp: "(P = Q) = ((P --> Q) & (Q --> P))" by iprover |
1003 |
1003 |
1004 |
1004 |
1005 lemma cases_simp: "((P --> Q) & (~P --> Q)) = Q" |
1005 lemma cases_simp: "((P --> Q) & (~P --> Q)) = Q" |
1006 -- {* Avoids duplication of subgoals after @{text split_if}, when the true and false *} |
1006 -- \<open>Avoids duplication of subgoals after @{text split_if}, when the true and false\<close> |
1007 -- {* cases boil down to the same thing. *} |
1007 -- \<open>cases boil down to the same thing.\<close> |
1008 by blast |
1008 by blast |
1009 |
1009 |
1010 lemma not_all: "(~ (! x. P(x))) = (? x.~P(x))" by blast |
1010 lemma not_all: "(~ (! x. P(x))) = (? x.~P(x))" by blast |
1011 lemma imp_all: "((! x. P x) --> Q) = (? x. P x --> Q)" by blast |
1011 lemma imp_all: "((! x. P x) --> Q) = (? x. P x --> Q)" by blast |
1012 lemma not_ex: "(~ (? x. P(x))) = (! x.~P(x))" by iprover |
1012 lemma not_ex: "(~ (? x. P(x))) = (! x.~P(x))" by iprover |
1016 declare All_def [no_atp] |
1016 declare All_def [no_atp] |
1017 |
1017 |
1018 lemma ex_disj_distrib: "(? x. P(x) | Q(x)) = ((? x. P(x)) | (? x. Q(x)))" by iprover |
1018 lemma ex_disj_distrib: "(? x. P(x) | Q(x)) = ((? x. P(x)) | (? x. Q(x)))" by iprover |
1019 lemma all_conj_distrib: "(!x. P(x) & Q(x)) = ((! x. P(x)) & (! x. Q(x)))" by iprover |
1019 lemma all_conj_distrib: "(!x. P(x) & Q(x)) = ((! x. P(x)) & (! x. Q(x)))" by iprover |
1020 |
1020 |
1021 text {* |
1021 text \<open> |
1022 \medskip The @{text "&"} congruence rule: not included by default! |
1022 \medskip The @{text "&"} congruence rule: not included by default! |
1023 May slow rewrite proofs down by as much as 50\% *} |
1023 May slow rewrite proofs down by as much as 50\%\<close> |
1024 |
1024 |
1025 lemma conj_cong: |
1025 lemma conj_cong: |
1026 "(P = P') ==> (P' ==> (Q = Q')) ==> ((P & Q) = (P' & Q'))" |
1026 "(P = P') ==> (P' ==> (Q = Q')) ==> ((P & Q) = (P' & Q'))" |
1027 by iprover |
1027 by iprover |
1028 |
1028 |
1029 lemma rev_conj_cong: |
1029 lemma rev_conj_cong: |
1030 "(Q = Q') ==> (Q' ==> (P = P')) ==> ((P & Q) = (P' & Q'))" |
1030 "(Q = Q') ==> (Q' ==> (P = P')) ==> ((P & Q) = (P' & Q'))" |
1031 by iprover |
1031 by iprover |
1032 |
1032 |
1033 text {* The @{text "|"} congruence rule: not included by default! *} |
1033 text \<open>The @{text "|"} congruence rule: not included by default!\<close> |
1034 |
1034 |
1035 lemma disj_cong: |
1035 lemma disj_cong: |
1036 "(P = P') ==> (~P' ==> (Q = Q')) ==> ((P | Q) = (P' | Q'))" |
1036 "(P = P') ==> (~P' ==> (Q = Q')) ==> ((P | Q) = (P' | Q'))" |
1037 by blast |
1037 by blast |
1038 |
1038 |
1039 |
1039 |
1040 text {* \medskip if-then-else rules *} |
1040 text \<open>\medskip if-then-else rules\<close> |
1041 |
1041 |
1042 lemma if_True [code]: "(if True then x else y) = x" |
1042 lemma if_True [code]: "(if True then x else y) = x" |
1043 by (unfold If_def) blast |
1043 by (unfold If_def) blast |
1044 |
1044 |
1045 lemma if_False [code]: "(if False then x else y) = y" |
1045 lemma if_False [code]: "(if False then x else y) = y" |
1068 lemma if_eq_cancel: "(if x = y then y else x) = x" |
1068 lemma if_eq_cancel: "(if x = y then y else x) = x" |
1069 by (simplesubst split_if, blast) |
1069 by (simplesubst split_if, blast) |
1070 |
1070 |
1071 lemma if_bool_eq_conj: |
1071 lemma if_bool_eq_conj: |
1072 "(if P then Q else R) = ((P-->Q) & (~P-->R))" |
1072 "(if P then Q else R) = ((P-->Q) & (~P-->R))" |
1073 -- {* This form is useful for expanding @{text "if"}s on the RIGHT of the @{text "==>"} symbol. *} |
1073 -- \<open>This form is useful for expanding @{text "if"}s on the RIGHT of the @{text "==>"} symbol.\<close> |
1074 by (rule split_if) |
1074 by (rule split_if) |
1075 |
1075 |
1076 lemma if_bool_eq_disj: "(if P then Q else R) = ((P&Q) | (~P&R))" |
1076 lemma if_bool_eq_disj: "(if P then Q else R) = ((P&Q) | (~P&R))" |
1077 -- {* And this form is useful for expanding @{text "if"}s on the LEFT. *} |
1077 -- \<open>And this form is useful for expanding @{text "if"}s on the LEFT.\<close> |
1078 by (simplesubst split_if) blast |
1078 by (simplesubst split_if) blast |
1079 |
1079 |
1080 lemma Eq_TrueI: "P ==> P == True" by (unfold atomize_eq) iprover |
1080 lemma Eq_TrueI: "P ==> P == True" by (unfold atomize_eq) iprover |
1081 lemma Eq_FalseI: "~P ==> P == False" by (unfold atomize_eq) iprover |
1081 lemma Eq_FalseI: "~P ==> P == False" by (unfold atomize_eq) iprover |
1082 |
1082 |
1083 text {* \medskip let rules for simproc *} |
1083 text \<open>\medskip let rules for simproc\<close> |
1084 |
1084 |
1085 lemma Let_folded: "f x \<equiv> g x \<Longrightarrow> Let x f \<equiv> Let x g" |
1085 lemma Let_folded: "f x \<equiv> g x \<Longrightarrow> Let x f \<equiv> Let x g" |
1086 by (unfold Let_def) |
1086 by (unfold Let_def) |
1087 |
1087 |
1088 lemma Let_unfold: "f x \<equiv> g \<Longrightarrow> Let x f \<equiv> g" |
1088 lemma Let_unfold: "f x \<equiv> g \<Longrightarrow> Let x f \<equiv> g" |
1089 by (unfold Let_def) |
1089 by (unfold Let_def) |
1090 |
1090 |
1091 text {* |
1091 text \<open> |
1092 The following copy of the implication operator is useful for |
1092 The following copy of the implication operator is useful for |
1093 fine-tuning congruence rules. It instructs the simplifier to simplify |
1093 fine-tuning congruence rules. It instructs the simplifier to simplify |
1094 its premise. |
1094 its premise. |
1095 *} |
1095 \<close> |
1096 |
1096 |
1097 definition simp_implies :: "[prop, prop] => prop" (infixr "=simp=>" 1) where |
1097 definition simp_implies :: "[prop, prop] => prop" (infixr "=simp=>" 1) where |
1098 "simp_implies \<equiv> op ==>" |
1098 "simp_implies \<equiv> op ==>" |
1099 |
1099 |
1100 lemma simp_impliesI: |
1100 lemma simp_impliesI: |
1157 lemma ex_comm: |
1157 lemma ex_comm: |
1158 "(\<exists>x y. P x y) = (\<exists>y x. P x y)" |
1158 "(\<exists>x y. P x y) = (\<exists>y x. P x y)" |
1159 by blast |
1159 by blast |
1160 |
1160 |
1161 ML_file "Tools/simpdata.ML" |
1161 ML_file "Tools/simpdata.ML" |
1162 ML {* open Simpdata *} |
1162 ML \<open>open Simpdata\<close> |
1163 |
1163 |
1164 setup {* |
1164 setup \<open> |
1165 map_theory_simpset (put_simpset HOL_basic_ss) #> |
1165 map_theory_simpset (put_simpset HOL_basic_ss) #> |
1166 Simplifier.method_setup Splitter.split_modifiers |
1166 Simplifier.method_setup Splitter.split_modifiers |
1167 *} |
1167 \<close> |
1168 |
1168 |
1169 simproc_setup defined_Ex ("EX x. P x") = {* fn _ => Quantifier1.rearrange_ex *} |
1169 simproc_setup defined_Ex ("EX x. P x") = \<open>fn _ => Quantifier1.rearrange_ex\<close> |
1170 simproc_setup defined_All ("ALL x. P x") = {* fn _ => Quantifier1.rearrange_all *} |
1170 simproc_setup defined_All ("ALL x. P x") = \<open>fn _ => Quantifier1.rearrange_all\<close> |
1171 |
1171 |
1172 text {* Simproc for proving @{text "(y = x) == False"} from premise @{text "~(x = y)"}: *} |
1172 text \<open>Simproc for proving @{text "(y = x) == False"} from premise @{text "~(x = y)"}:\<close> |
1173 |
1173 |
1174 simproc_setup neq ("x = y") = {* fn _ => |
1174 simproc_setup neq ("x = y") = \<open>fn _ => |
1175 let |
1175 let |
1176 val neq_to_EQ_False = @{thm not_sym} RS @{thm Eq_FalseI}; |
1176 val neq_to_EQ_False = @{thm not_sym} RS @{thm Eq_FalseI}; |
1177 fun is_neq eq lhs rhs thm = |
1177 fun is_neq eq lhs rhs thm = |
1178 (case Thm.prop_of thm of |
1178 (case Thm.prop_of thm of |
1179 _ $ (Not $ (eq' $ l' $ r')) => |
1179 _ $ (Not $ (eq' $ l' $ r')) => |
1281 "!!P Q. (EX x. P & Q x) = (P & (EX x. Q x))" |
1281 "!!P Q. (EX x. P & Q x) = (P & (EX x. Q x))" |
1282 "!!P Q. (EX x. P x | Q) = ((EX x. P x) | Q)" |
1282 "!!P Q. (EX x. P x | Q) = ((EX x. P x) | Q)" |
1283 "!!P Q. (EX x. P | Q x) = (P | (EX x. Q x))" |
1283 "!!P Q. (EX x. P | Q x) = (P | (EX x. Q x))" |
1284 "!!P Q. (EX x. P x --> Q) = ((ALL x. P x) --> Q)" |
1284 "!!P Q. (EX x. P x --> Q) = ((ALL x. P x) --> Q)" |
1285 "!!P Q. (EX x. P --> Q x) = (P --> (EX x. Q x))" |
1285 "!!P Q. (EX x. P --> Q x) = (P --> (EX x. Q x))" |
1286 -- {* Miniscoping: pushing in existential quantifiers. *} |
1286 -- \<open>Miniscoping: pushing in existential quantifiers.\<close> |
1287 by (iprover | blast)+ |
1287 by (iprover | blast)+ |
1288 |
1288 |
1289 lemma all_simps: |
1289 lemma all_simps: |
1290 "!!P Q. (ALL x. P x & Q) = ((ALL x. P x) & Q)" |
1290 "!!P Q. (ALL x. P x & Q) = ((ALL x. P x) & Q)" |
1291 "!!P Q. (ALL x. P & Q x) = (P & (ALL x. Q x))" |
1291 "!!P Q. (ALL x. P & Q x) = (P & (ALL x. Q x))" |
1292 "!!P Q. (ALL x. P x | Q) = ((ALL x. P x) | Q)" |
1292 "!!P Q. (ALL x. P x | Q) = ((ALL x. P x) | Q)" |
1293 "!!P Q. (ALL x. P | Q x) = (P | (ALL x. Q x))" |
1293 "!!P Q. (ALL x. P | Q x) = (P | (ALL x. Q x))" |
1294 "!!P Q. (ALL x. P x --> Q) = ((EX x. P x) --> Q)" |
1294 "!!P Q. (ALL x. P x --> Q) = ((EX x. P x) --> Q)" |
1295 "!!P Q. (ALL x. P --> Q x) = (P --> (ALL x. Q x))" |
1295 "!!P Q. (ALL x. P --> Q x) = (P --> (ALL x. Q x))" |
1296 -- {* Miniscoping: pushing in universal quantifiers. *} |
1296 -- \<open>Miniscoping: pushing in universal quantifiers.\<close> |
1297 by (iprover | blast)+ |
1297 by (iprover | blast)+ |
1298 |
1298 |
1299 lemmas [simp] = |
1299 lemmas [simp] = |
1300 triv_forall_equality (*prunes params*) |
1300 triv_forall_equality (*prunes params*) |
1301 True_implies_equals implies_True_equals (*prune True in asms*) |
1301 True_implies_equals implies_True_equals (*prune True in asms*) |
1328 simp_thms |
1328 simp_thms |
1329 |
1329 |
1330 lemmas [cong] = imp_cong simp_implies_cong |
1330 lemmas [cong] = imp_cong simp_implies_cong |
1331 lemmas [split] = split_if |
1331 lemmas [split] = split_if |
1332 |
1332 |
1333 ML {* val HOL_ss = simpset_of @{context} *} |
1333 ML \<open>val HOL_ss = simpset_of @{context}\<close> |
1334 |
1334 |
1335 text {* Simplifies x assuming c and y assuming ~c *} |
1335 text \<open>Simplifies x assuming c and y assuming ~c\<close> |
1336 lemma if_cong: |
1336 lemma if_cong: |
1337 assumes "b = c" |
1337 assumes "b = c" |
1338 and "c \<Longrightarrow> x = u" |
1338 and "c \<Longrightarrow> x = u" |
1339 and "\<not> c \<Longrightarrow> y = v" |
1339 and "\<not> c \<Longrightarrow> y = v" |
1340 shows "(if b then x else y) = (if c then u else v)" |
1340 shows "(if b then x else y) = (if c then u else v)" |
1341 using assms by simp |
1341 using assms by simp |
1342 |
1342 |
1343 text {* Prevents simplification of x and y: |
1343 text \<open>Prevents simplification of x and y: |
1344 faster and allows the execution of functional programs. *} |
1344 faster and allows the execution of functional programs.\<close> |
1345 lemma if_weak_cong [cong]: |
1345 lemma if_weak_cong [cong]: |
1346 assumes "b = c" |
1346 assumes "b = c" |
1347 shows "(if b then x else y) = (if c then x else y)" |
1347 shows "(if b then x else y) = (if c then x else y)" |
1348 using assms by (rule arg_cong) |
1348 using assms by (rule arg_cong) |
1349 |
1349 |
1350 text {* Prevents simplification of t: much faster *} |
1350 text \<open>Prevents simplification of t: much faster\<close> |
1351 lemma let_weak_cong: |
1351 lemma let_weak_cong: |
1352 assumes "a = b" |
1352 assumes "a = b" |
1353 shows "(let x = a in t x) = (let x = b in t x)" |
1353 shows "(let x = a in t x) = (let x = b in t x)" |
1354 using assms by (rule arg_cong) |
1354 using assms by (rule arg_cong) |
1355 |
1355 |
1356 text {* To tidy up the result of a simproc. Only the RHS will be simplified. *} |
1356 text \<open>To tidy up the result of a simproc. Only the RHS will be simplified.\<close> |
1357 lemma eq_cong2: |
1357 lemma eq_cong2: |
1358 assumes "u = u'" |
1358 assumes "u = u'" |
1359 shows "(t \<equiv> u) \<equiv> (t \<equiv> u')" |
1359 shows "(t \<equiv> u) \<equiv> (t \<equiv> u')" |
1360 using assms by simp |
1360 using assms by simp |
1361 |
1361 |
1362 lemma if_distrib: |
1362 lemma if_distrib: |
1363 "f (if c then x else y) = (if c then f x else f y)" |
1363 "f (if c then x else y) = (if c then f x else f y)" |
1364 by simp |
1364 by simp |
1365 |
1365 |
1366 text{*As a simplification rule, it replaces all function equalities by |
1366 text\<open>As a simplification rule, it replaces all function equalities by |
1367 first-order equalities.*} |
1367 first-order equalities.\<close> |
1368 lemma fun_eq_iff: "f = g \<longleftrightarrow> (\<forall>x. f x = g x)" |
1368 lemma fun_eq_iff: "f = g \<longleftrightarrow> (\<forall>x. f x = g x)" |
1369 by auto |
1369 by auto |
1370 |
1370 |
1371 |
1371 |
1372 subsubsection {* Generic cases and induction *} |
1372 subsubsection \<open>Generic cases and induction\<close> |
1373 |
1373 |
1374 text {* Rule projections: *} |
1374 text \<open>Rule projections:\<close> |
1375 ML {* |
1375 ML \<open> |
1376 structure Project_Rule = Project_Rule |
1376 structure Project_Rule = Project_Rule |
1377 ( |
1377 ( |
1378 val conjunct1 = @{thm conjunct1} |
1378 val conjunct1 = @{thm conjunct1} |
1379 val conjunct2 = @{thm conjunct2} |
1379 val conjunct2 = @{thm conjunct2} |
1380 val mp = @{thm mp} |
1380 val mp = @{thm mp} |
1381 ); |
1381 ); |
1382 *} |
1382 \<close> |
1383 |
1383 |
1384 context |
1384 context |
1385 begin |
1385 begin |
1386 |
1386 |
1387 qualified definition "induct_forall P \<equiv> \<forall>x. P x" |
1387 qualified definition "induct_forall P \<equiv> \<forall>x. P x" |
1536 end |
1536 end |
1537 |
1537 |
1538 ML_file "~~/src/Tools/induct_tacs.ML" |
1538 ML_file "~~/src/Tools/induct_tacs.ML" |
1539 |
1539 |
1540 |
1540 |
1541 subsubsection {* Coherent logic *} |
1541 subsubsection \<open>Coherent logic\<close> |
1542 |
1542 |
1543 ML_file "~~/src/Tools/coherent.ML" |
1543 ML_file "~~/src/Tools/coherent.ML" |
1544 ML {* |
1544 ML \<open> |
1545 structure Coherent = Coherent |
1545 structure Coherent = Coherent |
1546 ( |
1546 ( |
1547 val atomize_elimL = @{thm atomize_elimL}; |
1547 val atomize_elimL = @{thm atomize_elimL}; |
1548 val atomize_exL = @{thm atomize_exL}; |
1548 val atomize_exL = @{thm atomize_exL}; |
1549 val atomize_conjL = @{thm atomize_conjL}; |
1549 val atomize_conjL = @{thm atomize_conjL}; |
1550 val atomize_disjL = @{thm atomize_disjL}; |
1550 val atomize_disjL = @{thm atomize_disjL}; |
1551 val operator_names = [@{const_name HOL.disj}, @{const_name HOL.conj}, @{const_name Ex}]; |
1551 val operator_names = [@{const_name HOL.disj}, @{const_name HOL.conj}, @{const_name Ex}]; |
1552 ); |
1552 ); |
1553 *} |
1553 \<close> |
1554 |
1554 |
1555 |
1555 |
1556 subsubsection {* Reorienting equalities *} |
1556 subsubsection \<open>Reorienting equalities\<close> |
1557 |
1557 |
1558 ML {* |
1558 ML \<open> |
1559 signature REORIENT_PROC = |
1559 signature REORIENT_PROC = |
1560 sig |
1560 sig |
1561 val add : (term -> bool) -> theory -> theory |
1561 val add : (term -> bool) -> theory -> theory |
1562 val proc : morphism -> Proof.context -> cterm -> thm option |
1562 val proc : morphism -> Proof.context -> cterm -> thm option |
1563 end; |
1563 end; |
1614 "(\<not>(P \<and> Q)) = (\<not> P \<or> \<not> Q)" "(\<not> (P \<or> Q)) = (\<not> P \<and> \<not>Q)" "(P \<longrightarrow> Q) = (\<not>P \<or> Q)" |
1614 "(\<not>(P \<and> Q)) = (\<not> P \<or> \<not> Q)" "(\<not> (P \<or> Q)) = (\<not> P \<and> \<not>Q)" "(P \<longrightarrow> Q) = (\<not>P \<or> Q)" |
1615 "(P = Q) = ((P \<and> Q) \<or> (\<not>P \<and> \<not> Q))" "(\<not>(P = Q)) = ((P \<and> \<not> Q) \<or> (\<not>P \<and> Q))" |
1615 "(P = Q) = ((P \<and> Q) \<or> (\<not>P \<and> \<not> Q))" "(\<not>(P = Q)) = ((P \<and> \<not> Q) \<or> (\<not>P \<and> Q))" |
1616 "(\<not> \<not>(P)) = P" |
1616 "(\<not> \<not>(P)) = P" |
1617 by blast+ |
1617 by blast+ |
1618 |
1618 |
1619 subsection {* Basic ML bindings *} |
1619 subsection \<open>Basic ML bindings\<close> |
1620 |
1620 |
1621 ML {* |
1621 ML \<open> |
1622 val FalseE = @{thm FalseE} |
1622 val FalseE = @{thm FalseE} |
1623 val Let_def = @{thm Let_def} |
1623 val Let_def = @{thm Let_def} |
1624 val TrueI = @{thm TrueI} |
1624 val TrueI = @{thm TrueI} |
1625 val allE = @{thm allE} |
1625 val allE = @{thm allE} |
1626 val allI = @{thm allI} |
1626 val allI = @{thm allI} |
1665 val spec = @{thm spec} |
1665 val spec = @{thm spec} |
1666 val ssubst = @{thm ssubst} |
1666 val ssubst = @{thm ssubst} |
1667 val subst = @{thm subst} |
1667 val subst = @{thm subst} |
1668 val sym = @{thm sym} |
1668 val sym = @{thm sym} |
1669 val trans = @{thm trans} |
1669 val trans = @{thm trans} |
1670 *} |
1670 \<close> |
1671 |
1671 |
1672 ML_file "Tools/cnf.ML" |
1672 ML_file "Tools/cnf.ML" |
1673 |
1673 |
1674 |
1674 |
1675 section {* @{text NO_MATCH} simproc *} |
1675 section \<open>@{text NO_MATCH} simproc\<close> |
1676 |
1676 |
1677 text {* |
1677 text \<open> |
1678 The simplification procedure can be used to avoid simplification of terms of a certain form |
1678 The simplification procedure can be used to avoid simplification of terms of a certain form |
1679 *} |
1679 \<close> |
1680 |
1680 |
1681 definition NO_MATCH :: "'a \<Rightarrow> 'b \<Rightarrow> bool" where "NO_MATCH pat val \<equiv> True" |
1681 definition NO_MATCH :: "'a \<Rightarrow> 'b \<Rightarrow> bool" where "NO_MATCH pat val \<equiv> True" |
1682 |
1682 |
1683 lemma NO_MATCH_cong[cong]: "NO_MATCH pat val = NO_MATCH pat val" by (rule refl) |
1683 lemma NO_MATCH_cong[cong]: "NO_MATCH pat val = NO_MATCH pat val" by (rule refl) |
1684 |
1684 |
1685 declare [[coercion_args NO_MATCH - -]] |
1685 declare [[coercion_args NO_MATCH - -]] |
1686 |
1686 |
1687 simproc_setup NO_MATCH ("NO_MATCH pat val") = {* fn _ => fn ctxt => fn ct => |
1687 simproc_setup NO_MATCH ("NO_MATCH pat val") = \<open>fn _ => fn ctxt => fn ct => |
1688 let |
1688 let |
1689 val thy = Proof_Context.theory_of ctxt |
1689 val thy = Proof_Context.theory_of ctxt |
1690 val dest_binop = Term.dest_comb #> apfst (Term.dest_comb #> snd) |
1690 val dest_binop = Term.dest_comb #> apfst (Term.dest_comb #> snd) |
1691 val m = Pattern.matches thy (dest_binop (Thm.term_of ct)) |
1691 val m = Pattern.matches thy (dest_binop (Thm.term_of ct)) |
1692 in if m then NONE else SOME @{thm NO_MATCH_def} end |
1692 in if m then NONE else SOME @{thm NO_MATCH_def} end |
1693 *} |
1693 \<close> |
1694 |
1694 |
1695 text {* |
1695 text \<open> |
1696 This setup ensures that a rewrite rule of the form @{term "NO_MATCH pat val \<Longrightarrow> t"} |
1696 This setup ensures that a rewrite rule of the form @{term "NO_MATCH pat val \<Longrightarrow> t"} |
1697 is only applied, if the pattern @{term pat} does not match the value @{term val}. |
1697 is only applied, if the pattern @{term pat} does not match the value @{term val}. |
1698 *} |
1698 \<close> |
1699 |
1699 |
1700 |
1700 |
1701 subsection {* Code generator setup *} |
1701 subsection \<open>Code generator setup\<close> |
1702 |
1702 |
1703 subsubsection {* Generic code generator preprocessor setup *} |
1703 subsubsection \<open>Generic code generator preprocessor setup\<close> |
1704 |
1704 |
1705 lemma conj_left_cong: |
1705 lemma conj_left_cong: |
1706 "P \<longleftrightarrow> Q \<Longrightarrow> P \<and> R \<longleftrightarrow> Q \<and> R" |
1706 "P \<longleftrightarrow> Q \<Longrightarrow> P \<and> R \<longleftrightarrow> Q \<and> R" |
1707 by (fact arg_cong) |
1707 by (fact arg_cong) |
1708 |
1708 |
1709 lemma disj_left_cong: |
1709 lemma disj_left_cong: |
1710 "P \<longleftrightarrow> Q \<Longrightarrow> P \<or> R \<longleftrightarrow> Q \<or> R" |
1710 "P \<longleftrightarrow> Q \<Longrightarrow> P \<or> R \<longleftrightarrow> Q \<or> R" |
1711 by (fact arg_cong) |
1711 by (fact arg_cong) |
1712 |
1712 |
1713 setup {* |
1713 setup \<open> |
1714 Code_Preproc.map_pre (put_simpset HOL_basic_ss) #> |
1714 Code_Preproc.map_pre (put_simpset HOL_basic_ss) #> |
1715 Code_Preproc.map_post (put_simpset HOL_basic_ss) #> |
1715 Code_Preproc.map_post (put_simpset HOL_basic_ss) #> |
1716 Code_Simp.map_ss (put_simpset HOL_basic_ss #> |
1716 Code_Simp.map_ss (put_simpset HOL_basic_ss #> |
1717 Simplifier.add_cong @{thm conj_left_cong} #> |
1717 Simplifier.add_cong @{thm conj_left_cong} #> |
1718 Simplifier.add_cong @{thm disj_left_cong}) |
1718 Simplifier.add_cong @{thm disj_left_cong}) |
1719 *} |
1719 \<close> |
1720 |
1720 |
1721 |
1721 |
1722 subsubsection {* Equality *} |
1722 subsubsection \<open>Equality\<close> |
1723 |
1723 |
1724 class equal = |
1724 class equal = |
1725 fixes equal :: "'a \<Rightarrow> 'a \<Rightarrow> bool" |
1725 fixes equal :: "'a \<Rightarrow> 'a \<Rightarrow> bool" |
1726 assumes equal_eq: "equal x y \<longleftrightarrow> x = y" |
1726 assumes equal_eq: "equal x y \<longleftrightarrow> x = y" |
1727 begin |
1727 begin |
1738 end |
1738 end |
1739 |
1739 |
1740 declare eq_equal [symmetric, code_post] |
1740 declare eq_equal [symmetric, code_post] |
1741 declare eq_equal [code] |
1741 declare eq_equal [code] |
1742 |
1742 |
1743 setup {* |
1743 setup \<open> |
1744 Code_Preproc.map_pre (fn ctxt => |
1744 Code_Preproc.map_pre (fn ctxt => |
1745 ctxt addsimprocs [Simplifier.simproc_global_i @{theory} "equal" [@{term HOL.eq}] |
1745 ctxt addsimprocs [Simplifier.simproc_global_i @{theory} "equal" [@{term HOL.eq}] |
1746 (fn _ => fn Const (_, Type ("fun", [Type _, _])) => SOME @{thm eq_equal} | _ => NONE)]) |
1746 (fn _ => fn Const (_, Type ("fun", [Type _, _])) => SOME @{thm eq_equal} | _ => NONE)]) |
1747 *} |
1747 \<close> |
1748 |
1748 |
1749 |
1749 |
1750 subsubsection {* Generic code generator foundation *} |
1750 subsubsection \<open>Generic code generator foundation\<close> |
1751 |
1751 |
1752 text {* Datatype @{typ bool} *} |
1752 text \<open>Datatype @{typ bool}\<close> |
1753 |
1753 |
1754 code_datatype True False |
1754 code_datatype True False |
1755 |
1755 |
1756 lemma [code]: |
1756 lemma [code]: |
1757 shows "False \<and> P \<longleftrightarrow> False" |
1757 shows "False \<and> P \<longleftrightarrow> False" |
1801 |
1801 |
1802 lemma equal_itself_code [code]: |
1802 lemma equal_itself_code [code]: |
1803 "equal TYPE('a) TYPE('a) \<longleftrightarrow> True" |
1803 "equal TYPE('a) TYPE('a) \<longleftrightarrow> True" |
1804 by (simp add: equal) |
1804 by (simp add: equal) |
1805 |
1805 |
1806 setup {* Sign.add_const_constraint (@{const_name equal}, SOME @{typ "'a\<Colon>type \<Rightarrow> 'a \<Rightarrow> bool"}) *} |
1806 setup \<open>Sign.add_const_constraint (@{const_name equal}, SOME @{typ "'a\<Colon>type \<Rightarrow> 'a \<Rightarrow> bool"})\<close> |
1807 |
1807 |
1808 lemma equal_alias_cert: "OFCLASS('a, equal_class) \<equiv> ((op = :: 'a \<Rightarrow> 'a \<Rightarrow> bool) \<equiv> equal)" (is "?ofclass \<equiv> ?equal") |
1808 lemma equal_alias_cert: "OFCLASS('a, equal_class) \<equiv> ((op = :: 'a \<Rightarrow> 'a \<Rightarrow> bool) \<equiv> equal)" (is "?ofclass \<equiv> ?equal") |
1809 proof |
1809 proof |
1810 assume "PROP ?ofclass" |
1810 assume "PROP ?ofclass" |
1811 show "PROP ?equal" |
1811 show "PROP ?equal" |
1812 by (tactic {* ALLGOALS (resolve_tac @{context} [Thm.unconstrainT @{thm eq_equal}]) *}) |
1812 by (tactic \<open>ALLGOALS (resolve_tac @{context} [Thm.unconstrainT @{thm eq_equal}])\<close>) |
1813 (fact `PROP ?ofclass`) |
1813 (fact \<open>PROP ?ofclass\<close>) |
1814 next |
1814 next |
1815 assume "PROP ?equal" |
1815 assume "PROP ?equal" |
1816 show "PROP ?ofclass" proof |
1816 show "PROP ?ofclass" proof |
1817 qed (simp add: `PROP ?equal`) |
1817 qed (simp add: \<open>PROP ?equal\<close>) |
1818 qed |
1818 qed |
1819 |
1819 |
1820 setup {* Sign.add_const_constraint (@{const_name equal}, SOME @{typ "'a\<Colon>equal \<Rightarrow> 'a \<Rightarrow> bool"}) *} |
1820 setup \<open>Sign.add_const_constraint (@{const_name equal}, SOME @{typ "'a\<Colon>equal \<Rightarrow> 'a \<Rightarrow> bool"})\<close> |
1821 |
1821 |
1822 setup {* Nbe.add_const_alias @{thm equal_alias_cert} *} |
1822 setup \<open>Nbe.add_const_alias @{thm equal_alias_cert}\<close> |
1823 |
1823 |
1824 text {* Cases *} |
1824 text \<open>Cases\<close> |
1825 |
1825 |
1826 lemma Let_case_cert: |
1826 lemma Let_case_cert: |
1827 assumes "CASE \<equiv> (\<lambda>x. Let x f)" |
1827 assumes "CASE \<equiv> (\<lambda>x. Let x f)" |
1828 shows "CASE x \<equiv> f x" |
1828 shows "CASE x \<equiv> f x" |
1829 using assms by simp_all |
1829 using assms by simp_all |
1830 |
1830 |
1831 setup {* |
1831 setup \<open> |
1832 Code.add_case @{thm Let_case_cert} #> |
1832 Code.add_case @{thm Let_case_cert} #> |
1833 Code.add_undefined @{const_name undefined} |
1833 Code.add_undefined @{const_name undefined} |
1834 *} |
1834 \<close> |
1835 |
1835 |
1836 declare [[code abort: undefined]] |
1836 declare [[code abort: undefined]] |
1837 |
1837 |
1838 |
1838 |
1839 subsubsection {* Generic code generator target languages *} |
1839 subsubsection \<open>Generic code generator target languages\<close> |
1840 |
1840 |
1841 text {* type @{typ bool} *} |
1841 text \<open>type @{typ bool}\<close> |
1842 |
1842 |
1843 code_printing |
1843 code_printing |
1844 type_constructor bool \<rightharpoonup> |
1844 type_constructor bool \<rightharpoonup> |
1845 (SML) "bool" and (OCaml) "bool" and (Haskell) "Bool" and (Scala) "Boolean" |
1845 (SML) "bool" and (OCaml) "bool" and (Haskell) "Bool" and (Scala) "Boolean" |
1846 | constant True \<rightharpoonup> |
1846 | constant True \<rightharpoonup> |
1883 |
1883 |
1884 code_identifier |
1884 code_identifier |
1885 code_module Pure \<rightharpoonup> |
1885 code_module Pure \<rightharpoonup> |
1886 (SML) HOL and (OCaml) HOL and (Haskell) HOL and (Scala) HOL |
1886 (SML) HOL and (OCaml) HOL and (Haskell) HOL and (Scala) HOL |
1887 |
1887 |
1888 text {* using built-in Haskell equality *} |
1888 text \<open>using built-in Haskell equality\<close> |
1889 |
1889 |
1890 code_printing |
1890 code_printing |
1891 type_class equal \<rightharpoonup> (Haskell) "Eq" |
1891 type_class equal \<rightharpoonup> (Haskell) "Eq" |
1892 | constant HOL.equal \<rightharpoonup> (Haskell) infix 4 "==" |
1892 | constant HOL.equal \<rightharpoonup> (Haskell) infix 4 "==" |
1893 | constant HOL.eq \<rightharpoonup> (Haskell) infix 4 "==" |
1893 | constant HOL.eq \<rightharpoonup> (Haskell) infix 4 "==" |
1894 |
1894 |
1895 text {* undefined *} |
1895 text \<open>undefined\<close> |
1896 |
1896 |
1897 code_printing |
1897 code_printing |
1898 constant undefined \<rightharpoonup> |
1898 constant undefined \<rightharpoonup> |
1899 (SML) "!(raise/ Fail/ \"undefined\")" |
1899 (SML) "!(raise/ Fail/ \"undefined\")" |
1900 and (OCaml) "failwith/ \"undefined\"" |
1900 and (OCaml) "failwith/ \"undefined\"" |
1901 and (Haskell) "error/ \"undefined\"" |
1901 and (Haskell) "error/ \"undefined\"" |
1902 and (Scala) "!sys.error(\"undefined\")" |
1902 and (Scala) "!sys.error(\"undefined\")" |
1903 |
1903 |
1904 |
1904 |
1905 subsubsection {* Evaluation and normalization by evaluation *} |
1905 subsubsection \<open>Evaluation and normalization by evaluation\<close> |
1906 |
1906 |
1907 method_setup eval = {* |
1907 method_setup eval = \<open> |
1908 let |
1908 let |
1909 fun eval_tac ctxt = |
1909 fun eval_tac ctxt = |
1910 let val conv = Code_Runtime.dynamic_holds_conv ctxt |
1910 let val conv = Code_Runtime.dynamic_holds_conv ctxt |
1911 in |
1911 in |
1912 CONVERSION (Conv.params_conv ~1 (K (Conv.concl_conv ~1 conv)) ctxt) THEN' |
1912 CONVERSION (Conv.params_conv ~1 (K (Conv.concl_conv ~1 conv)) ctxt) THEN' |
1913 resolve_tac ctxt [TrueI] |
1913 resolve_tac ctxt [TrueI] |
1914 end |
1914 end |
1915 in |
1915 in |
1916 Scan.succeed (SIMPLE_METHOD' o eval_tac) |
1916 Scan.succeed (SIMPLE_METHOD' o eval_tac) |
1917 end |
1917 end |
1918 *} "solve goal by evaluation" |
1918 \<close> "solve goal by evaluation" |
1919 |
1919 |
1920 method_setup normalization = {* |
1920 method_setup normalization = \<open> |
1921 Scan.succeed (fn ctxt => |
1921 Scan.succeed (fn ctxt => |
1922 SIMPLE_METHOD' |
1922 SIMPLE_METHOD' |
1923 (CHANGED_PROP o |
1923 (CHANGED_PROP o |
1924 (CONVERSION (Nbe.dynamic_conv ctxt) |
1924 (CONVERSION (Nbe.dynamic_conv ctxt) |
1925 THEN_ALL_NEW (TRY o resolve_tac ctxt [TrueI])))) |
1925 THEN_ALL_NEW (TRY o resolve_tac ctxt [TrueI])))) |
1926 *} "solve goal by normalization" |
1926 \<close> "solve goal by normalization" |
1927 |
1927 |
1928 |
1928 |
1929 subsection {* Counterexample Search Units *} |
1929 subsection \<open>Counterexample Search Units\<close> |
1930 |
1930 |
1931 subsubsection {* Quickcheck *} |
1931 subsubsection \<open>Quickcheck\<close> |
1932 |
1932 |
1933 quickcheck_params [size = 5, iterations = 50] |
1933 quickcheck_params [size = 5, iterations = 50] |
1934 |
1934 |
1935 |
1935 |
1936 subsubsection {* Nitpick setup *} |
1936 subsubsection \<open>Nitpick setup\<close> |
1937 |
1937 |
1938 named_theorems nitpick_unfold "alternative definitions of constants as needed by Nitpick" |
1938 named_theorems nitpick_unfold "alternative definitions of constants as needed by Nitpick" |
1939 and nitpick_simp "equational specification of constants as needed by Nitpick" |
1939 and nitpick_simp "equational specification of constants as needed by Nitpick" |
1940 and nitpick_psimp "partial equational specification of constants as needed by Nitpick" |
1940 and nitpick_psimp "partial equational specification of constants as needed by Nitpick" |
1941 and nitpick_choice_spec "choice specification of constants as needed by Nitpick" |
1941 and nitpick_choice_spec "choice specification of constants as needed by Nitpick" |
1942 |
1942 |
1943 declare if_bool_eq_conj [nitpick_unfold, no_atp] |
1943 declare if_bool_eq_conj [nitpick_unfold, no_atp] |
1944 if_bool_eq_disj [no_atp] |
1944 if_bool_eq_disj [no_atp] |
1945 |
1945 |
1946 |
1946 |
1947 subsection {* Preprocessing for the predicate compiler *} |
1947 subsection \<open>Preprocessing for the predicate compiler\<close> |
1948 |
1948 |
1949 named_theorems code_pred_def "alternative definitions of constants for the Predicate Compiler" |
1949 named_theorems code_pred_def "alternative definitions of constants for the Predicate Compiler" |
1950 and code_pred_inline "inlining definitions for the Predicate Compiler" |
1950 and code_pred_inline "inlining definitions for the Predicate Compiler" |
1951 and code_pred_simp "simplification rules for the optimisations in the Predicate Compiler" |
1951 and code_pred_simp "simplification rules for the optimisations in the Predicate Compiler" |
1952 |
1952 |
1953 |
1953 |
1954 subsection {* Legacy tactics and ML bindings *} |
1954 subsection \<open>Legacy tactics and ML bindings\<close> |
1955 |
1955 |
1956 ML {* |
1956 ML \<open> |
1957 (* combination of (spec RS spec RS ...(j times) ... spec RS mp) *) |
1957 (* combination of (spec RS spec RS ...(j times) ... spec RS mp) *) |
1958 local |
1958 local |
1959 fun wrong_prem (Const (@{const_name All}, _) $ Abs (_, _, t)) = wrong_prem t |
1959 fun wrong_prem (Const (@{const_name All}, _) $ Abs (_, _, t)) = wrong_prem t |
1960 | wrong_prem (Bound _) = true |
1960 | wrong_prem (Bound _) = true |
1961 | wrong_prem _ = false; |
1961 | wrong_prem _ = false; |