# HG changeset patch # User wenzelm # Date 1639304322 -3600 # Node ID cdd2284c8047054ff24e54bfa66631204d96363d # Parent 70be57333ea1b0e1866be2e944f2e0f70c437ae4# Parent 0dd4dbe7bed387ab84124eac5ad991486698062c merged, resolving conflict in src/Doc/Implementation/Logic.thy; diff -r 70be57333ea1 -r cdd2284c8047 Admin/components/components.sha1 --- a/Admin/components/components.sha1 Sun Dec 12 10:42:51 2021 +0100 +++ b/Admin/components/components.sha1 Sun Dec 12 11:18:42 2021 +0100 @@ -274,6 +274,8 @@ edcb517b7578db4eec1b6573b624f291776e11f6 naproche-20210124.tar.gz d858eb0ede6aea6b8cc40de63bd3a17f8f9f5300 naproche-20210129.tar.gz 810ee0f35adada9bf970c33fd80b986ab2255bf3 naproche-20210201.tar.gz +37bb6d934cfaf157efcadb349a0244d145ce15b0 naproche-20211211.tar.gz +d098dd0873b1720a77dc4e060267f9a6c93f341a naproche-2d99afe5c349.tar.gz 4a4e56fd03b7ba4edd38046f853873a90cf55d1a naproche-4ad61140062f.tar.gz 77252e0b40f89825b9b5935f9f0c4cd5d4e7012a naproche-6d0d76ce2f2a.tar.gz 9c02ecf93863c3289002c5e5ac45a83e2505984c naproche-755224402e36.tar.gz diff -r 70be57333ea1 -r cdd2284c8047 CONTRIBUTORS --- a/CONTRIBUTORS Sun Dec 12 10:42:51 2021 +0100 +++ b/CONTRIBUTORS Sun Dec 12 11:18:42 2021 +0100 @@ -3,6 +3,10 @@ listed as an author in one of the source files of this Isabelle distribution. +Contributions to this Isabelle version +-------------------------------------- + + Contributions to Isabelle2021-1 ------------------------------- diff -r 70be57333ea1 -r cdd2284c8047 NEWS --- a/NEWS Sun Dec 12 10:42:51 2021 +0100 +++ b/NEWS Sun Dec 12 11:18:42 2021 +0100 @@ -4,6 +4,37 @@ (Note: Isabelle/jEdit shows a tree-view of the NEWS file in Sidekick.) +New in this Isabelle version +---------------------------- + +*** General *** + +* Old-style {* verbatim *} tokens have been discontinued (legacy feature +since Isabelle2019). INCOMPATIBILITY, use \cartouche\ syntax instead. + + +*** HOL *** + +* Theory "HOL.Relation": Added lemmas asymp_less and asymp_greater to + type class preorder. + +* Theory "HOL-Library.Multiset": + - Consolidated operation and fact names. + multp ~> multp_code + multeqp ~> multeqp_code + multp_cancel_add_mset ~> multp_cancel_add_mset0 + multp_cancel_add_mset0[simplified] ~> multp_cancel_add_mset + multp_code_iff ~> multp_code_iff_mult + multeqp_code_iff ~> multeqp_code_iff_reflcl_mult + Minor INCOMPATIBILITY. + - Moved mult1_lessE out of preorder type class and add explicit + assumption. Minor INCOMPATIBILITY. + - Added predicate multp equivalent to set mult. Reuse name previously + used for what is now called multp_code. Minor INCOMPATIBILITY. + - Lifted multiple lemmas from mult to multp. + - Redefined less_multiset to be based on multp. INCOMPATIBILITY. + + New in Isabelle2021-1 (December 2021) ------------------------------------- diff -r 70be57333ea1 -r cdd2284c8047 lib/texinputs/isabelle.sty --- a/lib/texinputs/isabelle.sty Sun Dec 12 10:42:51 2021 +0100 +++ b/lib/texinputs/isabelle.sty Sun Dec 12 11:18:42 2021 +0100 @@ -140,8 +140,6 @@ \chardef\isacharbar=`\|% \chardef\isacharbraceright=`\}% \chardef\isachartilde=`\~% -\def\isacharverbatimopen{\isacharbraceleft\isacharasterisk}% -\def\isacharverbatimclose{\isacharasterisk\isacharbraceright}% \def\isacartoucheopen{\isatext{\guilsinglleft}}% \def\isacartoucheclose{\isatext{\guilsinglright}}% } diff -r 70be57333ea1 -r cdd2284c8047 src/Doc/Implementation/Logic.thy --- a/src/Doc/Implementation/Logic.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Doc/Implementation/Logic.thy Sun Dec 12 11:18:42 2021 +0100 @@ -217,10 +217,10 @@ \<^rail>\ @{syntax_def type_const}: @{syntax name} (@{syntax embedded_ml}*) ; - @{syntax_def type_const_fn}: @{syntax type_const} @'=>' @{syntax embedded} + @{syntax_def type_const_fn}: @{syntax type_const} @'=>' @{syntax embedded_ml} ; - @{syntax_def embedded_ml}: @{syntax embedded} | - @{syntax control_symbol} @{syntax embedded} | @'_' + @{syntax_def embedded_ml}: + @'_' | @{syntax embedded} | @{syntax control_symbol} @{syntax embedded} \ The text provided as @{syntax embedded_ml} is treated as regular Isabelle/ML @@ -491,9 +491,10 @@ @{syntax_def term_const}: @{syntax name} (@{syntax embedded_ml}*) (@{syntax for_args})? ; - @{syntax_def term_const_fn}: @{ syntax term_const} @'=>' @{syntax embedded} + @{syntax_def term_const_fn}: + @{syntax term_const} @'=>' @{syntax embedded_ml} ; - @{syntax_def for_args}: @'for' (@{syntax embedded_ml}*) + @{syntax_def for_args}: @'for' (@{syntax embedded_ml}+) \ \ diff -r 70be57333ea1 -r cdd2284c8047 src/Doc/Isar_Ref/Outer_Syntax.thy --- a/src/Doc/Isar_Ref/Outer_Syntax.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Doc/Isar_Ref/Outer_Syntax.thy Sun Dec 12 11:18:42 2021 +0100 @@ -234,12 +234,11 @@ text \ A chunk of document @{syntax text} is usually given as @{syntax cartouche} - \\\\\ or @{syntax verbatim}, i.e.\ enclosed in \<^verbatim>\{*\~\\\~\<^verbatim>\*}\. For - convenience, any of the smaller text unit that conforms to @{syntax name} is - admitted as well. + \\\\\. For convenience, any of the smaller text unit that conforms to + @{syntax name} is admitted as well. \<^rail>\ - @{syntax_def text}: @{syntax embedded} | @{syntax verbatim} + @{syntax_def text}: @{syntax embedded} \ Typical uses are document markup commands, like \<^theory_text>\chapter\, \<^theory_text>\section\ etc. diff -r 70be57333ea1 -r cdd2284c8047 src/Doc/Tutorial/ToyList/ToyList.thy --- a/src/Doc/Tutorial/ToyList/ToyList.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Doc/Tutorial/ToyList/ToyList.thy Sun Dec 12 11:18:42 2021 +0100 @@ -107,7 +107,7 @@ When Isabelle prints a syntax error message, it refers to the HOL syntax as the \textbf{inner syntax} and the enclosing theory language as the \textbf{outer syntax}. -Comments\index{comment} must be in enclosed in \texttt{(* }and\texttt{ *)}. +Comments\index{comment} must be in enclosed in \texttt{(*}and\texttt{*)}. \section{Evaluation} \index{evaluation} diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/ATP.thy --- a/src/HOL/ATP.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/ATP.thy Sun Dec 12 11:18:42 2021 +0100 @@ -7,7 +7,7 @@ section \Automatic Theorem Provers (ATPs)\ theory ATP - imports Meson + imports Meson Hilbert_Choice begin subsection \ATP problems and proofs\ @@ -50,6 +50,9 @@ definition fequal :: "'a \ 'a \ bool" where "fequal x y \ (x = y)" +definition fChoice :: "('a \ bool) \ 'a" where + "fChoice \ Hilbert_Choice.Eps" + lemma fTrue_ne_fFalse: "fFalse \ fTrue" unfolding fFalse_def fTrue_def by simp @@ -130,6 +133,16 @@ "fequal x y = fFalse \ fequal (f x) (f y) = fTrue" unfolding fFalse_def fTrue_def fequal_def by auto +lemma fChoice_iff_Ex: "P (fChoice P) \ HOL.Ex P" + unfolding fChoice_def + by (fact some_eq_ex) + +text \ +We use the @{const HOL.Ex} constant on the right-hand side of @{thm [source] fChoice_iff_Ex} because +we want to use the TPTP-native version if fChoice is introduced in a logic that supports FOOL. +In logics that don't support it, it gets replaced by fEx during processing. +Notice that we cannot use @{term "\x. P x"}, as existentials are not skolimized by the metis proof +method but @{term "Ex P"} is eta-expanded if FOOL is supported.\ subsection \Basic connection between ATPs and HOL\ diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/BNF_Def.thy --- a/src/HOL/BNF_Def.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/BNF_Def.thy Sun Dec 12 11:18:42 2021 +0100 @@ -139,7 +139,7 @@ lemma pick_middlep: "(P OO Q) a c \ P a (pick_middlep P Q a c) \ Q (pick_middlep P Q a c) c" - unfolding pick_middlep_def apply(rule someI_ex) by auto + unfolding pick_middlep_def by (rule someI_ex) auto definition fstOp where "fstOp P Q ac = (fst ac, pick_middlep P Q (fst ac) (snd ac))" diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Bali/Term.thy --- a/src/HOL/Bali/Term.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Bali/Term.thy Sun Dec 12 11:18:42 2021 +0100 @@ -110,7 +110,7 @@ | UNot \ \{\tt !} logical complement\ \ \function codes for binary operations\ -datatype binop = Mul \ \{\tt * } multiplication\ +datatype binop = Mul \ \{\tt *} multiplication\ | Div \ \{\tt /} division\ | Mod \ \{\tt \%} remainder\ | Plus \ \{\tt +} addition\ diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Computational_Algebra/Factorial_Ring.thy --- a/src/HOL/Computational_Algebra/Factorial_Ring.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Computational_Algebra/Factorial_Ring.thy Sun Dec 12 11:18:42 2021 +0100 @@ -920,7 +920,7 @@ assumes "is_unit x" shows "infinite {n. x^n dvd y}" proof - - from `is_unit x` have "is_unit (x^n)" for n + from \is_unit x\ have "is_unit (x^n)" for n using is_unit_power_iff by auto hence "x^n dvd y" for n by auto @@ -2181,7 +2181,7 @@ using is_unit_power_iff by simp hence "p^k dvd x" by auto - moreover from `is_unit p` have "p^k dvd p^multiplicity p x" + moreover from \is_unit p\ have "p^k dvd p^multiplicity p x" using multiplicity_unit_left is_unit_power_iff by simp ultimately show ?thesis by simp next @@ -2194,16 +2194,16 @@ moreover have "p^k dvd x \ k = 0" proof (rule ccontr) assume "p^k dvd x" and "k \ 0" - with `p = 0` have "p^k = 0" by auto - with `p^k dvd x` have "0 dvd x" by auto + with \p = 0\ have "p^k = 0" by auto + with \p^k dvd x\ have "0 dvd x" by auto hence "x = 0" by auto - with `x \ 0` show False by auto + with \x \ 0\ show False by auto qed ultimately show ?thesis - by (auto simp add: is_unit_power_iff `\ is_unit p`) + by (auto simp add: is_unit_power_iff \\ is_unit p\) next case False - with `x \ 0` `\ is_unit p` show ?thesis + with \x \ 0\ \\ is_unit p\ show ?thesis by (simp add: power_dvd_iff_le_multiplicity dvd_power_iff multiplicity_same_power) qed qed diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Deriv.thy --- a/src/HOL/Deriv.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Deriv.thy Sun Dec 12 11:18:42 2021 +0100 @@ -1611,7 +1611,7 @@ and derf: "\x. \a < x; x < b\ \ (f has_derivative f' x) (at x)" obtains \ where "a < \" "\ < b" "f b - f a = (f' \) (b - a)" proof - - have "\x. a < x \ x < b \ (\y. f' x y - (f b - f a) / (b - a) * y) = (\v. 0)" + have "\\. a < \ \ \ < b \ (\y. f' \ y - (f b - f a) / (b - a) * y) = (\v. 0)" proof (intro Rolle_deriv[OF \a < b\]) fix x assume x: "a < x" "x < b" @@ -1619,12 +1619,8 @@ has_derivative (\y. f' x y - (f b - f a) / (b - a) * y)) (at x)" by (intro derivative_intros derf[OF x]) qed (use assms in \auto intro!: continuous_intros simp: field_simps\) - then obtain \ where - "a < \" "\ < b" "(\y. f' \ y - (f b - f a) / (b - a) * y) = (\v. 0)" - by metis then show ?thesis - by (metis (no_types, opaque_lifting) that add.right_neutral add_diff_cancel_left' add_diff_eq \a < b\ - less_irrefl nonzero_eq_divide_eq) + by (smt (verit, ccfv_SIG) pos_le_divide_eq pos_less_divide_eq that) qed theorem MVT: diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Eisbach/match_method.ML --- a/src/HOL/Eisbach/match_method.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Eisbach/match_method.ML Sun Dec 12 11:18:42 2021 +0100 @@ -95,7 +95,7 @@ else let val b = #1 (the opt_dyn) in error ("Cannot bind fact name in term match" ^ Position.here (pos_of b)) end)) -- - Scan.lift (for_fixes -- (\<^keyword>\\\ |-- Parse.token Parse.text)) + Scan.lift (for_fixes -- (\<^keyword>\\\ |-- Parse.token Parse.embedded)) >> (fn ((ctxt, ts), (fixes, body)) => (case Token.get_value body of SOME (Token.Source src) => diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Equiv_Relations.thy --- a/src/HOL/Equiv_Relations.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Equiv_Relations.thy Sun Dec 12 11:18:42 2021 +0100 @@ -368,7 +368,7 @@ have eqv: "equiv S ?r" unfolding relation_of_def by (auto intro: comp_equivI) have finite: "C \ S//?r \ finite C" for C - by (fact finite_equiv_class[OF `finite S` equiv_type[OF `equiv S ?r`]]) + by (fact finite_equiv_class[OF \finite S\ equiv_type[OF \equiv S ?r\]]) have disjoint: "A \ S//?r \ B \ S//?r \ A \ B \ A \ B = {}" for A B using eqv quotient_disj by blast diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Examples/Rewrite_Examples.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Examples/Rewrite_Examples.thy Sun Dec 12 11:18:42 2021 +0100 @@ -0,0 +1,301 @@ +theory Rewrite_Examples +imports Main "HOL-Library.Rewrite" +begin + +section \The rewrite Proof Method by Example\ + +text\ +This theory gives an overview over the features of the pattern-based rewrite proof method. + +Documentation: @{url "https://arxiv.org/abs/2111.04082"} +\ + +lemma + fixes a::int and b::int and c::int + assumes "P (b + a)" + shows "P (a + b)" +by (rewrite at "a + b" add.commute) + (rule assms) + +(* Selecting a specific subterm in a large, ambiguous term. *) +lemma + fixes a b c :: int + assumes "f (a - a + (a - a)) + f ( 0 + c) = f 0 + f c" + shows "f (a - a + (a - a)) + f ((a - a) + c) = f 0 + f c" + by (rewrite in "f _ + f \ = _" diff_self) fact + +lemma + fixes a b c :: int + assumes "f (a - a + 0 ) + f ((a - a) + c) = f 0 + f c" + shows "f (a - a + (a - a)) + f ((a - a) + c) = f 0 + f c" + by (rewrite at "f (_ + \) + f _ = _" diff_self) fact + +lemma + fixes a b c :: int + assumes "f ( 0 + (a - a)) + f ((a - a) + c) = f 0 + f c" + shows "f (a - a + (a - a)) + f ((a - a) + c) = f 0 + f c" + by (rewrite in "f (\ + _) + _ = _" diff_self) fact + +lemma + fixes a b c :: int + assumes "f (a - a + 0 ) + f ((a - a) + c) = f 0 + f c" + shows "f (a - a + (a - a)) + f ((a - a) + c) = f 0 + f c" + by (rewrite in "f (_ + \) + _ = _" diff_self) fact + +lemma + fixes x y :: nat + shows"x + y > c \ y + x > c" + by (rewrite at "\ > c" add.commute) assumption + +(* We can also rewrite in the assumptions. *) +lemma + fixes x y :: nat + assumes "y + x > c \ y + x > c" + shows "x + y > c \ y + x > c" + by (rewrite in asm add.commute) fact + +lemma + fixes x y :: nat + assumes "y + x > c \ y + x > c" + shows "x + y > c \ y + x > c" + by (rewrite in "x + y > c" at asm add.commute) fact + +lemma + fixes x y :: nat + assumes "y + x > c \ y + x > c" + shows "x + y > c \ y + x > c" + by (rewrite at "\ > c" at asm add.commute) fact + +lemma + assumes "P {x::int. y + 1 = 1 + x}" + shows "P {x::int. y + 1 = x + 1}" + by (rewrite at "x+1" in "{x::int. \ }" add.commute) fact + +lemma + assumes "P {x::int. y + 1 = 1 + x}" + shows "P {x::int. y + 1 = x + 1}" + by (rewrite at "any_identifier_will_work+1" in "{any_identifier_will_work::int. \ }" add.commute) + fact + +lemma + assumes "P {(x::nat, y::nat, z). x + z * 3 = Q (\s t. s * t + y - 3)}" + shows "P {(x::nat, y::nat, z). x + z * 3 = Q (\s t. y + s * t - 3)}" + by (rewrite at "b + d * e" in "\(a, b, c). _ = Q (\d e. \)" add.commute) fact + +(* This is not limited to the first assumption *) +lemma + assumes "PROP P \ PROP Q" + shows "PROP R \ PROP P \ PROP Q" + by (rewrite at asm assms) + +lemma + assumes "PROP P \ PROP Q" + shows "PROP R \ PROP R \ PROP P \ PROP Q" + by (rewrite at asm assms) + +(* Rewriting "at asm" selects each full assumption, not any parts *) +lemma + assumes "(PROP P \ PROP Q) \ (PROP S \ PROP R)" + shows "PROP S \ (PROP P \ PROP Q) \ PROP R" + apply (rewrite at asm assms) + apply assumption + done + + + +(* Rewriting with conditional rewriting rules works just as well. *) +lemma test_theorem: + fixes x :: nat + shows "x \ y \ x \ y \ x = y" + by (rule Orderings.order_antisym) + +(* Premises of the conditional rule yield new subgoals. The + assumptions of the goal are propagated into these subgoals +*) +lemma + fixes f :: "nat \ nat" + shows "f x \ 0 \ f x \ 0 \ f x = 0" + apply (rewrite at "f x" to "0" test_theorem) + apply assumption + apply assumption + apply (rule refl) + done + +(* This holds also for rewriting in assumptions. The order of assumptions is preserved *) +lemma + assumes rewr: "PROP P \ PROP Q \ PROP R \ PROP R'" + assumes A1: "PROP S \ PROP T \ PROP U \ PROP P" + assumes A2: "PROP S \ PROP T \ PROP U \ PROP Q" + assumes C: "PROP S \ PROP R' \ PROP T \ PROP U \ PROP V" + shows "PROP S \ PROP R \ PROP T \ PROP U \ PROP V" + apply (rewrite at asm rewr) + apply (fact A1) + apply (fact A2) + apply (fact C) + done + + +(* + Instantiation. + + Since all rewriting is now done via conversions, + instantiation becomes fairly easy to do. +*) + +(* We first introduce a function f and an extended + version of f that is annotated with an invariant. *) +fun f :: "nat \ nat" where "f n = n" +definition "f_inv (I :: nat \ bool) n \ f n" + +lemma annotate_f: "f = f_inv I" + by (simp add: f_inv_def fun_eq_iff) + +(* We have a lemma with a bound variable n, and + want to add an invariant to f. *) +lemma + assumes "P (\n. f_inv (\_. True) n + 1) = x" + shows "P (\n. f n + 1) = x" + by (rewrite to "f_inv (\_. True)" annotate_f) fact + +(* We can also add an invariant that contains the variable n bound in the outer context. + For this, we need to bind this variable to an identifier. *) +lemma + assumes "P (\n. f_inv (\x. n < x + 1) n + 1) = x" + shows "P (\n. f n + 1) = x" + by (rewrite in "\n. \" to "f_inv (\x. n < x + 1)" annotate_f) fact + +(* Any identifier will work *) +lemma + assumes "P (\n. f_inv (\x. n < x + 1) n + 1) = x" + shows "P (\n. f n + 1) = x" + by (rewrite in "\abc. \" to "f_inv (\x. abc < x + 1)" annotate_f) fact + +(* The "for" keyword. *) +lemma + assumes "P (2 + 1)" + shows "\x y. P (1 + 2 :: nat)" +by (rewrite in "P (1 + 2)" at for (x) add.commute) fact + +lemma + assumes "\x y. P (y + x)" + shows "\x y. P (x + y :: nat)" +by (rewrite in "P (x + _)" at for (x y) add.commute) fact + +lemma + assumes "\x y z. y + x + z = z + y + (x::int)" + shows "\x y z. x + y + z = z + y + (x::int)" +by (rewrite at "x + y" in "x + y + z" in for (x y z) add.commute) fact + +lemma + assumes "\x y z. z + (x + y) = z + y + (x::int)" + shows "\x y z. x + y + z = z + y + (x::int)" +by (rewrite at "(_ + y) + z" in for (y z) add.commute) fact + +lemma + assumes "\x y z. x + y + z = y + z + (x::int)" + shows "\x y z. x + y + z = z + y + (x::int)" +by (rewrite at "\ + _" at "_ = \" in for () add.commute) fact + +lemma + assumes eq: "\x. P x \ g x = x" + assumes f1: "\x. Q x \ P x" + assumes f2: "\x. Q x \ x" + shows "\x. Q x \ g x" + apply (rewrite at "g x" in for (x) eq) + apply (fact f1) + apply (fact f2) + done + +(* The for keyword can be used anywhere in the pattern where there is an \-Quantifier. *) +lemma + assumes "(\(x::int). x < 1 + x)" + and "(x::int) + 1 > x" + shows "(\(x::int). x + 1 > x) \ (x::int) + 1 > x" +by (rewrite at "x + 1" in for (x) at asm add.commute) + (rule assms) + +(* The rewrite method also has an ML interface *) +lemma + assumes "\a b. P ((a + 1) * (1 + b)) " + shows "\a b :: nat. P ((a + 1) * (b + 1))" + apply (tactic \ + let + val (x, ctxt) = yield_singleton Variable.add_fixes "x" \<^context> + (* Note that the pattern order is reversed *) + val pat = [ + Rewrite.For [(x, SOME \<^Type>\nat\)], + Rewrite.In, + Rewrite.Term (\<^Const>\plus \<^Type>\nat\ for \Free (x, \<^Type>\nat\)\ \<^term>\1 :: nat\\, [])] + val to = NONE + in CCONVERSION (Rewrite.rewrite_conv ctxt (pat, to) @{thms add.commute}) 1 end + \) + apply (fact assms) + done + +lemma + assumes "Q (\b :: int. P (\a. a + b) (\a. a + b))" + shows "Q (\b :: int. P (\a. a + b) (\a. b + a))" + apply (tactic \ + let + val (x, ctxt) = yield_singleton Variable.add_fixes "x" \<^context> + val pat = [ + Rewrite.Concl, + Rewrite.In, + Rewrite.Term (Free ("Q", (\<^Type>\int\ --> TVar (("'b",0), [])) --> \<^Type>\bool\) + $ Abs ("x", \<^Type>\int\, Rewrite.mk_hole 1 (\<^Type>\int\ --> TVar (("'b",0), [])) $ Bound 0), [(x, \<^Type>\int\)]), + Rewrite.In, + Rewrite.Term (\<^Const>\plus \<^Type>\int\ for \Free (x, \<^Type>\int\)\ \Var (("c", 0), \<^Type>\int\)\\, []) + ] + val to = NONE + in CCONVERSION (Rewrite.rewrite_conv ctxt (pat, to) @{thms add.commute}) 1 end + \) + apply (fact assms) + done + +(* There is also conversion-like rewrite function: *) +ML \ + val ct = \<^cprop>\Q (\b :: int. P (\a. a + b) (\a. b + a))\ + val (x, ctxt) = yield_singleton Variable.add_fixes "x" \<^context> + val pat = [ + Rewrite.Concl, + Rewrite.In, + Rewrite.Term (Free ("Q", (\<^typ>\int\ --> TVar (("'b",0), [])) --> \<^typ>\bool\) + $ Abs ("x", \<^typ>\int\, Rewrite.mk_hole 1 (\<^typ>\int\ --> TVar (("'b",0), [])) $ Bound 0), [(x, \<^typ>\int\)]), + Rewrite.In, + Rewrite.Term (\<^Const>\plus \<^Type>\int\ for \Free (x, \<^Type>\int\)\ \Var (("c", 0), \<^Type>\int\)\\, []) + ] + val to = NONE + val th = Rewrite.rewrite_conv ctxt (pat, to) @{thms add.commute} ct +\ + +text \Some regression tests\ + +ML \ + val ct = \<^cterm>\(\b :: int. (\a. b + a))\ + val (x, ctxt) = yield_singleton Variable.add_fixes "x" \<^context> + val pat = [ + Rewrite.In, + Rewrite.Term (\<^Const>\plus \<^Type>\int\ for \Var (("c", 0), \<^Type>\int\)\ \Var (("c", 0), \<^Type>\int\)\\, []) + ] + val to = NONE + val _ = + case try (Rewrite.rewrite_conv ctxt (pat, to) @{thms add.commute}) ct of + NONE => () + | _ => error "should not have matched anything" +\ + +ML \ + Rewrite.params_pconv (Conv.all_conv |> K |> K) \<^context> (Vartab.empty, []) \<^cterm>\\x. PROP A\ +\ + +lemma + assumes eq: "PROP A \ PROP B \ PROP C" + assumes f1: "PROP D \ PROP A" + assumes f2: "PROP D \ PROP C" + shows "\x. PROP D \ PROP B" + apply (rewrite eq) + apply (fact f1) + apply (fact f2) + done + +end diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Examples/document/root.tex --- a/src/HOL/Examples/document/root.tex Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Examples/document/root.tex Sun Dec 12 11:18:42 2021 +0100 @@ -1,7 +1,7 @@ \documentclass[11pt,a4paper]{article} \usepackage[T1]{fontenc} \usepackage[only,bigsqcap]{stmaryrd} -\usepackage{ifthen,proof,amssymb,isabelle,isabellesym} +\usepackage{ifthen,proof,amssymb,isabelle,isabellesym,wasysym} \isabellestyle{literal} \usepackage{pdfsetup}\urlstyle{rm} diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Library/Multiset.thy --- a/src/HOL/Library/Multiset.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Library/Multiset.thy Sun Dec 12 11:18:42 2021 +0100 @@ -4,12 +4,13 @@ Author: Jasmin Blanchette, Inria, LORIA, MPII Author: Dmitriy Traytel, TU Muenchen Author: Mathias Fleury, MPII + Author: Martin Desharnais, MPI-INF Saarbruecken *) section \(Finite) Multisets\ theory Multiset -imports Cancellation + imports Cancellation begin subsection \The type of multisets\ @@ -2788,8 +2789,6 @@ subsection \The multiset order\ -subsubsection \Well-foundedness\ - definition mult1 :: "('a \ 'a) set \ ('a multiset \ 'a multiset) set" where "mult1 r = {(N, M). \a M0 K. M = add_mset a M0 \ N = M0 + K \ (\b. b \# K \ (b, a) \ r)}" @@ -2797,6 +2796,9 @@ definition mult :: "('a \ 'a) set \ ('a multiset \ 'a multiset) set" where "mult r = (mult1 r)\<^sup>+" +definition multp :: "('a \ 'a \ bool) \ 'a multiset \ 'a multiset \ bool" where + "multp r M N \ (M, N) \ mult {(x, y). r x y}" + lemma mult1I: assumes "M = add_mset a M0" and "N = M0 + K" and "\b. b \# K \ (b, a) \ r" shows "(N, M) \ mult1 r" @@ -2809,14 +2811,29 @@ lemma mono_mult1: assumes "r \ r'" shows "mult1 r \ mult1 r'" -unfolding mult1_def using assms by blast + unfolding mult1_def using assms by blast lemma mono_mult: assumes "r \ r'" shows "mult r \ mult r'" -unfolding mult_def using mono_mult1[OF assms] trancl_mono by blast + unfolding mult_def using mono_mult1[OF assms] trancl_mono by blast + +lemma mono_multp[mono]: "r \ r' \ multp r \ multp r'" + unfolding le_fun_def le_bool_def +proof (intro allI impI) + fix M N :: "'a multiset" + assume "\x xa. r x xa \ r' x xa" + hence "{(x, y). r x y} \ {(x, y). r' x y}" + by blast + thus "multp r M N \ multp r' M N" + unfolding multp_def + by (fact mono_mult[THEN subsetD, rotated]) +qed lemma not_less_empty [iff]: "(M, {#}) \ mult1 r" -by (simp add: mult1_def) + by (simp add: mult1_def) + + +subsubsection \Well-foundedness\ lemma less_add: assumes mult1: "(N, add_mset a M0) \ mult1 r" @@ -2918,11 +2935,15 @@ qed qed -theorem wf_mult1: "wf r \ wf (mult1 r)" -by (rule acc_wfI) (rule all_accessible) - -theorem wf_mult: "wf r \ wf (mult r)" -unfolding mult_def by (rule wf_trancl) (rule wf_mult1) +lemma wf_mult1: "wf r \ wf (mult1 r)" + by (rule acc_wfI) (rule all_accessible) + +lemma wf_mult: "wf r \ wf (mult r)" + unfolding mult_def by (rule wf_trancl) (rule wf_mult1) + +lemma wfP_multp: "wfP r \ wfP (multp r)" + unfolding multp_def wfP_def + by (simp add: wf_mult) subsubsection \Closure-free presentation\ @@ -2965,6 +2986,9 @@ qed qed +lemmas multp_implies_one_step = + mult_implies_one_step[of "{(x, y). r x y}" for r, folded multp_def transp_trans, simplified] + lemma one_step_implies_mult: assumes "J \ {#}" and @@ -2997,6 +3021,9 @@ qed qed +lemmas one_step_implies_multp = + one_step_implies_mult[of _ _ "{(x, y). r x y}" for r, folded multp_def, simplified] + lemma subset_implies_mult: assumes sub: "A \# B" shows "(A, B) \ mult r" @@ -3009,8 +3036,10 @@ by (rule one_step_implies_mult[of "B - A" "{#}" _ A, unfolded ApBmA, simplified]) qed - -subsection \The multiset extension is cancellative for multiset union\ +lemmas subset_implies_multp = subset_implies_mult[of _ _ "{(x, y). r x y}" for r, folded multp_def] + + +subsubsection \The multiset extension is cancellative for multiset union\ lemma mult_cancel: assumes "trans s" and "irrefl s" @@ -3045,10 +3074,18 @@ thus ?L using one_step_implies_mult[of J K s "I + Z"] by (auto simp: ac_simps) qed +lemmas multp_cancel = + mult_cancel[of "{(x, y). r x y}" for r, + folded multp_def transp_trans irreflp_irrefl_eq, simplified] + lemmas mult_cancel_add_mset = mult_cancel[of _ _ "{#_#}", unfolded union_mset_add_mset_right add.comm_neutral] -lemma mult_cancel_max: +lemmas multp_cancel_add_mset = + mult_cancel_add_mset[of "{(x, y). r x y}" for r, + folded multp_def transp_trans irreflp_irrefl_eq, simplified] + +lemma mult_cancel_max0: assumes "trans s" and "irrefl s" shows "(X, Y) \ mult s \ (X - X \# Y, Y - X \# Y) \ mult s" (is "?L \ ?R") proof - @@ -3056,6 +3093,112 @@ thus ?thesis using mult_cancel[OF assms, of "X - X \# Y" "X \# Y" "Y - X \# Y"] by auto qed +lemmas mult_cancel_max = mult_cancel_max0[simplified] + +lemmas multp_cancel_max = + mult_cancel_max[of "{(x, y). r x y}" for r, + folded multp_def transp_trans irreflp_irrefl_eq, simplified] + + +subsubsection \Partial-order properties\ + +lemma mult1_lessE: + assumes "(N, M) \ mult1 {(a, b). r a b}" and "asymp r" + obtains a M0 K where "M = add_mset a M0" "N = M0 + K" + "a \# K" "\b. b \# K \ r b a" +proof - + from assms obtain a M0 K where "M = add_mset a M0" "N = M0 + K" and + *: "b \# K \ r b a" for b by (blast elim: mult1E) + moreover from * [of a] have "a \# K" + using \asymp r\ by (meson asymp.cases) + ultimately show thesis by (auto intro: that) +qed + +lemma trans_mult: "trans r \ trans (mult r)" + by (simp add: mult_def) + +lemma transp_multp: "transp r \ transp (multp r)" + unfolding multp_def transp_trans_eq + by (fact trans_mult[of "{(x, y). r x y}" for r, folded transp_trans]) + +lemma irrefl_mult: + assumes "trans r" "irrefl r" + shows "irrefl (mult r)" +proof (intro irreflI notI) + fix M + assume "(M, M) \ mult r" + then obtain I J K where "M = I + J" and "M = I + K" + and "J \ {#}" and "(\k\set_mset K. \j\set_mset J. (k, j) \ r)" + using mult_implies_one_step[OF \trans r\] by blast + then have *: "K \ {#}" and **: "\k\set_mset K. \j\set_mset K. (k, j) \ r" by auto + have "finite (set_mset K)" by simp + hence "set_mset K = {}" + using ** + proof (induction rule: finite_induct) + case empty + thus ?case by simp + next + case (insert x F) + have False + using \irrefl r\[unfolded irrefl_def, rule_format] + using \trans r\[THEN transD] + by (metis equals0D insert.IH insert.prems insertE insertI1 insertI2) + thus ?case .. + qed + with * show False by simp +qed + +lemmas irreflp_multp = + irrefl_mult[of "{(x, y). r x y}" for r, + folded transp_trans_eq irreflp_irrefl_eq, simplified, folded multp_def] + +instantiation multiset :: (preorder) order begin + +definition less_multiset :: "'a multiset \ 'a multiset \ bool" + where "M < N \ multp (<) M N" + +definition less_eq_multiset :: "'a multiset \ 'a multiset \ bool" + where "less_eq_multiset M N \ M < N \ M = N" + +instance +proof intro_classes + fix M N :: "'a multiset" + show "(M < N) = (M \ N \ \ N \ M)" + unfolding less_eq_multiset_def less_multiset_def + by (metis irreflp_def irreflp_less irreflp_multp transpE transp_less transp_multp) +next + fix M :: "'a multiset" + show "M \ M" + unfolding less_eq_multiset_def + by simp +next + fix M1 M2 M3 :: "'a multiset" + show "M1 \ M2 \ M2 \ M3 \ M1 \ M3" + unfolding less_eq_multiset_def less_multiset_def + using transp_multp[OF transp_less, THEN transpD] + by blast +next + fix M N :: "'a multiset" + show "M \ N \ N \ M \ M = N" + unfolding less_eq_multiset_def less_multiset_def + using transp_multp[OF transp_less, THEN transpD] + using irreflp_multp[OF transp_less irreflp_less, unfolded irreflp_def, rule_format] + by blast +qed + +end + +lemma mset_le_irrefl [elim!]: + fixes M :: "'a::preorder multiset" + shows "M < M \ R" + by simp + +lemma wfP_less_multiset[simp]: + assumes wfP_less: "wfP ((<) :: ('a :: preorder) \ 'a \ bool)" + shows "wfP ((<) :: 'a multiset \ 'a multiset \ bool)" + using wfP_multp[OF wfP_less] less_multiset_def + by (metis wfPUNIVI wfP_induct) + subsection \Quasi-executable version of the multiset extension\ @@ -3063,22 +3206,22 @@ Predicate variants of \mult\ and the reflexive closure of \mult\, which are executable whenever the given predicate \P\ is. Together with the standard code equations for \(\#\) and \(-\) this should yield quadratic - (with respect to calls to \P\) implementations of \multp\ and \multeqp\. + (with respect to calls to \P\) implementations of \multp_code\ and \multeqp_code\. \ -definition multp :: "('a \ 'a \ bool) \ 'a multiset \ 'a multiset \ bool" where - "multp P N M = +definition multp_code :: "('a \ 'a \ bool) \ 'a multiset \ 'a multiset \ bool" where + "multp_code P N M = (let Z = M \# N; X = M - Z in X \ {#} \ (let Y = N - Z in (\y \ set_mset Y. \x \ set_mset X. P y x)))" -definition multeqp :: "('a \ 'a \ bool) \ 'a multiset \ 'a multiset \ bool" where - "multeqp P N M = +definition multeqp_code :: "('a \ 'a \ bool) \ 'a multiset \ 'a multiset \ bool" where + "multeqp_code P N M = (let Z = M \# N; X = M - Z; Y = N - Z in (\y \ set_mset Y. \x \ set_mset X. P y x))" -lemma multp_iff: +lemma multp_code_iff_mult: assumes "irrefl R" and "trans R" and [simp]: "\x y. P x y \ (x, y) \ R" - shows "multp P N M \ (N, M) \ mult R" (is "?L \ ?R") + shows "multp_code P N M \ (N, M) \ mult R" (is "?L \ ?R") proof - have *: "M \# N + (N - M \# N) = N" "M \# N + (M - M \# N) = M" "(M - M \# N) \# (N - M \# N) = {#}" by (auto simp flip: count_inject) @@ -3086,87 +3229,40 @@ proof assume ?L thus ?R using one_step_implies_mult[of "M - M \# N" "N - M \# N" R "M \# N"] * - by (auto simp: multp_def Let_def) + by (auto simp: multp_code_def Let_def) next { fix I J K :: "'a multiset" assume "(I + J) \# (I + K) = {#}" then have "I = {#}" by (metis inter_union_distrib_right union_eq_empty) } note [dest!] = this assume ?R thus ?L using mult_implies_one_step[OF assms(2), of "N - M \# N" "M - M \# N"] - mult_cancel_max[OF assms(2,1), of "N" "M"] * by (auto simp: multp_def) + mult_cancel_max[OF assms(2,1), of "N" "M"] * by (auto simp: multp_code_def) qed qed -lemma multeqp_iff: +lemma multp_code_eq_multp: "irreflp r \ transp r \ multp_code r = multp r" + using multp_code_iff_mult[of "{(x, y). r x y}" r for r, + folded irreflp_irrefl_eq transp_trans multp_def, simplified] + by blast + +lemma multeqp_code_iff_reflcl_mult: assumes "irrefl R" and "trans R" and "\x y. P x y \ (x, y) \ R" - shows "multeqp P N M \ (N, M) \ (mult R)\<^sup>=" + shows "multeqp_code P N M \ (N, M) \ (mult R)\<^sup>=" proof - { assume "N \ M" "M - M \# N = {#}" then obtain y where "count N y \ count M y" by (auto simp flip: count_inject) then have "\y. count M y < count N y" using \M - M \# N = {#}\ by (auto simp flip: count_inject dest!: le_neq_implies_less fun_cong[of _ _ y]) } - then have "multeqp P N M \ multp P N M \ N = M" - by (auto simp: multeqp_def multp_def Let_def in_diff_count) - thus ?thesis using multp_iff[OF assms] by simp -qed - - -subsubsection \Partial-order properties\ - -lemma (in preorder) mult1_lessE: - assumes "(N, M) \ mult1 {(a, b). a < b}" - obtains a M0 K where "M = add_mset a M0" "N = M0 + K" - "a \# K" "\b. b \# K \ b < a" -proof - - from assms obtain a M0 K where "M = add_mset a M0" "N = M0 + K" and - *: "b \# K \ b < a" for b by (blast elim: mult1E) - moreover from * [of a] have "a \# K" by auto - ultimately show thesis by (auto intro: that) + then have "multeqp_code P N M \ multp_code P N M \ N = M" + by (auto simp: multeqp_code_def multp_code_def Let_def in_diff_count) + thus ?thesis using multp_code_iff_mult[OF assms] by simp qed -instantiation multiset :: (preorder) order -begin - -definition less_multiset :: "'a multiset \ 'a multiset \ bool" - where "M' < M \ (M', M) \ mult {(x', x). x' < x}" - -definition less_eq_multiset :: "'a multiset \ 'a multiset \ bool" - where "less_eq_multiset M' M \ M' < M \ M' = M" - -instance -proof - - have irrefl: "\ M < M" for M :: "'a multiset" - proof - assume "M < M" - then have MM: "(M, M) \ mult {(x, y). x < y}" by (simp add: less_multiset_def) - have "trans {(x'::'a, x). x' < x}" - by (metis (mono_tags, lifting) case_prodD case_prodI less_trans mem_Collect_eq transI) - moreover note MM - ultimately have "\I J K. M = I + J \ M = I + K - \ J \ {#} \ (\k\set_mset K. \j\set_mset J. (k, j) \ {(x, y). x < y})" - by (rule mult_implies_one_step) - then obtain I J K where "M = I + J" and "M = I + K" - and "J \ {#}" and "(\k\set_mset K. \j\set_mset J. (k, j) \ {(x, y). x < y})" by blast - then have *: "K \ {#}" and **: "\k\set_mset K. \j\set_mset K. k < j" by auto - have "finite (set_mset K)" by simp - moreover note ** - ultimately have "set_mset K = {}" - by (induct rule: finite_induct) (auto intro: order_less_trans) - with * show False by simp - qed - have trans: "K < M \ M < N \ K < N" for K M N :: "'a multiset" - unfolding less_multiset_def mult_def by (blast intro: trancl_trans) - show "OFCLASS('a multiset, order_class)" - by standard (auto simp add: less_eq_multiset_def irrefl dest: trans) -qed - -end - -lemma mset_le_irrefl [elim!]: - fixes M :: "'a::preorder multiset" - shows "M < M \ R" - by simp +lemma multeqp_code_eq_reflclp_multp: "irreflp r \ transp r \ multeqp_code r = (multp r)\<^sup>=\<^sup>=" + using multeqp_code_iff_reflcl_mult[of "{(x, y). r x y}" r for r, + folded irreflp_irrefl_eq transp_trans, simplified, folded multp_def] + by blast subsubsection \Monotonicity of multiset union\ @@ -3175,7 +3271,7 @@ by (force simp: mult1_def) lemma union_le_mono2: "B < D \ C + B < C + (D::'a::preorder multiset)" -apply (unfold less_multiset_def mult_def) +apply (unfold less_multiset_def multp_def mult_def) apply (erule trancl_induct) apply (blast intro: mult1_union) apply (blast intro: mult1_union trancl_trans) diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Library/Multiset_Order.thy --- a/src/HOL/Library/Multiset_Order.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Library/Multiset_Order.thy Sun Dec 12 11:18:42 2021 +0100 @@ -11,6 +11,135 @@ subsection \Alternative Characterizations\ +subsubsection \The Dershowitz--Manna Ordering\ + +definition multp\<^sub>D\<^sub>M where + "multp\<^sub>D\<^sub>M r M N \ + (\X Y. X \ {#} \ X \# N \ M = (N - X) + Y \ (\k. k \# Y \ (\a. a \# X \ r k a)))" + +lemma multp\<^sub>D\<^sub>M_imp_multp: + "multp\<^sub>D\<^sub>M r M N \ multp r M N" +proof - + assume "multp\<^sub>D\<^sub>M r M N" + then obtain X Y where + "X \ {#}" and "X \# N" and "M = N - X + Y" and "\k. k \# Y \ (\a. a \# X \ r k a)" + unfolding multp\<^sub>D\<^sub>M_def by blast + then have "multp r (N - X + Y) (N - X + X)" + by (intro one_step_implies_multp) (auto simp: Bex_def trans_def) + with \M = N - X + Y\ \X \# N\ show "multp r M N" + by (metis subset_mset.diff_add) +qed + +subsubsection \The Huet--Oppen Ordering\ + +definition multp\<^sub>H\<^sub>O where + "multp\<^sub>H\<^sub>O r M N \ M \ N \ (\y. count N y < count M y \ (\x. r y x \ count M x < count N x))" + +lemma multp_imp_multp\<^sub>H\<^sub>O: + assumes "asymp r" and "transp r" + shows "multp r M N \ multp\<^sub>H\<^sub>O r M N" + unfolding multp_def mult_def +proof (induction rule: trancl_induct) + case (base P) + then show ?case + using \asymp r\ + by (auto elim!: mult1_lessE simp: count_eq_zero_iff multp\<^sub>H\<^sub>O_def split: if_splits + dest!: Suc_lessD) +next + case (step N P) + from step(3) have "M \ N" and + **: "\y. count N y < count M y \ (\x. r y x \ count M x < count N x)" + by (simp_all add: multp\<^sub>H\<^sub>O_def) + from step(2) obtain M0 a K where + *: "P = add_mset a M0" "N = M0 + K" "a \# K" "\b. b \# K \ r b a" + using \asymp r\ by (auto elim: mult1_lessE) + from \M \ N\ ** *(1,2,3) have "M \ P" + using *(4) \asymp r\ + by (metis asymp.cases add_cancel_right_right add_diff_cancel_left' add_mset_add_single count_inI + count_union diff_diff_add_mset diff_single_trivial in_diff_count multi_member_last) + moreover + { assume "count P a \ count M a" + with \a \# K\ have "count N a < count M a" unfolding *(1,2) + by (auto simp add: not_in_iff) + with ** obtain z where z: "r a z" "count M z < count N z" + by blast + with * have "count N z \ count P z" + using \asymp r\ + by (metis add_diff_cancel_left' add_mset_add_single asymp.cases diff_diff_add_mset + diff_single_trivial in_diff_count not_le_imp_less) + with z have "\z. r a z \ count M z < count P z" by auto + } note count_a = this + { fix y + assume count_y: "count P y < count M y" + have "\x. r y x \ count M x < count P x" + proof (cases "y = a") + case True + with count_y count_a show ?thesis by auto + next + case False + show ?thesis + proof (cases "y \# K") + case True + with *(4) have "r y a" by simp + then show ?thesis + by (cases "count P a \ count M a") (auto dest: count_a intro: \transp r\[THEN transpD]) + next + case False + with \y \ a\ have "count P y = count N y" unfolding *(1,2) + by (simp add: not_in_iff) + with count_y ** obtain z where z: "r y z" "count M z < count N z" by auto + show ?thesis + proof (cases "z \# K") + case True + with *(4) have "r z a" by simp + with z(1) show ?thesis + by (cases "count P a \ count M a") (auto dest!: count_a intro: \transp r\[THEN transpD]) + next + case False + with \a \# K\ have "count N z \ count P z" unfolding * + by (auto simp add: not_in_iff) + with z show ?thesis by auto + qed + qed + qed + } + ultimately show ?case unfolding multp\<^sub>H\<^sub>O_def by blast +qed + +lemma multp\<^sub>H\<^sub>O_imp_multp\<^sub>D\<^sub>M: "multp\<^sub>H\<^sub>O r M N \ multp\<^sub>D\<^sub>M r M N" +unfolding multp\<^sub>D\<^sub>M_def +proof (intro iffI exI conjI) + assume "multp\<^sub>H\<^sub>O r M N" + then obtain z where z: "count M z < count N z" + unfolding multp\<^sub>H\<^sub>O_def by (auto simp: multiset_eq_iff nat_neq_iff) + define X where "X = N - M" + define Y where "Y = M - N" + from z show "X \ {#}" unfolding X_def by (auto simp: multiset_eq_iff not_less_eq_eq Suc_le_eq) + from z show "X \# N" unfolding X_def by auto + show "M = (N - X) + Y" unfolding X_def Y_def multiset_eq_iff count_union count_diff by force + show "\k. k \# Y \ (\a. a \# X \ r k a)" + proof (intro allI impI) + fix k + assume "k \# Y" + then have "count N k < count M k" unfolding Y_def + by (auto simp add: in_diff_count) + with \multp\<^sub>H\<^sub>O r M N\ obtain a where "r k a" and "count M a < count N a" + unfolding multp\<^sub>H\<^sub>O_def by blast + then show "\a. a \# X \ r k a" unfolding X_def + by (auto simp add: in_diff_count) + qed +qed + +lemma multp_eq_multp\<^sub>D\<^sub>M: "asymp r \ transp r \ multp r = multp\<^sub>D\<^sub>M r" + using multp\<^sub>D\<^sub>M_imp_multp multp_imp_multp\<^sub>H\<^sub>O[THEN multp\<^sub>H\<^sub>O_imp_multp\<^sub>D\<^sub>M] + by blast + +lemma multp_eq_multp\<^sub>H\<^sub>O: "asymp r \ transp r \ multp r = multp\<^sub>H\<^sub>O r" + using multp\<^sub>H\<^sub>O_imp_multp\<^sub>D\<^sub>M[THEN multp\<^sub>D\<^sub>M_imp_multp] multp_imp_multp\<^sub>H\<^sub>O + by blast + +subsubsection \Properties of Preorders\ + context preorder begin @@ -59,107 +188,29 @@ lemma mult_imp_less_multiset\<^sub>H\<^sub>O: "(M, N) \ mult {(x, y). x < y} \ less_multiset\<^sub>H\<^sub>O M N" -proof (unfold mult_def, induct rule: trancl_induct) - case (base P) - then show ?case - by (auto elim!: mult1_lessE simp add: count_eq_zero_iff less_multiset\<^sub>H\<^sub>O_def split: if_splits dest!: Suc_lessD) -next - case (step N P) - from step(3) have "M \ N" and - **: "\y. count N y < count M y \ (\x>y. count M x < count N x)" - by (simp_all add: less_multiset\<^sub>H\<^sub>O_def) - from step(2) obtain M0 a K where - *: "P = add_mset a M0" "N = M0 + K" "a \# K" "\b. b \# K \ b < a" - by (blast elim: mult1_lessE) - from \M \ N\ ** *(1,2,3) have "M \ P" by (force dest: *(4) elim!: less_asym split: if_splits ) - moreover - { assume "count P a \ count M a" - with \a \# K\ have "count N a < count M a" unfolding *(1,2) - by (auto simp add: not_in_iff) - with ** obtain z where z: "z > a" "count M z < count N z" - by blast - with * have "count N z \ count P z" - by (auto elim: less_asym intro: count_inI) - with z have "\z > a. count M z < count P z" by auto - } note count_a = this - { fix y - assume count_y: "count P y < count M y" - have "\x>y. count M x < count P x" - proof (cases "y = a") - case True - with count_y count_a show ?thesis by auto - next - case False - show ?thesis - proof (cases "y \# K") - case True - with *(4) have "y < a" by simp - then show ?thesis by (cases "count P a \ count M a") (auto dest: count_a intro: less_trans) - next - case False - with \y \ a\ have "count P y = count N y" unfolding *(1,2) - by (simp add: not_in_iff) - with count_y ** obtain z where z: "z > y" "count M z < count N z" by auto - show ?thesis - proof (cases "z \# K") - case True - with *(4) have "z < a" by simp - with z(1) show ?thesis - by (cases "count P a \ count M a") (auto dest!: count_a intro: less_trans) - next - case False - with \a \# K\ have "count N z \ count P z" unfolding * - by (auto simp add: not_in_iff) - with z show ?thesis by auto - qed - qed - qed - } - ultimately show ?case unfolding less_multiset\<^sub>H\<^sub>O_def by blast -qed + unfolding multp_def[of "(<)", symmetric] + using multp_imp_multp\<^sub>H\<^sub>O[of "(<)"] + by (simp add: less_multiset\<^sub>H\<^sub>O_def multp\<^sub>H\<^sub>O_def) lemma less_multiset\<^sub>D\<^sub>M_imp_mult: "less_multiset\<^sub>D\<^sub>M M N \ (M, N) \ mult {(x, y). x < y}" -proof - - assume "less_multiset\<^sub>D\<^sub>M M N" - then obtain X Y where - "X \ {#}" and "X \# N" and "M = N - X + Y" and "\k. k \# Y \ (\a. a \# X \ k < a)" - unfolding less_multiset\<^sub>D\<^sub>M_def by blast - then have "(N - X + Y, N - X + X) \ mult {(x, y). x < y}" - by (intro one_step_implies_mult) (auto simp: Bex_def trans_def) - with \M = N - X + Y\ \X \# N\ show "(M, N) \ mult {(x, y). x < y}" - by (metis subset_mset.diff_add) -qed + unfolding multp_def[of "(<)", symmetric] + by (rule multp\<^sub>D\<^sub>M_imp_multp[of "(<)" M N]) (simp add: less_multiset\<^sub>D\<^sub>M_def multp\<^sub>D\<^sub>M_def) lemma less_multiset\<^sub>H\<^sub>O_imp_less_multiset\<^sub>D\<^sub>M: "less_multiset\<^sub>H\<^sub>O M N \ less_multiset\<^sub>D\<^sub>M M N" -unfolding less_multiset\<^sub>D\<^sub>M_def -proof (intro iffI exI conjI) - assume "less_multiset\<^sub>H\<^sub>O M N" - then obtain z where z: "count M z < count N z" - unfolding less_multiset\<^sub>H\<^sub>O_def by (auto simp: multiset_eq_iff nat_neq_iff) - define X where "X = N - M" - define Y where "Y = M - N" - from z show "X \ {#}" unfolding X_def by (auto simp: multiset_eq_iff not_less_eq_eq Suc_le_eq) - from z show "X \# N" unfolding X_def by auto - show "M = (N - X) + Y" unfolding X_def Y_def multiset_eq_iff count_union count_diff by force - show "\k. k \# Y \ (\a. a \# X \ k < a)" - proof (intro allI impI) - fix k - assume "k \# Y" - then have "count N k < count M k" unfolding Y_def - by (auto simp add: in_diff_count) - with \less_multiset\<^sub>H\<^sub>O M N\ obtain a where "k < a" and "count M a < count N a" - unfolding less_multiset\<^sub>H\<^sub>O_def by blast - then show "\a. a \# X \ k < a" unfolding X_def - by (auto simp add: in_diff_count) - qed -qed + unfolding less_multiset\<^sub>D\<^sub>M_def less_multiset\<^sub>H\<^sub>O_def + unfolding multp\<^sub>D\<^sub>M_def[symmetric] multp\<^sub>H\<^sub>O_def[symmetric] + by (rule multp\<^sub>H\<^sub>O_imp_multp\<^sub>D\<^sub>M) lemma mult_less_multiset\<^sub>D\<^sub>M: "(M, N) \ mult {(x, y). x < y} \ less_multiset\<^sub>D\<^sub>M M N" - by (metis less_multiset\<^sub>D\<^sub>M_imp_mult less_multiset\<^sub>H\<^sub>O_imp_less_multiset\<^sub>D\<^sub>M mult_imp_less_multiset\<^sub>H\<^sub>O) + unfolding multp_def[of "(<)", symmetric] + using multp_eq_multp\<^sub>D\<^sub>M[of "(<)", simplified] + by (simp add: multp\<^sub>D\<^sub>M_def less_multiset\<^sub>D\<^sub>M_def) lemma mult_less_multiset\<^sub>H\<^sub>O: "(M, N) \ mult {(x, y). x < y} \ less_multiset\<^sub>H\<^sub>O M N" - by (metis less_multiset\<^sub>D\<^sub>M_imp_mult less_multiset\<^sub>H\<^sub>O_imp_less_multiset\<^sub>D\<^sub>M mult_imp_less_multiset\<^sub>H\<^sub>O) + unfolding multp_def[of "(<)", symmetric] + using multp_eq_multp\<^sub>H\<^sub>O[of "(<)", simplified] + by (simp add: multp\<^sub>H\<^sub>O_def less_multiset\<^sub>H\<^sub>O_def) lemmas mult\<^sub>D\<^sub>M = mult_less_multiset\<^sub>D\<^sub>M[unfolded less_multiset\<^sub>D\<^sub>M_def] lemmas mult\<^sub>H\<^sub>O = mult_less_multiset\<^sub>H\<^sub>O[unfolded less_multiset\<^sub>H\<^sub>O_def] @@ -167,10 +218,15 @@ end lemma less_multiset_less_multiset\<^sub>H\<^sub>O: "M < N \ less_multiset\<^sub>H\<^sub>O M N" - unfolding less_multiset_def mult\<^sub>H\<^sub>O less_multiset\<^sub>H\<^sub>O_def .. + unfolding less_multiset_def multp_def mult\<^sub>H\<^sub>O less_multiset\<^sub>H\<^sub>O_def .. -lemmas less_multiset\<^sub>D\<^sub>M = mult\<^sub>D\<^sub>M[folded less_multiset_def] -lemmas less_multiset\<^sub>H\<^sub>O = mult\<^sub>H\<^sub>O[folded less_multiset_def] +lemma less_multiset\<^sub>D\<^sub>M: + "M < N \ (\X Y. X \ {#} \ X \# N \ M = N - X + Y \ (\k. k \# Y \ (\a. a \# X \ k < a)))" + by (rule mult\<^sub>D\<^sub>M[folded multp_def less_multiset_def]) + +lemma less_multiset\<^sub>H\<^sub>O: + "M < N \ M \ N \ (\y. count N y < count M y \ (\x>y. count M x < count N x))" + by (rule mult\<^sub>H\<^sub>O[folded multp_def less_multiset_def]) lemma subset_eq_imp_le_multiset: shows "M \# N \ M \ N" @@ -198,7 +254,7 @@ (* FIXME: "le" should be "less" in this and other names *) lemma le_multiset_empty_right[simp]: "\ M < {#}" - using subset_mset.le_zero_eq less_multiset\<^sub>D\<^sub>M by blast + using subset_mset.le_zero_eq less_multiset_def multp_def less_multiset\<^sub>D\<^sub>M by blast (* FIXME: "le" should be "less" in this and other names *) lemma union_le_diff_plus: "P \# M \ N < P \ M - P + N < M" @@ -381,9 +437,9 @@ begin lemma wf_less_multiset: "wf {(M :: 'a multiset, N). M < N}" - unfolding less_multiset_def by (auto intro: wf_mult wf) + unfolding less_multiset_def multp_def by (auto intro: wf_mult wf) -instance by standard (metis less_multiset_def wf wf_def wf_mult) +instance by standard (metis less_multiset_def multp_def wf wf_def wf_mult) end diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Library/Rewrite.thy --- a/src/HOL/Library/Rewrite.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Library/Rewrite.thy Sun Dec 12 11:18:42 2021 +0100 @@ -2,6 +2,8 @@ Author: Christoph Traut, Lars Noschinski, TU Muenchen Proof method "rewrite" with support for subterm-selection based on patterns. + +Documentation: https://arxiv.org/abs/2111.04082 *) theory Rewrite diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/List.thy --- a/src/HOL/List.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/List.thy Sun Dec 12 11:18:42 2021 +0100 @@ -4238,6 +4238,8 @@ case (Cons x xs) thus ?case by (fastforce split: if_splits) qed +lemmas find_None_iff2 = find_None_iff[THEN eq_iff_swap] + lemma find_Some_iff: "List.find P xs = Some x \ (\i x = xs!i \ (\j P (xs!j)))" @@ -4249,6 +4251,8 @@ using diff_Suc_1[unfolded One_nat_def] less_Suc_eq_0_disj by fastforce qed +lemmas find_Some_iff2 = find_Some_iff[THEN eq_iff_swap] + lemma find_cong[fundef_cong]: assumes "xs = ys" and "\x. x \ set ys \ P x = Q x" shows "List.find P xs = List.find Q ys" diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Map.thy --- a/src/HOL/Map.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Map.thy Sun Dec 12 11:18:42 2021 +0100 @@ -667,6 +667,10 @@ lemma fun_upd_None_if_notin_dom[simp]: "k \ dom m \ m(k := None) = m" by auto +lemma ran_map_upd_Some: + "\ m x = Some y; inj_on m (dom m); z \ ran m \ \ ran(m(x := Some z)) = ran m - {y} \ {z}" +by(force simp add: ran_def domI inj_onD) + lemma ran_map_add: assumes "dom m1 \ dom m2 = {}" shows "ran (m1 ++ m2) = ran m1 \ ran m2" diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/ROOT --- a/src/HOL/ROOT Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/ROOT Sun Dec 12 11:18:42 2021 +0100 @@ -36,6 +36,7 @@ "ML" Peirce Records + Rewrite_Examples Seq Sqrt document_files @@ -695,7 +696,6 @@ Reflection_Examples Refute_Examples Residue_Ring - Rewrite_Examples SOS SOS_Cert Serbian diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Relation.thy --- a/src/HOL/Relation.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Relation.thy Sun Dec 12 11:18:42 2021 +0100 @@ -241,6 +241,11 @@ lemma irrefl_distinct [code]: "irrefl r \ (\(a, b) \ r. a \ b)" by (auto simp add: irrefl_def) +lemma (in preorder) irreflp_less[simp]: "irreflp (<)" + by (simp add: irreflpI) + +lemma (in preorder) irreflp_greater[simp]: "irreflp (>)" + by (simp add: irreflpI) subsubsection \Asymmetry\ @@ -259,6 +264,17 @@ lemma asym_iff: "asym R \ (\x y. (x,y) \ R \ (y,x) \ R)" by (blast intro: asymI dest: asymD) +context preorder begin + +lemma asymp_less[simp]: "asymp (<)" + by (auto intro: asympI dual_order.asym) + +lemma asymp_greater[simp]: "asymp (>)" + by (auto intro: asympI dual_order.asym) + +end + + subsubsection \Symmetry\ definition sym :: "'a rel \ bool" diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Set_Interval.thy --- a/src/HOL/Set_Interval.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Set_Interval.thy Sun Dec 12 11:18:42 2021 +0100 @@ -1581,7 +1581,7 @@ assume "finite S" and "\ Suc (Max S) \ card S" then have "Suc (Max S) < card S" by simp - with `finite S` have "S \ {0..Max S}" + with \finite S\ have "S \ {0..Max S}" by auto hence "card S \ card {0..Max S}" by (intro card_mono; auto) @@ -2110,14 +2110,14 @@ let ?S' = "S - {Max S}" from Suc have "Max S \ S" by (auto intro: Max_in) hence cards: "card S = Suc (card ?S')" - using `finite S` by (intro card.remove; auto) + using \finite S\ by (intro card.remove; auto) hence "\ {0.. \ ?S'" using Suc by (intro Suc; auto) hence "\ {0.. \ ?S' + Max S" - using `Max S \ x` by simp + using \Max S \ x\ by simp also have "... = \ S" - using sum.remove[OF `finite S` `Max S \ S`, where g="\x. x"] + using sum.remove[OF \finite S\ \Max S \ S\, where g="\x. x"] by simp finally show ?case using cards Suc by auto diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/TPTP/ATP_Theory_Export.thy --- a/src/HOL/TPTP/ATP_Theory_Export.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/TPTP/ATP_Theory_Export.thy Sun Dec 12 11:18:42 2021 +0100 @@ -26,7 +26,8 @@ if do_it then "/tmp/isa_filter" |> generate_casc_lbt_isa_files_for_theory ctxt thy - (THF (Without_FOOL, Polymorphic, THF_Without_Choice)) infer_policy "poly_native_higher" + (THF (Polymorphic, {with_ite = false, with_let = false}, THF_Without_Choice)) infer_policy + "poly_native_higher" else () \ diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/TPTP/atp_problem_import.ML --- a/src/HOL/TPTP/atp_problem_import.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/TPTP/atp_problem_import.ML Sun Dec 12 11:18:42 2021 +0100 @@ -246,8 +246,6 @@ ORELSE SOLVE_TIMEOUT (timeout div 10) "meson" (Meson.meson_tac lthy [] i) ORELSE SOLVE_TIMEOUT (timeout div 10) "fastforce" (fast_force_tac lthy i) -fun problem_const_prefix thy = Context.theory_name thy ^ Long_Name.separator - fun make_conj (defs, nondefs) conjs = Logic.list_implies (rev defs @ rev nondefs, case conjs of conj :: _ => conj | [] => \<^prop>\False\) @@ -298,9 +296,9 @@ val (format, type_enc, lam_trans) = (case format_str of "FOF" => (FOF, "mono_guards??", liftingN) - | "TF0" => (TFF (Without_FOOL, Monomorphic), "mono_native", liftingN) - | "TH0" => (THF (Without_FOOL, Monomorphic, THF_Without_Choice), "mono_native_higher", - keep_lamsN) + | "TF0" => (TFF (Monomorphic, Without_FOOL), "mono_native", liftingN) + | "TH0" => (THF (Monomorphic, {with_ite = false, with_let = false}, THF_Without_Choice), + "mono_native_higher", keep_lamsN) | "DFG" => (DFG Monomorphic, "mono_native", liftingN) | _ => error ("Unknown format " ^ quote format_str ^ " (expected \"FOF\", \"TF0\", \"TH0\", or \"DFG\")")) diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/TPTP/atp_theory_export.ML --- a/src/HOL/TPTP/atp_theory_export.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/TPTP/atp_theory_export.ML Sun Dec 12 11:18:42 2021 +0100 @@ -36,11 +36,11 @@ val prefix = Library.prefix val fact_name_of = prefix fact_prefix o ascii_of -fun atp_of_format (THF (_, Polymorphic, _)) = leo3N - | atp_of_format (THF (_, Monomorphic, _)) = satallaxN +fun atp_of_format (THF (Polymorphic, _, _)) = leo3N + | atp_of_format (THF (Monomorphic, _, _)) = satallaxN | atp_of_format (DFG Monomorphic) = spassN - | atp_of_format (TFF (_, Polymorphic)) = alt_ergoN - | atp_of_format (TFF (_, Monomorphic)) = vampireN + | atp_of_format (TFF (Polymorphic, _)) = alt_ergoN + | atp_of_format (TFF (Monomorphic, _)) = vampireN | atp_of_format FOF = eN (* FIXME? *) | atp_of_format CNF_UEQ = waldmeisterN | atp_of_format CNF = eN (* FIXME? *) diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Tools/ATP/atp_problem.ML --- a/src/HOL/Tools/ATP/atp_problem.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Tools/ATP/atp_problem.ML Sun Dec 12 11:18:42 2021 +0100 @@ -32,7 +32,8 @@ gen_prec : bool, gen_simp : bool} - datatype fool = Without_FOOL | With_FOOL + type syntax = {with_ite : bool, with_let : bool} + datatype fool = Without_FOOL | With_FOOL of syntax datatype polymorphism = Monomorphic | Polymorphic datatype thf_flavor = THF_Lambda_Free | THF_Without_Choice | THF_With_Choice @@ -40,8 +41,8 @@ CNF | CNF_UEQ | FOF | - TFF of fool * polymorphism | - THF of fool * polymorphism * thf_flavor | + TFF of polymorphism * fool | + THF of polymorphism * syntax * thf_flavor | DFG of polymorphism datatype atp_formula_role = @@ -196,7 +197,9 @@ gen_prec : bool, gen_simp : bool} -datatype fool = Without_FOOL | With_FOOL + +type syntax = {with_ite : bool, with_let : bool} +datatype fool = Without_FOOL | With_FOOL of syntax datatype polymorphism = Monomorphic | Polymorphic datatype thf_flavor = THF_Lambda_Free | THF_Without_Choice | THF_With_Choice @@ -204,8 +207,8 @@ CNF | CNF_UEQ | FOF | - TFF of fool * polymorphism | - THF of fool * polymorphism * thf_flavor | + TFF of polymorphism * fool | + THF of polymorphism * syntax * thf_flavor | DFG of polymorphism datatype atp_formula_role = @@ -274,7 +277,7 @@ fun make_builtin arity is_predicate name = (name, {arity = arity, is_predicate = is_predicate}) in map (make_builtin 0 true) [tptp_false, tptp_true] @ - map (make_builtin 1 true) [tptp_not] @ + map (make_builtin 1 true) [tptp_not, tptp_ho_forall, tptp_ho_exists] @ map (make_builtin 2 true) [tptp_and, tptp_or, tptp_implies, tptp_if, tptp_iff, tptp_not_iff, tptp_equal, tptp_old_equal] @ map (make_builtin 2 false) [tptp_let] @ @@ -390,13 +393,17 @@ fun is_format_higher_order (THF _) = true | is_format_higher_order _ = false + +fun is_format_higher_order_with_choice (THF (_, _, THF_With_Choice)) = true + | is_format_higher_order_with_choice _ = false + fun is_format_typed (TFF _) = true | is_format_typed (THF _) = true | is_format_typed (DFG _) = true | is_format_typed _ = false -fun is_format_with_fool (THF (With_FOOL, _, _)) = true - | is_format_with_fool (TFF (With_FOOL, _)) = true +fun is_format_with_fool (THF _) = true + | is_format_with_fool (TFF (_, With_FOOL _)) = true | is_format_with_fool _ = false fun tptp_string_of_role Axiom = "axiom" @@ -516,7 +523,7 @@ if ts = [] orelse is_format_higher_order format then app0 (s ^ "(" ^ declaration ^ ", " ^ definition ^ ", " ^ usage ^ ")") [] ts else - error (tptp_let ^ " is special syntax and more than three arguments is only \ + error (tptp_let ^ " is special syntax and more than two arguments is only \ \supported in higher order") end | _ => error (tptp_let ^ " is special syntax and must have at least two arguments")) @@ -526,19 +533,21 @@ if ts = [] orelse is_format_higher_order format then app0 (s ^ "(" ^ of_term t1 ^ ", " ^ of_term t2 ^ ", " ^ of_term t3 ^ ")") [] ts else - error (tptp_ite ^" is special syntax and more than three arguments is only supported \ + error (tptp_ite ^ " is special syntax and more than three arguments is only supported \ \in higher order") - | _ => error "$ite is special syntax and must have at least three arguments") + | _ => error (tptp_ite ^ " is special syntax and must have at least three arguments")) else if s = tptp_choice then (case ts of - [AAbs (((s', ty), tm), args)] => + (AAbs (((s', ty), tm), args) :: ts) => (* There is code in "ATP_Problem_Generate" to ensure that "Eps" is always applied to an abstraction. *) - tptp_string_of_app format - (tptp_choice ^ "[" ^ s' ^ " : " ^ of_type ty ^ - "]: " ^ of_term tm ^ "" - |> parens) (map of_term args) - | _ => app ()) + if ts = [] orelse is_format_higher_order_with_choice format then + let val declaration = s' ^ " : " ^ of_type ty in + app0 ("(" ^ tptp_choice ^ "[" ^ declaration ^ "]: " ^ of_term tm ^ ")") [] (args @ ts) + end + else + error (tptp_choice ^ " is only supported in higher order") + | _ => error (tptp_choice ^ " must be followed by a lambda abstraction")) else (case (Symtab.lookup tptp_builtins s, ts) of (SOME {arity = 1, is_predicate = true}, [t]) => diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Tools/ATP/atp_problem_generate.ML --- a/src/HOL/Tools/ATP/atp_problem_generate.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Tools/ATP/atp_problem_generate.ML Sun Dec 12 11:18:42 2021 +0100 @@ -153,10 +153,8 @@ Const_Types of ctr_optim | No_Types -type syntax = {with_ite: bool} - datatype type_enc = - Native of order * fool * syntax * polymorphism * type_level | + Native of order * fool * polymorphism * type_level | Guards of polymorphism * type_level | Tags of polymorphism * type_level @@ -165,17 +163,22 @@ fun is_type_enc_native (Native _) = true | is_type_enc_native _ = false -fun is_type_enc_full_higher_order (Native (Higher_Order THF_Lambda_Free, _, _, _, _)) = false - | is_type_enc_full_higher_order (Native (Higher_Order _, _, _, _, _)) = true +fun is_type_enc_full_higher_order (Native (Higher_Order THF_Lambda_Free, _, _, _)) = false + | is_type_enc_full_higher_order (Native (Higher_Order _, _, _, _)) = true | is_type_enc_full_higher_order _ = false -fun is_type_enc_fool (Native (_, With_FOOL, _, _, _)) = true +fun is_type_enc_fool (Native (_, With_FOOL _, _, _)) = true | is_type_enc_fool _ = false -fun is_type_enc_higher_order (Native (Higher_Order _, _, _, _, _)) = true +fun is_type_enc_higher_order (Native (Higher_Order _, _, _, _)) = true | is_type_enc_higher_order _ = false -fun has_type_enc_ite (Native (_, _, {with_ite, ...}, _, _)) = with_ite + +fun has_type_enc_choice (Native (Higher_Order THF_With_Choice, _, _, _)) = true + | has_type_enc_choice _ = false +fun has_type_enc_ite (Native (_, With_FOOL {with_ite, ...}, _, _)) = with_ite | has_type_enc_ite _ = false +fun has_type_enc_let (Native (_, With_FOOL {with_let, ...}, _, _)) = with_let + | has_type_enc_let _ = false -fun polymorphism_of_type_enc (Native (_, _, _, poly, _)) = poly +fun polymorphism_of_type_enc (Native (_, _, poly, _)) = poly | polymorphism_of_type_enc (Guards (poly, _)) = poly | polymorphism_of_type_enc (Tags (poly, _)) = poly @@ -188,7 +191,7 @@ fun is_type_enc_mangling type_enc = polymorphism_of_type_enc type_enc = Mangled_Monomorphic -fun level_of_type_enc (Native (_, _, _, _, level)) = level +fun level_of_type_enc (Native (_, _, _, level)) = level | level_of_type_enc (Guards (_, level)) = level | level_of_type_enc (Tags (_, level)) = level @@ -330,7 +333,8 @@ ("c_implies", (\<^const_name>\implies\, (@{thm fimplies_def}, ("fimplies", \<^const_name>\fimplies\)))), ("equal", (\<^const_name>\HOL.eq\, (@{thm fequal_def}, ("fequal", \<^const_name>\fequal\)))), ("c_All", (\<^const_name>\All\, (@{thm fAll_def}, ("fAll", \<^const_name>\fAll\)))), - ("c_Ex", (\<^const_name>\Ex\, (@{thm fEx_def}, ("fEx", \<^const_name>\fEx\))))] + ("c_Ex", (\<^const_name>\Ex\, (@{thm fEx_def}, ("fEx", \<^const_name>\fEx\)))), + ("c_Choice", (\<^const_name>\Hilbert_Choice.Eps\, (@{thm fChoice_def}, ("fChoice", \<^const_name>\fChoice\))))] val proxify_const = AList.lookup (op =) proxy_table #> Option.map (snd o snd) @@ -349,6 +353,7 @@ (\<^const_name>\If\, "If"), (\<^const_name>\Set.member\, "member"), (\<^const_name>\HOL.Let\, "Let"), + (\<^const_name>\Hilbert_Choice.Eps\, "Choice"), (\<^const_name>\Meson.COMBI\, combinator_prefix ^ "I"), (\<^const_name>\Meson.COMBK\, combinator_prefix ^ "K"), (\<^const_name>\Meson.COMBB\, combinator_prefix ^ "B"), @@ -386,15 +391,8 @@ fun tvar_name ((x as (s, _)), _) = (make_tvar x, s) (* "HOL.eq" and choice are mapped to the ATP's equivalents *) -local - val choice_const = (fst o dest_Const o HOLogic.choice_const) dummyT - fun default c = const_prefix ^ lookup_const c -in - fun make_fixed_const _ \<^const_name>\HOL.eq\ = tptp_old_equal - | make_fixed_const (SOME (Native (Higher_Order THF_With_Choice, _, _, _, _))) c = - if c = choice_const then tptp_choice else default c - | make_fixed_const _ c = default c -end +fun make_fixed_const _ \<^const_name>\HOL.eq\ = tptp_old_equal + | make_fixed_const _ c = const_prefix ^ lookup_const c fun make_fixed_type_const c = type_const_prefix ^ lookup_const c @@ -680,33 +678,37 @@ fun native_of_string s = let + val (_, s) = + (case try (unsuffix "_arith") s of + SOME s => (true, s) + | NONE => (false, s)) + val syntax = {with_ite = true, with_let = true} val (fool, core) = (case try (unsuffix "_fool") s of - SOME s => (With_FOOL, s) + SOME s => (With_FOOL syntax, s) | NONE => (Without_FOOL, s)) - val syntax = {with_ite = (fool = With_FOOL)} in (case (core, poly) of ("native", SOME poly) => (case (poly, level) of (Mangled_Monomorphic, _) => if is_type_level_uniform level then - Native (First_Order, fool, syntax, Mangled_Monomorphic, level) + Native (First_Order, fool, Mangled_Monomorphic, level) else raise Same.SAME | (Raw_Monomorphic, _) => raise Same.SAME - | (poly, All_Types) => Native (First_Order, fool, syntax, poly, All_Types)) + | (poly, All_Types) => Native (First_Order, fool, poly, All_Types)) | ("native_higher", SOME poly) => (case (poly, level) of (_, Nonmono_Types _) => raise Same.SAME | (_, Undercover_Types) => raise Same.SAME | (Mangled_Monomorphic, _) => if is_type_level_uniform level then - Native (Higher_Order THF_With_Choice, fool, syntax, Mangled_Monomorphic, level) + Native (Higher_Order THF_With_Choice, With_FOOL syntax, Mangled_Monomorphic, level) else raise Same.SAME | (poly as Raw_Polymorphic _, All_Types) => - Native (Higher_Order THF_With_Choice, fool, syntax, poly, All_Types) + Native (Higher_Order THF_With_Choice, With_FOOL syntax, poly, All_Types) | _ => raise Same.SAME)) end @@ -752,28 +754,28 @@ fun adjust_hologic hologic (Higher_Order hologic') = Higher_Order (min_hologic hologic hologic') | adjust_hologic _ type_enc = type_enc -fun adjust_fool Without_FOOL _ = Without_FOOL - | adjust_fool _ fool = fool +fun adjust_syntax {with_ite = ite1, with_let = let1} {with_ite = ite2, with_let = let2} = + {with_ite = ite1 andalso ite2, with_let = let1 andalso let2} + +fun adjust_fool (With_FOOL syntax) (With_FOOL syntax') = With_FOOL (adjust_syntax syntax syntax') + | adjust_fool _ _ = Without_FOOL fun no_type_classes Type_Class_Polymorphic = Raw_Polymorphic With_Phantom_Type_Vars | no_type_classes poly = poly -fun adjust_type_enc (THF (fool, Polymorphic, hologic)) - (Native (order, fool', syntax, poly, level)) = - Native (adjust_hologic hologic order, adjust_fool fool fool', syntax, no_type_classes poly, - level) - | adjust_type_enc (THF (fool, Monomorphic, hologic)) (Native (order, fool', syntax, _, level)) = - Native (adjust_hologic hologic order, adjust_fool fool fool', syntax, Mangled_Monomorphic, +fun adjust_type_enc (THF (poly, syntax, hologic)) (Native (order, fool, poly', level)) = + Native (adjust_hologic hologic order, adjust_fool (With_FOOL syntax) fool, + (case poly of Polymorphic => no_type_classes poly' | Monomorphic => Mangled_Monomorphic), level) - | adjust_type_enc (TFF (fool, Monomorphic)) (Native (_, fool', syntax, _, level)) = - Native (First_Order, adjust_fool fool fool', syntax, Mangled_Monomorphic, level) - | adjust_type_enc (DFG Polymorphic) (Native (_, _, syntax, poly, level)) = - Native (First_Order, Without_FOOL, syntax, poly, level) - | adjust_type_enc (DFG Monomorphic) (Native (_, _, syntax, _, level)) = - Native (First_Order, Without_FOOL, syntax, Mangled_Monomorphic, level) - | adjust_type_enc (TFF (fool, _)) (Native (_, fool', syntax, poly, level)) = - Native (First_Order, adjust_fool fool fool', syntax, no_type_classes poly, level) - | adjust_type_enc format (Native (_, _, _, poly, level)) = + | adjust_type_enc (TFF (poly, fool)) (Native (_, fool', poly', level)) = + Native (First_Order, adjust_fool fool fool', + (case poly of Polymorphic => no_type_classes poly' | Monomorphic => Mangled_Monomorphic), + level) + | adjust_type_enc (DFG Polymorphic) (Native (_, _, poly, level)) = + Native (First_Order, Without_FOOL, poly, level) + | adjust_type_enc (DFG Monomorphic) (Native (_, _, _, level)) = + Native (First_Order, Without_FOOL, Mangled_Monomorphic, level) + | adjust_type_enc format (Native (_, _, poly, level)) = adjust_type_enc format (Guards (no_type_classes poly, level)) | adjust_type_enc CNF_UEQ (type_enc as Guards stuff) = (if is_type_enc_sound type_enc then Tags else Guards) stuff @@ -949,8 +951,8 @@ T_args else (case type_enc of - Native (_, _, _, Raw_Polymorphic _, _) => T_args - | Native (_, _, _, Type_Class_Polymorphic, _) => T_args + Native (_, _, Raw_Polymorphic _, _) => T_args + | Native (_, _, Type_Class_Polymorphic, _) => T_args | _ => let fun gen_type_args _ _ [] = [] @@ -1086,7 +1088,7 @@ val tm_args = tm_args @ (case type_enc of - Native (_, _, _, Raw_Polymorphic Without_Phantom_Type_Vars, _) => + Native (_, _, Raw_Polymorphic Without_Phantom_Type_Vars, _) => [ATerm ((TYPE_name, ty_args), [])] | _ => []) in AAtom (ATerm ((cl, ty_args), tm_args)) end @@ -1187,10 +1189,10 @@ val unmangled_invert_const = invert_const o hd o unmangled_const_name -fun vars_of_iterm vars (IConst ((s, _), _, _)) = insert (op =) s vars - | vars_of_iterm vars (IVar ((s, _), _)) = insert (op =) s vars - | vars_of_iterm vars (IApp (tm1, tm2)) = union (op =) (vars_of_iterm vars tm1) (vars_of_iterm vars tm2) - | vars_of_iterm vars (IAbs (_, tm)) = vars_of_iterm vars tm +fun vars_of_iterm (IConst ((s, _), _, _)) = [s] + | vars_of_iterm (IVar ((s, _), _)) = [s] + | vars_of_iterm (IApp (tm1, tm2)) = union (op =) (vars_of_iterm tm1) (vars_of_iterm tm2) + | vars_of_iterm (IAbs (((s, _), _), tm)) = insert (op =) s (vars_of_iterm tm) fun generate_unique_name gen unique n = let val x = gen n in @@ -1201,7 +1203,7 @@ | eta_expand_quantifier_body tm = let (* We accumulate all variables because E 2.5 does not support variable shadowing. *) - val vars = vars_of_iterm [] tm + val vars = vars_of_iterm tm val x = generate_unique_name (fn n => "X" ^ (if n = 0 then "" else string_of_int n)) (fn name => not (exists (equal name) vars)) 0 @@ -1215,6 +1217,8 @@ let val is_fool = is_type_enc_fool type_enc val has_ite = has_type_enc_ite type_enc + val has_let = has_type_enc_let type_enc + val has_choice = has_type_enc_choice type_enc fun tweak_ho_quant ho_quant (T as Type (_, [p_T as Type (_, [x_T, _]), _])) [] = (* Eta-expand "!!" and "??", to work around LEO-II, Leo-III, and Satallax parser limitations. This works in conjunction with special code in "ATP_Problem" that uses the @@ -1258,7 +1262,7 @@ else tm2' | IConst ((s, _), _, _) => - if s = tptp_ho_forall orelse s = tptp_ho_exists then + if s = tptp_ho_forall orelse s = tptp_ho_exists orelse s = tptp_choice then eta_expand_quantifier_body tm2' else tm2' @@ -1270,7 +1274,7 @@ let val argc = length args in if has_ite andalso s = "c_If" andalso argc >= 3 then IConst (`I tptp_ite, T, []) - else if is_fool andalso s = "c_Let" andalso argc >= 2 then + else if has_let andalso s = "c_Let" andalso argc >= 2 then IConst (`I tptp_let, T, []) else (case proxify_const s of @@ -1279,6 +1283,7 @@ fun plain_const () = IConst (name, T, []) fun proxy_const () = IConst (proxy_base |>> prefix const_prefix, T, T_args) fun handle_fool card x = if card = argc then x else proxy_const () + fun handle_min_card card x = if argc < card then proxy_const () else x in if top_level then (case s of @@ -1295,6 +1300,11 @@ | "c_implies" => IConst (`I tptp_implies, T, []) | "c_All" => tweak_ho_quant tptp_ho_forall T args | "c_Ex" => tweak_ho_quant tptp_ho_exists T args + | "c_Choice" => + if has_choice then + handle_min_card 1 (IConst (`I tptp_choice, T, [])) + else + proxy_const () | s => if is_tptp_equal s then tweak_ho_equal T argc @@ -1310,6 +1320,7 @@ | "c_implies" => handle_fool 2 (IConst (`I tptp_implies, T, [])) | "c_All" => handle_fool 1 (tweak_ho_quant tptp_ho_forall T args) | "c_Ex" => handle_fool 1 (tweak_ho_quant tptp_ho_exists T args) + | "c_Choice" => proxy_const () | s => if is_tptp_equal s then handle_fool 2 (IConst (`I tptp_equal, T, [])) @@ -1610,7 +1621,8 @@ fun consider_var_ary const_T var_T max_ary = let fun iter ary T = - if ary = max_ary orelse type_instance thy var_T T orelse type_instance thy T var_T then + if ary = max_ary orelse type_instance thy var_T T orelse type_instance thy T var_T orelse + not (can dest_funT T) then ary else iter (ary + 1) (range_type T) @@ -1850,9 +1862,26 @@ (* Partial characterization of "fAll" and "fEx". A complete characterization would require the axiom of choice for replay with Metis. *) (("fAll", false), [(General, @{lemma "\ fAll P \ P x" by (auto simp: fAll_def)})]), - (("fEx", false), [(General, @{lemma "\ P x \ fEx P" by (auto simp: fEx_def)})])] + (("fEx", false), [(General, @{lemma "\ P x \ fEx P" by (auto simp: fEx_def)})]), + (("fChoice", true), [(General, @{thm fChoice_iff_Ex})])] |> map (apsnd (map (apsnd zero_var_indexes))) +val () = + let + fun is_skolemizable \<^Const_>\Ex _ for \Abs _\\ = true + | is_skolemizable _ = false + + fun check_no_skolemizable_thm thm = + if Term.exists_subterm is_skolemizable (Thm.full_prop_of thm) then + error "Theorems of the helper table cannot contain skolemizable terms because they don't \ + \get skolimized in metis." + else + () + in + helper_table true + |> List.app (fn (_, thms) => List.app (check_no_skolemizable_thm o snd) thms) + end + fun completish_helper_table with_combs = helper_table with_combs @ [((predicator_name, true), @@ -1881,10 +1910,10 @@ |> class_membs_of_types type_enc add_sorts_on_tvar |> map (class_atom type_enc))) #> (case type_enc of - Native (_, _, _, Type_Class_Polymorphic, _) => + Native (_, _, Type_Class_Polymorphic, _) => mk_atyquant AForall (map (fn TVar (z as (_, S)) => (AType ((tvar_name z, []), []), map (`make_class) (normalize_classes S) )) Ts) - | Native (_, _, _, Raw_Polymorphic _, _) => + | Native (_, _, Raw_Polymorphic _, _) => mk_atyquant AForall (map (fn TVar (z as _) => (AType ((tvar_name z, []), []), [])) Ts) | _ => mk_aquant AForall (map (fn TVar z => (tvar_name z, NONE)) Ts))) @@ -1940,10 +1969,11 @@ in fold (fn ((helper_s, needs_sound), ths) => let - fun map_syntax_of_type_enc f (Native (order, fool, syntax, polymorphism, type_level)) = - Native (order, fool, f syntax, polymorphism, type_level) - | map_syntax_of_type_enc _ type_enc = type_enc - val remove_ite_syntax = map_syntax_of_type_enc (K {with_ite = false}) + fun map_syntax f (Native (order, With_FOOL syntax, polymorphism, type_level)) = + Native (order, With_FOOL (f syntax), polymorphism, type_level) + | map_syntax _ type_enc = type_enc + val remove_ite_syntax = map_syntax + (fn {with_let, ...} => {with_ite = false, with_let = with_let}) in if (needs_sound andalso not sound) orelse (helper_s <> unmangled_s andalso @@ -2313,7 +2343,7 @@ fun decl_lines_of_classes type_enc = (case type_enc of - Native (_, _, _, Raw_Polymorphic phantoms, _) => map (decl_line_of_class phantoms) + Native (_, _, Raw_Polymorphic phantoms, _) => map (decl_line_of_class phantoms) | _ => K []) fun sym_decl_table_of_facts thy type_enc sym_tab (conjs, facts, extra_tms) = @@ -2375,7 +2405,7 @@ ? (fold (fold add_fact_syms) [conjs, facts] #> fold add_iterm_syms extra_tms #> (case type_enc of - Native (_, _, _, Raw_Polymorphic phantoms, _) => + Native (_, _, Raw_Polymorphic phantoms, _) => phantoms = Without_Phantom_Type_Vars ? add_TYPE_const () | Native _ => I | _ => fold add_undefined_const (var_types ()))) @@ -2815,9 +2845,8 @@ if lam_trans = keep_lamsN andalso not (is_type_enc_full_higher_order type_enc) then liftingN else lam_trans val simp_options = - let val simp = not (is_type_enc_fool type_enc) in - {if_simps = simp, let_simps = simp} - end + {if_simps = not (has_type_enc_ite type_enc), + let_simps = not (has_type_enc_let type_enc)} val (classes, conjs, facts, subclass_pairs, tcon_clauses, lifted) = translate_formulas simp_options ctxt prem_role format type_enc lam_trans presimp hyp_ts concl_t facts diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Tools/Metis/metis_generate.ML --- a/src/HOL/Tools/Metis/metis_generate.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Tools/Metis/metis_generate.ML Sun Dec 12 11:18:42 2021 +0100 @@ -206,12 +206,9 @@ |> Monomorph.monomorph atp_schematic_consts_of ctxt |> chop (length conj_clauses) |> apply2 (maps (map (zero_var_indexes o snd))) - val num_conjs = length conj_clauses (* Pretend every clause is a "simp" rule, to guide the term ordering. *) val clauses = - map2 (fn j => pair (Int.toString j, (Local, Simp))) (0 upto num_conjs - 1) conj_clauses @ - map2 (fn j => pair (Int.toString (num_conjs + j), (Local, Simp))) - (0 upto length fact_clauses - 1) fact_clauses + map_index (apfst (fn j => (Int.toString j, (Local, Simp)))) (conj_clauses @ fact_clauses) val (old_skolems, props) = fold_rev (fn (name, th) => fn (old_skolems, props) => th |> Thm.prop_of |> Logic.strip_imp_concl diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Tools/Metis/metis_reconstruct.ML --- a/src/HOL/Tools/Metis/metis_reconstruct.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Tools/Metis/metis_reconstruct.ML Sun Dec 12 11:18:42 2021 +0100 @@ -682,10 +682,10 @@ SOME ((ax_no, cluster_no), clusters_in_term true t |> cluster_no > 1 ? cons (ax_no, cluster_no - 1)) | _ => raise TERM ("discharge_skolem_premises: Expected Var", [var])) - val prems = Logic.strip_imp_prems (Thm.prop_of prems_imp_false) - val substs = prems |> map2 subst_info_of_prem (1 upto length prems) - |> sort (int_ord o apply2 fst) + val substs = + map_index (fn (i, prem) => subst_info_of_prem (i + 1) prem) prems + |> sort (int_ord o apply2 fst) val depss = maps (map_filter deps_of_term_subst o snd o snd o snd) substs val clusters = maps (op ::) depss val ordered_clusters = @@ -702,7 +702,7 @@ (Integer.add 1)) substs |> Int_Tysubst_Table.dest val needed_axiom_props = - 0 upto length axioms - 1 ~~ axioms + map_index I axioms |> map_filter (fn (_, NONE) => NONE | (ax_no, SOME (_, t)) => if exists (fn ((ax_no', _), n) => diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Tools/Metis/metis_tactic.ML --- a/src/HOL/Tools/Metis/metis_tactic.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Tools/Metis/metis_tactic.ML Sun Dec 12 11:18:42 2021 +0100 @@ -151,14 +151,14 @@ val new_skolem = Config.get ctxt new_skolem orelse null (Meson.choice_theorems thy) val do_lams = lam_trans = liftingN ? introduce_lam_wrappers ctxt val th_cls_pairs = - map2 (fn j => fn th => + map_index (fn (j, th) => (Thm.get_name_hint th, th |> Drule.eta_contraction_rule |> Meson_Clausify.cnf_axiom Meson.simp_options_all_true ctxt new_skolem (lam_trans = combsN) j ||> map do_lams)) - (0 upto length ths0 - 1) ths0 + ths0 val ths = maps (snd o snd) th_cls_pairs val dischargers = map (fst o snd) th_cls_pairs val cls = cls |> map (Drule.eta_contraction_rule #> do_lams) diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Tools/Mirabelle/mirabelle_sledgehammer.ML --- a/src/HOL/Tools/Mirabelle/mirabelle_sledgehammer.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Tools/Mirabelle/mirabelle_sledgehammer.ML Sun Dec 12 11:18:42 2021 +0100 @@ -3,7 +3,7 @@ Author: Sascha Boehme, TU Munich Author: Tobias Nipkow, TU Munich Author: Makarius - Author: Martin Desharnais, UniBw Munich + Author: Martin Desharnais, UniBw Munich, MPI-INF Saarbruecken Mirabelle action: "sledgehammer". *) @@ -21,48 +21,16 @@ val check_trivialK = "check_trivial" (*=BOOL: check if goals are "trivial"*) val e_selection_heuristicK = "e_selection_heuristic" (*=STRING: E clause selection heuristic*) -val fact_filterK = "fact_filter" (*=STRING: fact filter*) val force_sosK = "force_sos" (*=BOOL: use set-of-support (in Vampire)*) -val isar_proofsK = "isar_proofs" (*=SMART_BOOL: enable Isar proof generation*) val keepK = "keep" (*=BOOL: keep temporary files created by sledgehammer*) -val lam_transK = "lam_trans" (*=STRING: lambda translation scheme*) -val max_factsK = "max_facts" (*=NUM: max. relevant clauses to use*) -val max_mono_itersK = "max_mono_iters" (*=NUM: max. iterations of monomorphiser*) -val max_new_mono_instancesK = "max_new_mono_instances" (*=NUM: max. new monomorphic instances*) -val max_relevantK = "max_relevant" (*=NUM: max. relevant clauses to use*) -val minimizeK = "minimize" (*=BOOL: instruct sledgehammer to run its minimizer*) -val preplay_timeoutK = "preplay_timeout" (*=TIME: timeout for finding reconstructed proof*) val proof_methodK = "proof_method" (*=STRING: how to reconstruct proofs (e.g. using metis)*) val proverK = "prover" (*=STRING: name of the external prover to call*) -val prover_timeoutK = "prover_timeout" (*=TIME: timeout for invoked ATP (seconds of process time)*) -val sliceK = "slice" (*=BOOL: allow sledgehammer-level strategy-scheduling*) -val smt_proofsK = "smt_proofs" (*=BOOL: enable SMT proof generation*) -val strictK = "strict" (*=BOOL: run in strict mode*) val term_orderK = "term_order" (*=STRING: term order (in E)*) -val type_encK = "type_enc" (*=STRING: type encoding scheme*) -val uncurried_aliasesK = "uncurried_aliases" (*=SMART_BOOL: use fresh function names to alias curried applications*) -(*FIXME sensible to have Mirabelle-level Sledgehammer defaults?*) (*defaults used in this Mirabelle action*) -val preplay_timeout_default = "1" -val lam_trans_default = "smart" -val uncurried_aliases_default = "smart" -val fact_filter_default = "smart" -val type_enc_default = "smart" -val strict_default = "false" -val max_facts_default = "smart" -val slice_default = "true" val check_trivial_default = false val keep_default = false -(*If a key is present in args then augment a list with its pair*) -(*This is used to avoid fixing default values at the Mirabelle level, and - instead use the default values of the tool (Sledgehammer in this case).*) -fun available_parameter args key label list = - let - val value = AList.lookup (op =) args key - in if is_some value then (label, the value) :: list else list end - datatype sh_data = ShData of { calls: int, success: int, @@ -336,23 +304,22 @@ SH_FAIL of int * int | SH_ERROR -fun run_sh prover_name fact_filter type_enc strict max_facts slice - lam_trans uncurried_aliases e_selection_heuristic term_order force_sos - hard_timeout timeout preplay_timeout isar_proofsLST smt_proofsLST - minimizeLST max_new_mono_instancesLST max_mono_itersLST dir pos st = +fun run_sh (params as {max_facts, minimize, preplay_timeout, ...}) prover_name e_selection_heuristic + term_order force_sos hard_timeout dir pos st = let val thy = Proof.theory_of st val {context = ctxt, facts = chained_ths, goal} = Proof.goal st val i = 1 fun set_file_name (SOME dir) = - Config.put Sledgehammer_Prover_ATP.atp_dest_dir dir - #> Config.put Sledgehammer_Prover_ATP.atp_problem_prefix - ("prob_" ^ + let + val filename = "prob_" ^ StringCvt.padLeft #"0" 5 (str0 (Position.line_of pos)) ^ "_" ^ - StringCvt.padLeft #"0" 6 (str0 (Position.offset_of pos)) ^ "__") - #> Config.put SMT_Config.debug_files - (dir ^ "/" ^ Name.desymbolize (SOME false) (ATP_Util.timestamp ()) ^ "_" - ^ serial_string ()) + StringCvt.padLeft #"0" 6 (str0 (Position.offset_of pos)) + in + Config.put Sledgehammer_Prover_ATP.atp_dest_dir dir + #> Config.put Sledgehammer_Prover_ATP.atp_problem_prefix (filename ^ "__") + #> Config.put SMT_Config.debug_files (dir ^ "/" ^ filename ^ "__" ^ serial_string ()) + end | set_file_name NONE = I val st' = st @@ -364,30 +331,13 @@ term_order |> the_default I) #> (Option.map (Config.put Sledgehammer_ATP_Systems.force_sos) force_sos |> the_default I)) - val params as {max_facts, minimize, preplay_timeout, ...} = - Sledgehammer_Commands.default_params thy - ([(* ("verbose", "true"), *) - ("fact_filter", fact_filter), - ("type_enc", type_enc), - ("strict", strict), - ("lam_trans", lam_trans |> the_default lam_trans_default), - ("uncurried_aliases", uncurried_aliases |> the_default uncurried_aliases_default), - ("max_facts", max_facts), - ("slice", slice), - ("timeout", string_of_int timeout), - ("preplay_timeout", preplay_timeout)] - |> isar_proofsLST - |> smt_proofsLST - |> minimizeLST (*don't confuse the two minimization flags*) - |> max_new_mono_instancesLST - |> max_mono_itersLST) val default_max_facts = Sledgehammer_Prover_Minimize.default_max_facts_of_prover ctxt prover_name val (_, hyp_ts, concl_t) = ATP_Util.strip_subgoal goal i ctxt val time_limit = (case hard_timeout of NONE => I - | SOME secs => Timeout.apply (Time.fromSeconds secs)) + | SOME t => Timeout.apply t) fun failed failure = ({outcome = SOME failure, used_facts = [], used_from = [], preferred_methss = (Sledgehammer_Proof_Methods.Auto_Method, []), run_time = Time.zeroTime, @@ -431,33 +381,17 @@ in -fun run_sledgehammer change_data thy_index trivial output_dir args proof_method named_thms pos st = +fun run_sledgehammer change_data (params as {provers, timeout, ...}) output_dir + e_selection_heuristic term_order force_sos keep proof_method_from_msg thy_index trivial + proof_method named_thms pos st = let val thy = Proof.theory_of st val thy_name = Context.theory_name thy val triv_str = if trivial then "[T] " else "" val _ = change_data inc_sh_calls val _ = if trivial then () else change_data inc_sh_nontriv_calls - val prover_name = get_prover_name thy args - val fact_filter = AList.lookup (op =) args fact_filterK |> the_default fact_filter_default - val type_enc = AList.lookup (op =) args type_encK |> the_default type_enc_default - val strict = AList.lookup (op =) args strictK |> the_default strict_default - val max_facts = - (case AList.lookup (op =) args max_factsK of - SOME max => max - | NONE => - (case AList.lookup (op =) args max_relevantK of - SOME max => max - | NONE => max_facts_default)) - val slice = AList.lookup (op =) args sliceK |> the_default slice_default - val lam_trans = AList.lookup (op =) args lam_transK - val uncurried_aliases = AList.lookup (op =) args uncurried_aliasesK - val e_selection_heuristic = AList.lookup (op =) args e_selection_heuristicK - val term_order = AList.lookup (op =) args term_orderK - val force_sos = AList.lookup (op =) args force_sosK - |> Option.map (curry (op <>) "false") val keep_dir = - if Mirabelle.get_bool_argument args (keepK, keep_default) then + if keep then let val subdir = StringCvt.padLeft #"0" 4 (string_of_int thy_index) ^ "_" ^ thy_name in Path.append output_dir (Path.basic subdir) |> Isabelle_System.make_directory @@ -466,23 +400,13 @@ end else NONE - val timeout = Mirabelle.get_int_argument args (prover_timeoutK, 30) (* always use a hard timeout, but give some slack so that the automatic minimizer has a chance to do its magic *) - val preplay_timeout = AList.lookup (op =) args preplay_timeoutK - |> the_default preplay_timeout_default - val isar_proofsLST = available_parameter args isar_proofsK "isar_proofs" - val smt_proofsLST = available_parameter args smt_proofsK "smt_proofs" - val minimizeLST = available_parameter args minimizeK "minimize" - val max_new_mono_instancesLST = - available_parameter args max_new_mono_instancesK max_new_mono_instancesK - val max_mono_itersLST = available_parameter args max_mono_itersK max_mono_itersK - val hard_timeout = SOME (4 * timeout) + val hard_timeout = SOME (Time.scale 4.0 timeout) + val prover_name = hd provers val (msg, result) = - run_sh prover_name fact_filter type_enc strict max_facts slice lam_trans - uncurried_aliases e_selection_heuristic term_order force_sos - hard_timeout timeout preplay_timeout isar_proofsLST smt_proofsLST - minimizeLST max_new_mono_instancesLST max_mono_itersLST keep_dir pos st + run_sh params prover_name e_selection_heuristic term_order force_sos hard_timeout keep_dir pos + st in (case result of SH_OK (time_isa, time_prover, names) => @@ -498,7 +422,7 @@ change_data (inc_sh_max_lems (length names)); change_data (inc_sh_time_isa time_isa); change_data (inc_sh_time_prover time_prover); - proof_method := proof_method_from_msg args msg; + proof_method := proof_method_from_msg msg; named_thms := SOME (map_filter get_thms names); triv_str ^ "succeeded (" ^ string_of_int time_isa ^ "+" ^ string_of_int time_prover ^ ") [" ^ prover_name ^ "]:\n" ^ msg @@ -592,8 +516,22 @@ fun make_action ({arguments, timeout, output_dir, ...} : Mirabelle.action_context) = let + (* Parse Mirabelle-specific parameters *) val check_trivial = Mirabelle.get_bool_argument arguments (check_trivialK, check_trivial_default) + val keep = Mirabelle.get_bool_argument arguments (keepK, keep_default) + val e_selection_heuristic = AList.lookup (op =) arguments e_selection_heuristicK + val term_order = AList.lookup (op =) arguments term_orderK + val force_sos = AList.lookup (op =) arguments force_sosK + |> Option.map (curry (op <>) "false") + val proof_method_from_msg = proof_method_from_msg arguments + + (* Parse Sledgehammer parameters *) + val params = Sledgehammer_Commands.default_params \<^theory> arguments + |> (fn (params as {provers, ...}) => + (case provers of + prover :: _ => Sledgehammer_Prover.set_params_provers params [prover] + | _ => error "sledgehammer action requires one prover")) val data = Synchronized.var "Mirabelle_Sledgehammer.data" empty_data val change_data = Synchronized.change data @@ -611,8 +549,8 @@ check_trivial andalso Try0.try0 (SOME try_timeout) ([], [], [], []) pre handle Timeout.TIMEOUT _ => false val log1 = - run_sledgehammer change_data theory_index trivial output_dir arguments meth named_thms - pos pre + run_sledgehammer change_data params output_dir e_selection_heuristic term_order + force_sos keep proof_method_from_msg theory_index trivial meth named_thms pos pre val log2 = (case !named_thms of SOME thms => @@ -627,4 +565,4 @@ val () = Mirabelle.register_action "sledgehammer" make_action -end +end \ No newline at end of file diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Tools/Sledgehammer/sledgehammer_atp_systems.ML --- a/src/HOL/Tools/Sledgehammer/sledgehammer_atp_systems.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Tools/Sledgehammer/sledgehammer_atp_systems.ML Sun Dec 12 11:18:42 2021 +0100 @@ -67,6 +67,13 @@ (* ATP configuration *) +val TF0 = TFF (Monomorphic, Without_FOOL) +val TF1 = TFF (Polymorphic, Without_FOOL) +val TX0 = TFF (Monomorphic, With_FOOL {with_ite = true, with_let = true}) +val TX1 = TFF (Polymorphic, With_FOOL {with_ite = true, with_let = true}) +val TH0 = THF (Monomorphic, {with_ite = true, with_let = true}, THF_With_Choice) +val TH1 = THF (Polymorphic, {with_ite = true, with_let = true}, THF_With_Choice) + val default_max_mono_iters = 3 (* FUDGE *) val default_max_new_mono_instances = 100 (* FUDGE *) @@ -160,7 +167,6 @@ val term_order = Attrib.setup_config_string \<^binding>\atp_term_order\ (K smartN) - (* agsyHOL *) val agsyhol_config : atp_config = @@ -172,7 +178,7 @@ prem_role = Hypothesis, best_slices = (* FUDGE *) - K [(1.0, (((60, ""), THF (Without_FOOL, Monomorphic, THF_Without_Choice), "mono_native_higher", keep_lamsN, false), ""))], + K [(1.0, (((60, ""), THF (Monomorphic, {with_ite = false, with_let = false}, THF_Without_Choice), "mono_native_higher", keep_lamsN, false), ""))], best_max_mono_iters = default_max_mono_iters - 1 (* FUDGE *), best_max_new_mono_instances = default_max_new_mono_instances} @@ -194,7 +200,7 @@ prem_role = Hypothesis, best_slices = fn _ => (* FUDGE *) - [(1.0, (((100, ""), TFF (Without_FOOL, Polymorphic), "poly_native", liftingN, false), ""))], + [(1.0, (((100, ""), TF1, "poly_native", liftingN, false), ""))], best_max_mono_iters = default_max_mono_iters, best_max_new_mono_instances = default_max_new_mono_instances} @@ -294,11 +300,11 @@ val heuristic = Config.get ctxt e_selection_heuristic val (format, enc, main_lam_trans) = if string_ord (getenv "E_VERSION", "2.7") <> LESS then - (THF (With_FOOL, Monomorphic, THF_Without_Choice), "mono_native_higher_fool", keep_lamsN) + (THF (Monomorphic, {with_ite = true, with_let = false}, THF_Without_Choice), "mono_native_higher", keep_lamsN) else if string_ord (getenv "E_VERSION", "2.6") <> LESS then - (THF (Without_FOOL, Monomorphic, THF_Without_Choice), "mono_native_higher", keep_lamsN) + (THF (Monomorphic, {with_ite = true, with_let = false}, THF_Without_Choice), "mono_native_higher", keep_lamsN) else - (THF (Without_FOOL, Monomorphic, THF_Lambda_Free), "mono_native_higher", combsN) + (THF (Monomorphic, {with_ite = false, with_let = false}, THF_Lambda_Free), "mono_native_higher", combsN) in (* FUDGE *) if heuristic = e_smartN then @@ -357,7 +363,7 @@ prem_role = Hypothesis, best_slices = (* FUDGE *) - K [(1.0, (((40, ""), THF (Without_FOOL, Monomorphic, THF_Without_Choice), "mono_native_higher", keep_lamsN, false), ""))], + K [(1.0, (((40, ""), THF (Monomorphic, {with_ite = false, with_let = false}, THF_Without_Choice), "mono_native_higher", keep_lamsN, false), ""))], best_max_mono_iters = default_max_mono_iters - 1 (* FUDGE *), best_max_new_mono_instances = default_max_new_mono_instances} @@ -378,7 +384,7 @@ prem_role = Hypothesis, best_slices = (* FUDGE *) - K [(1.0, (((150, ""), THF (Without_FOOL, Polymorphic, THF_Without_Choice), "mono_native_higher", keep_lamsN, false), ""))], + K [(1.0, (((150, ""), THF (Polymorphic, {with_ite = true, with_let = true}, THF_Without_Choice), "mono_native_higher", keep_lamsN, false), ""))], best_max_mono_iters = default_max_mono_iters - 1 (* FUDGE *), best_max_new_mono_instances = default_max_new_mono_instances} @@ -401,7 +407,7 @@ prem_role = Hypothesis, best_slices = (* FUDGE *) - K [(1.0, (((150, ""), THF (Without_FOOL, Monomorphic, THF_Without_Choice), "mono_native_higher", keep_lamsN, false), ""))], + K [(1.0, (((150, ""), THF (Monomorphic, {with_ite = false, with_let = false}, THF_Without_Choice), "mono_native_higher", keep_lamsN, false), ""))], best_max_mono_iters = default_max_mono_iters - 1 (* FUDGE *), best_max_new_mono_instances = default_max_new_mono_instances} @@ -465,35 +471,31 @@ " --proof_extra free --forced_options avatar=off:equality_proxy=off:general_splitting=off:inequality_splitting=0:naming=0" val vampire_config : atp_config = - let - val format = TFF (With_FOOL, Polymorphic) - in - {exec = (["VAMPIRE_HOME"], ["vampire"]), - arguments = fn _ => fn full_proofs => fn sos => fn timeout => fn problem => fn _ => - [vampire_basic_options ^ (if full_proofs then " " ^ vampire_full_proof_options else "") ^ - " -t " ^ string_of_int (to_secs 1 timeout) ^ " --input_file " ^ File.bash_path problem - |> sos = sosN ? prefix "--sos on "], - proof_delims = - [("=========== Refutation ==========", - "======= End of refutation =======")] @ - tstp_proof_delims, - known_failures = - [(GaveUp, "UNPROVABLE"), - (GaveUp, "CANNOT PROVE"), - (Unprovable, "Satisfiability detected"), - (Unprovable, "Termination reason: Satisfiable"), - (Interrupted, "Aborted by signal SIGINT")] @ - known_szs_status_failures, - prem_role = Hypothesis, - best_slices = fn ctxt => - (* FUDGE *) - [(0.333, (((500, meshN), format, "mono_native_fool", combs_or_liftingN, false), sosN)), - (0.333, (((150, meshN), format, "poly_native_fool", combs_or_liftingN, false), sosN)), - (0.334, (((50, meshN), format, "mono_native_fool", combs_or_liftingN, false), no_sosN))] - |> Config.get ctxt force_sos ? (hd #> apfst (K 1.0) #> single), - best_max_mono_iters = default_max_mono_iters, - best_max_new_mono_instances = 2 * default_max_new_mono_instances (* FUDGE *)} - end + {exec = (["VAMPIRE_HOME"], ["vampire"]), + arguments = fn _ => fn full_proofs => fn sos => fn timeout => fn problem => fn _ => + [vampire_basic_options ^ (if full_proofs then " " ^ vampire_full_proof_options else "") ^ + " -t " ^ string_of_int (to_secs 1 timeout) ^ " --input_file " ^ File.bash_path problem + |> sos = sosN ? prefix "--sos on "], + proof_delims = + [("=========== Refutation ==========", + "======= End of refutation =======")] @ + tstp_proof_delims, + known_failures = + [(GaveUp, "UNPROVABLE"), + (GaveUp, "CANNOT PROVE"), + (Unprovable, "Satisfiability detected"), + (Unprovable, "Termination reason: Satisfiable"), + (Interrupted, "Aborted by signal SIGINT")] @ + known_szs_status_failures, + prem_role = Hypothesis, + best_slices = fn ctxt => + (* FUDGE *) + [(0.333, (((500, meshN), TX1, "mono_native_fool", combs_or_liftingN, false), sosN)), + (0.333, (((150, meshN), TX1, "poly_native_fool", combs_or_liftingN, false), sosN)), + (0.334, (((50, meshN), TX1, "mono_native_fool", combs_or_liftingN, false), no_sosN))] + |> Config.get ctxt force_sos ? (hd #> apfst (K 1.0) #> single), + best_max_mono_iters = default_max_mono_iters, + best_max_new_mono_instances = 2 * default_max_new_mono_instances (* FUDGE *)} val vampire = (vampireN, fn () => vampire_config) @@ -501,24 +503,20 @@ (* Z3 with TPTP syntax (half experimental, half legacy) *) val z3_tptp_config : atp_config = - let - val format = TFF (Without_FOOL, Monomorphic) - in - {exec = (["Z3_TPTP_HOME"], ["z3_tptp"]), - arguments = fn _ => fn _ => fn _ => fn timeout => fn problem => fn _ => - ["-proof -t:" ^ string_of_int (to_secs 1 timeout) ^ " -file:" ^ File.bash_path problem], - proof_delims = [("SZS status Theorem", "")], - known_failures = known_szs_status_failures, - prem_role = Hypothesis, - best_slices = - (* FUDGE *) - K [(0.5, (((250, meshN), format, "mono_native", combsN, false), "")), - (0.25, (((125, mepoN), format, "mono_native", combsN, false), "")), - (0.125, (((62, mashN), format, "mono_native", combsN, false), "")), - (0.125, (((31, meshN), format, "mono_native", combsN, false), ""))], - best_max_mono_iters = default_max_mono_iters, - best_max_new_mono_instances = 2 * default_max_new_mono_instances (* FUDGE *)} - end + {exec = (["Z3_TPTP_HOME"], ["z3_tptp"]), + arguments = fn _ => fn _ => fn _ => fn timeout => fn problem => fn _ => + ["-proof -t:" ^ string_of_int (to_secs 1 timeout) ^ " -file:" ^ File.bash_path problem], + proof_delims = [("SZS status Theorem", "")], + known_failures = known_szs_status_failures, + prem_role = Hypothesis, + best_slices = + (* FUDGE *) + K [(0.5, (((250, meshN), TF0, "mono_native", combsN, false), "")), + (0.25, (((125, mepoN), TF0, "mono_native", combsN, false), "")), + (0.125, (((62, mashN), TF0, "mono_native", combsN, false), "")), + (0.125, (((31, meshN), TF0, "mono_native", combsN, false), ""))], + best_max_mono_iters = default_max_mono_iters, + best_max_new_mono_instances = 2 * default_max_new_mono_instances (* FUDGE *)} val z3_tptp = (z3_tptpN, fn () => z3_tptp_config) @@ -527,8 +525,9 @@ val zipperposition_config : atp_config = let - val format = THF (Without_FOOL, Polymorphic, THF_Without_Choice) - val enc = ((512, "meshN"), format, "mono_native_higher", keep_lamsN, false) + val format = + THF (Polymorphic, {with_ite = true, with_let = false}, THF_Without_Choice) + val enc = ((512, "meshN"), format, "mono_native_higher_fool", keep_lamsN, false) in {exec = (["ZIPPERPOSITION_HOME"], ["zipperposition"]), arguments = fn _ => fn _ => fn extra_options => fn timeout => fn problem => fn _ => @@ -627,26 +626,26 @@ val remote_agsyhol = remotify_atp agsyhol "agsyHOL" ["1.0", "1"] - (K (((60, ""), THF (Without_FOOL, Monomorphic, THF_Without_Choice), "mono_native_higher", keep_lamsN, false), "") (* FUDGE *)) + (K (((60, ""), THF (Monomorphic, {with_ite = false, with_let = false}, THF_Without_Choice), "mono_native_higher", keep_lamsN, false), "") (* FUDGE *)) val remote_alt_ergo = remotify_atp alt_ergo "Alt-Ergo" ["0.95.2"] - (K (((250, ""), TFF (Without_FOOL, Polymorphic), "poly_native", keep_lamsN, false), "") (* FUDGE *)) + (K (((250, ""), TF1, "poly_native", keep_lamsN, false), "") (* FUDGE *)) val remote_e = remotify_atp e "E" ["2.0", "1.9.1", "1.8"] - (K (((750, ""), TFF (Without_FOOL, Monomorphic), "mono_native", combsN, false), "") (* FUDGE *)) + (K (((750, ""), TF0, "mono_native", combsN, false), "") (* FUDGE *)) val remote_iprover = remotify_atp iprover "iProver" ["0.99"] (K (((150, ""), FOF, "mono_guards??", liftingN, false), "") (* FUDGE *)) val remote_leo2 = remotify_atp leo2 "LEO-II" ["1.5.0", "1.4", "1.3", "1.2", "1"] - (K (((40, ""), THF (Without_FOOL, Monomorphic, THF_Without_Choice), "mono_native_higher", liftingN, false), "") (* FUDGE *)) + (K (((40, ""), THF (Monomorphic, {with_ite = false, with_let = false}, THF_Without_Choice), "mono_native_higher", liftingN, false), "") (* FUDGE *)) val remote_leo3 = remotify_atp leo3 "Leo-III" ["1.1"] - (K (((150, ""), THF (Without_FOOL, Polymorphic, THF_Without_Choice), "poly_native_higher", keep_lamsN, false), "") (* FUDGE *)) + (K (((150, ""), THF (Polymorphic, {with_ite = false, with_let = false}, THF_Without_Choice), "poly_native_higher", keep_lamsN, false), "") (* FUDGE *)) val remote_waldmeister = gen_remote_waldmeister waldmeisterN "raw_mono_tags??" val remote_zipperposition = remotify_atp zipperposition "Zipperpin" ["2.1", "2.0"] - (K (((512, ""), THF (Without_FOOL, Monomorphic, THF_Without_Choice), "mono_native_higher", keep_lamsN, false), "") (* FUDGE *)) + (K (((512, ""), THF (Monomorphic, {with_ite = false, with_let = false}, THF_Without_Choice), "mono_native_higher", keep_lamsN, false), "") (* FUDGE *)) (* Dummy prover *) @@ -664,19 +663,26 @@ best_max_mono_iters = default_max_mono_iters, best_max_new_mono_instances = default_max_new_mono_instances} +val dummy_fof = + let + val config = dummy_config Hypothesis FOF "mono_guards??" false + in (dummy_fofN, fn () => config) end -val dummy_fof_format = FOF -val dummy_fof_config = dummy_config Hypothesis dummy_fof_format "mono_guards??" false -val dummy_fof = (dummy_fofN, fn () => dummy_fof_config) +val dummy_tfx = + let + val config = dummy_config Hypothesis TX1 "poly_native_fool" false + in (dummy_tfxN, fn () => config) end -val dummy_tfx_format = TFF (With_FOOL, Polymorphic) -val dummy_tfx_config = dummy_config Hypothesis dummy_tfx_format "mono_native_fool" false -val dummy_tfx = (dummy_tfxN, fn () => dummy_tfx_config) +val dummy_thf = + let + val config = dummy_config Hypothesis TH1 "poly_native_higher" false + in (dummy_thfN, fn () => config) end -val dummy_thf_format = THF (With_FOOL, Polymorphic, THF_With_Choice) -val dummy_thf_config = dummy_config Hypothesis dummy_thf_format "mono_native_higher_fool" false -val dummy_thf = (dummy_thfN, fn () => dummy_thf_config) - +val dummy_thf_reduced = + let + val format = THF (Polymorphic, {with_ite = false, with_let = false}, THF_Without_Choice) + val config = dummy_config Hypothesis format "poly_native_higher" false + in (dummy_thfN ^ "_reduced", fn () => config) end (* Setup *) @@ -713,7 +719,7 @@ val atps = [agsyhol, alt_ergo, e, iprover, leo2, leo3, satallax, spass, vampire, z3_tptp, zipperposition, remote_agsyhol, remote_alt_ergo, remote_e, remote_iprover, remote_leo2, remote_leo3, - remote_waldmeister, remote_zipperposition, dummy_fof, dummy_tfx, dummy_thf] + remote_waldmeister, remote_zipperposition, dummy_fof, dummy_tfx, dummy_thf, dummy_thf_reduced] val _ = Theory.setup (fold add_atp atps) diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Tools/Sledgehammer/sledgehammer_prover.ML --- a/src/HOL/Tools/Sledgehammer/sledgehammer_prover.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Tools/Sledgehammer/sledgehammer_prover.ML Sun Dec 12 11:18:42 2021 +0100 @@ -47,6 +47,8 @@ preplay_timeout : Time.time, expect : string} + val set_params_provers : params -> string list -> params + type prover_problem = {comment : string, state : Proof.state, @@ -141,6 +143,33 @@ preplay_timeout : Time.time, expect : string} +fun set_params_provers params provers = + {debug = #debug params, + verbose = #verbose params, + overlord = #overlord params, + spy = #spy params, + provers = provers, + type_enc = #type_enc params, + strict = #strict params, + lam_trans = #lam_trans params, + uncurried_aliases = #uncurried_aliases params, + learn = #learn params, + fact_filter = #fact_filter params, + induction_rules = #induction_rules params, + max_facts = #max_facts params, + fact_thresholds = #fact_thresholds params, + max_mono_iters = #max_mono_iters params, + max_new_mono_instances = #max_new_mono_instances params, + isar_proofs = #isar_proofs params, + compress = #compress params, + try0 = #try0 params, + smt_proofs = #smt_proofs params, + slice = #slice params, + minimize = #minimize params, + timeout = #timeout params, + preplay_timeout = #preplay_timeout params, + expect = #expect params} + type prover_problem = {comment : string, state : Proof.state, diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Tools/Sledgehammer/sledgehammer_prover_atp.ML --- a/src/HOL/Tools/Sledgehammer/sledgehammer_prover_atp.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Tools/Sledgehammer/sledgehammer_prover_atp.ML Sun Dec 12 11:18:42 2021 +0100 @@ -151,6 +151,7 @@ val problem_file_name = Path.basic (problem_prefix ^ (if overlord then "" else serial_string ()) ^ suffix_of_mode mode ^ "_" ^ string_of_int subgoal) + |> Path.ext "p" val prob_path = if dest_dir = "" then File.tmp_path problem_file_name @@ -342,8 +343,16 @@ the proof file too. *) fun clean_up () = if dest_dir = "" then (try File.rm prob_path; ()) else () fun export (_, (output, _, _, _, _), _) = - if dest_dir = "" then () - else File.write (Path.explode (Path.implode prob_path ^ "_proof")) output + let + val make_export_path = + Path.split_ext + #> apfst (Path.explode o suffix "_proof" o Path.implode) + #> swap + #> uncurry Path.ext + in + if dest_dir = "" then () + else File.write (make_export_path prob_path) output + end val ((_, (_, pool, lifted, sym_tab)), (output, run_time, used_from, atp_proof, outcome), SOME (format, type_enc)) = diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Tools/Sledgehammer/sledgehammer_prover_smt.ML --- a/src/HOL/Tools/Sledgehammer/sledgehammer_prover_smt.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Tools/Sledgehammer/sledgehammer_prover_smt.ML Sun Dec 12 11:18:42 2021 +0100 @@ -76,11 +76,17 @@ not o exists_subtype (member (op =) [\<^typ>\nat\, \<^typ>\int\, HOLogic.realT]) fun smt_filter_loop name ({debug, overlord, max_mono_iters, max_new_mono_instances, timeout, slice, - ...} : params) state goal i = + type_enc, ...} : params) state goal i = let + val (higher_order, nat_as_int) = + (case type_enc of + SOME s => (String.isSubstring "native_higher" s, String.isSubstring "arith" s) + | NONE => (false, false)) fun repair_context ctxt = ctxt |> Context.proof_map (SMT_Config.select_solver name) |> Config.put SMT_Config.verbose debug + |> Config.put SMT_Config.higher_order higher_order + |> Config.put SMT_Config.nat_as_int nat_as_int |> (if overlord then Config.put SMT_Config.debug_files (overlord_file_location_of_prover name |> (fn (path, name) => path ^ "/" ^ name)) diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/Wellfounded.thy --- a/src/HOL/Wellfounded.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/HOL/Wellfounded.thy Sun Dec 12 11:18:42 2021 +0100 @@ -79,6 +79,9 @@ lemma (in wellorder) wf: "wf {(x, y). x < y}" unfolding wf_def by (blast intro: less_induct) +lemma (in wellorder) wfP_less[simp]: "wfP (<)" + by (simp add: wf wfP_def) + subsection \Basic Results\ diff -r 70be57333ea1 -r cdd2284c8047 src/HOL/ex/Rewrite_Examples.thy --- a/src/HOL/ex/Rewrite_Examples.thy Sun Dec 12 10:42:51 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,300 +0,0 @@ -theory Rewrite_Examples -imports Main "HOL-Library.Rewrite" -begin - -section \The rewrite Proof Method by Example\ - -(* This file is intended to give an overview over - the features of the pattern-based rewrite proof method. - - See also https://www21.in.tum.de/~noschinl/Pattern-2014/ -*) -lemma - fixes a::int and b::int and c::int - assumes "P (b + a)" - shows "P (a + b)" -by (rewrite at "a + b" add.commute) - (rule assms) - -(* Selecting a specific subterm in a large, ambiguous term. *) -lemma - fixes a b c :: int - assumes "f (a - a + (a - a)) + f ( 0 + c) = f 0 + f c" - shows "f (a - a + (a - a)) + f ((a - a) + c) = f 0 + f c" - by (rewrite in "f _ + f \ = _" diff_self) fact - -lemma - fixes a b c :: int - assumes "f (a - a + 0 ) + f ((a - a) + c) = f 0 + f c" - shows "f (a - a + (a - a)) + f ((a - a) + c) = f 0 + f c" - by (rewrite at "f (_ + \) + f _ = _" diff_self) fact - -lemma - fixes a b c :: int - assumes "f ( 0 + (a - a)) + f ((a - a) + c) = f 0 + f c" - shows "f (a - a + (a - a)) + f ((a - a) + c) = f 0 + f c" - by (rewrite in "f (\ + _) + _ = _" diff_self) fact - -lemma - fixes a b c :: int - assumes "f (a - a + 0 ) + f ((a - a) + c) = f 0 + f c" - shows "f (a - a + (a - a)) + f ((a - a) + c) = f 0 + f c" - by (rewrite in "f (_ + \) + _ = _" diff_self) fact - -lemma - fixes x y :: nat - shows"x + y > c \ y + x > c" - by (rewrite at "\ > c" add.commute) assumption - -(* We can also rewrite in the assumptions. *) -lemma - fixes x y :: nat - assumes "y + x > c \ y + x > c" - shows "x + y > c \ y + x > c" - by (rewrite in asm add.commute) fact - -lemma - fixes x y :: nat - assumes "y + x > c \ y + x > c" - shows "x + y > c \ y + x > c" - by (rewrite in "x + y > c" at asm add.commute) fact - -lemma - fixes x y :: nat - assumes "y + x > c \ y + x > c" - shows "x + y > c \ y + x > c" - by (rewrite at "\ > c" at asm add.commute) fact - -lemma - assumes "P {x::int. y + 1 = 1 + x}" - shows "P {x::int. y + 1 = x + 1}" - by (rewrite at "x+1" in "{x::int. \ }" add.commute) fact - -lemma - assumes "P {x::int. y + 1 = 1 + x}" - shows "P {x::int. y + 1 = x + 1}" - by (rewrite at "any_identifier_will_work+1" in "{any_identifier_will_work::int. \ }" add.commute) - fact - -lemma - assumes "P {(x::nat, y::nat, z). x + z * 3 = Q (\s t. s * t + y - 3)}" - shows "P {(x::nat, y::nat, z). x + z * 3 = Q (\s t. y + s * t - 3)}" - by (rewrite at "b + d * e" in "\(a, b, c). _ = Q (\d e. \)" add.commute) fact - -(* This is not limited to the first assumption *) -lemma - assumes "PROP P \ PROP Q" - shows "PROP R \ PROP P \ PROP Q" - by (rewrite at asm assms) - -lemma - assumes "PROP P \ PROP Q" - shows "PROP R \ PROP R \ PROP P \ PROP Q" - by (rewrite at asm assms) - -(* Rewriting "at asm" selects each full assumption, not any parts *) -lemma - assumes "(PROP P \ PROP Q) \ (PROP S \ PROP R)" - shows "PROP S \ (PROP P \ PROP Q) \ PROP R" - apply (rewrite at asm assms) - apply assumption - done - - - -(* Rewriting with conditional rewriting rules works just as well. *) -lemma test_theorem: - fixes x :: nat - shows "x \ y \ x \ y \ x = y" - by (rule Orderings.order_antisym) - -(* Premises of the conditional rule yield new subgoals. The - assumptions of the goal are propagated into these subgoals -*) -lemma - fixes f :: "nat \ nat" - shows "f x \ 0 \ f x \ 0 \ f x = 0" - apply (rewrite at "f x" to "0" test_theorem) - apply assumption - apply assumption - apply (rule refl) - done - -(* This holds also for rewriting in assumptions. The order of assumptions is preserved *) -lemma - assumes rewr: "PROP P \ PROP Q \ PROP R \ PROP R'" - assumes A1: "PROP S \ PROP T \ PROP U \ PROP P" - assumes A2: "PROP S \ PROP T \ PROP U \ PROP Q" - assumes C: "PROP S \ PROP R' \ PROP T \ PROP U \ PROP V" - shows "PROP S \ PROP R \ PROP T \ PROP U \ PROP V" - apply (rewrite at asm rewr) - apply (fact A1) - apply (fact A2) - apply (fact C) - done - - -(* - Instantiation. - - Since all rewriting is now done via conversions, - instantiation becomes fairly easy to do. -*) - -(* We first introduce a function f and an extended - version of f that is annotated with an invariant. *) -fun f :: "nat \ nat" where "f n = n" -definition "f_inv (I :: nat \ bool) n \ f n" - -lemma annotate_f: "f = f_inv I" - by (simp add: f_inv_def fun_eq_iff) - -(* We have a lemma with a bound variable n, and - want to add an invariant to f. *) -lemma - assumes "P (\n. f_inv (\_. True) n + 1) = x" - shows "P (\n. f n + 1) = x" - by (rewrite to "f_inv (\_. True)" annotate_f) fact - -(* We can also add an invariant that contains the variable n bound in the outer context. - For this, we need to bind this variable to an identifier. *) -lemma - assumes "P (\n. f_inv (\x. n < x + 1) n + 1) = x" - shows "P (\n. f n + 1) = x" - by (rewrite in "\n. \" to "f_inv (\x. n < x + 1)" annotate_f) fact - -(* Any identifier will work *) -lemma - assumes "P (\n. f_inv (\x. n < x + 1) n + 1) = x" - shows "P (\n. f n + 1) = x" - by (rewrite in "\abc. \" to "f_inv (\x. abc < x + 1)" annotate_f) fact - -(* The "for" keyword. *) -lemma - assumes "P (2 + 1)" - shows "\x y. P (1 + 2 :: nat)" -by (rewrite in "P (1 + 2)" at for (x) add.commute) fact - -lemma - assumes "\x y. P (y + x)" - shows "\x y. P (x + y :: nat)" -by (rewrite in "P (x + _)" at for (x y) add.commute) fact - -lemma - assumes "\x y z. y + x + z = z + y + (x::int)" - shows "\x y z. x + y + z = z + y + (x::int)" -by (rewrite at "x + y" in "x + y + z" in for (x y z) add.commute) fact - -lemma - assumes "\x y z. z + (x + y) = z + y + (x::int)" - shows "\x y z. x + y + z = z + y + (x::int)" -by (rewrite at "(_ + y) + z" in for (y z) add.commute) fact - -lemma - assumes "\x y z. x + y + z = y + z + (x::int)" - shows "\x y z. x + y + z = z + y + (x::int)" -by (rewrite at "\ + _" at "_ = \" in for () add.commute) fact - -lemma - assumes eq: "\x. P x \ g x = x" - assumes f1: "\x. Q x \ P x" - assumes f2: "\x. Q x \ x" - shows "\x. Q x \ g x" - apply (rewrite at "g x" in for (x) eq) - apply (fact f1) - apply (fact f2) - done - -(* The for keyword can be used anywhere in the pattern where there is an \-Quantifier. *) -lemma - assumes "(\(x::int). x < 1 + x)" - and "(x::int) + 1 > x" - shows "(\(x::int). x + 1 > x) \ (x::int) + 1 > x" -by (rewrite at "x + 1" in for (x) at asm add.commute) - (rule assms) - -(* The rewrite method also has an ML interface *) -lemma - assumes "\a b. P ((a + 1) * (1 + b)) " - shows "\a b :: nat. P ((a + 1) * (b + 1))" - apply (tactic \ - let - val (x, ctxt) = yield_singleton Variable.add_fixes "x" \<^context> - (* Note that the pattern order is reversed *) - val pat = [ - Rewrite.For [(x, SOME \<^Type>\nat\)], - Rewrite.In, - Rewrite.Term (\<^Const>\plus \<^Type>\nat\ for \Free (x, \<^Type>\nat\)\ \<^term>\1 :: nat\\, [])] - val to = NONE - in CCONVERSION (Rewrite.rewrite_conv ctxt (pat, to) @{thms add.commute}) 1 end - \) - apply (fact assms) - done - -lemma - assumes "Q (\b :: int. P (\a. a + b) (\a. a + b))" - shows "Q (\b :: int. P (\a. a + b) (\a. b + a))" - apply (tactic \ - let - val (x, ctxt) = yield_singleton Variable.add_fixes "x" \<^context> - val pat = [ - Rewrite.Concl, - Rewrite.In, - Rewrite.Term (Free ("Q", (\<^Type>\int\ --> TVar (("'b",0), [])) --> \<^Type>\bool\) - $ Abs ("x", \<^Type>\int\, Rewrite.mk_hole 1 (\<^Type>\int\ --> TVar (("'b",0), [])) $ Bound 0), [(x, \<^Type>\int\)]), - Rewrite.In, - Rewrite.Term (\<^Const>\plus \<^Type>\int\ for \Free (x, \<^Type>\int\)\ \Var (("c", 0), \<^Type>\int\)\\, []) - ] - val to = NONE - in CCONVERSION (Rewrite.rewrite_conv ctxt (pat, to) @{thms add.commute}) 1 end - \) - apply (fact assms) - done - -(* There is also conversion-like rewrite function: *) -ML \ - val ct = \<^cprop>\Q (\b :: int. P (\a. a + b) (\a. b + a))\ - val (x, ctxt) = yield_singleton Variable.add_fixes "x" \<^context> - val pat = [ - Rewrite.Concl, - Rewrite.In, - Rewrite.Term (Free ("Q", (\<^typ>\int\ --> TVar (("'b",0), [])) --> \<^typ>\bool\) - $ Abs ("x", \<^typ>\int\, Rewrite.mk_hole 1 (\<^typ>\int\ --> TVar (("'b",0), [])) $ Bound 0), [(x, \<^typ>\int\)]), - Rewrite.In, - Rewrite.Term (\<^Const>\plus \<^Type>\int\ for \Free (x, \<^Type>\int\)\ \Var (("c", 0), \<^Type>\int\)\\, []) - ] - val to = NONE - val th = Rewrite.rewrite_conv ctxt (pat, to) @{thms add.commute} ct -\ - -section \Regression tests\ - -ML \ - val ct = \<^cterm>\(\b :: int. (\a. b + a))\ - val (x, ctxt) = yield_singleton Variable.add_fixes "x" \<^context> - val pat = [ - Rewrite.In, - Rewrite.Term (\<^Const>\plus \<^Type>\int\ for \Var (("c", 0), \<^Type>\int\)\ \Var (("c", 0), \<^Type>\int\)\\, []) - ] - val to = NONE - val _ = - case try (Rewrite.rewrite_conv ctxt (pat, to) @{thms add.commute}) ct of - NONE => () - | _ => error "should not have matched anything" -\ - -ML \ - Rewrite.params_pconv (Conv.all_conv |> K |> K) \<^context> (Vartab.empty, []) \<^cterm>\\x. PROP A\ -\ - -lemma - assumes eq: "PROP A \ PROP B \ PROP C" - assumes f1: "PROP D \ PROP A" - assumes f2: "PROP D \ PROP C" - shows "\x. PROP D \ PROP B" - apply (rewrite eq) - apply (fact f1) - apply (fact f2) - done - -end diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Admin/build_release.scala --- a/src/Pure/Admin/build_release.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Admin/build_release.scala Sun Dec 12 11:18:42 2021 +0100 @@ -837,6 +837,9 @@ val other_isabelle = context.other_isabelle(tmp_dir) + Isabelle_System.make_directory(other_isabelle.etc) + File.write(other_isabelle.etc_settings, "ML_OPTIONS=\"--minheap 1000 --maxheap 4000\"\n") + other_isabelle.bash("bin/isabelle build -f -j " + parallel_jobs + " -o browser_info -o document=pdf -o document_variants=document:outline=/proof,/ML" + " -o system_heaps -c -a -d '~~/src/Benchmarks'", echo = true).check diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Admin/build_status.scala --- a/src/Pure/Admin/build_status.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Admin/build_status.scala Sun Dec 12 11:18:42 2021 +0100 @@ -204,7 +204,7 @@ profiles: List[Profile] = default_profiles, only_sessions: Set[String] = Set.empty, ml_statistics: Boolean = false, - ml_statistics_domain: String => Boolean = (key: String) => true, + ml_statistics_domain: String => Boolean = _ => true, verbose: Boolean = false): Data = { val date = Date.now() @@ -377,7 +377,7 @@ List(HTML.description( List(HTML.text("status date:") -> HTML.text(data.date.toString))))), HTML.par( - List(HTML.itemize(data.entries.map({ case data_entry => + List(HTML.itemize(data.entries.map(data_entry => List( HTML.link(clean_name(data_entry.name) + "/index.html", HTML.text(data_entry.name))) ::: @@ -388,7 +388,7 @@ List(HTML.span(HTML.error_message, HTML.text("Failed sessions:"))) ::: List(HTML.itemize(sessions.map(s => s.head.present_errors(s.name)))) }) - })))))) + )))))) for (data_entry <- data.entries) { val data_name = data_entry.name @@ -423,10 +423,10 @@ entry.ml_timing.elapsed.minutes.toString, entry.ml_timing.resources.minutes.toString, entry.maximum_code.toString, - entry.maximum_code.toString, + entry.average_code.toString, + entry.maximum_stack.toString, entry.average_stack.toString, - entry.maximum_stack.toString, - entry.average_heap.toString, + entry.maximum_heap.toString, entry.average_heap.toString, entry.stored_heap.toString).mkString(" ")))) @@ -608,7 +608,7 @@ "l:" -> (arg => options = options + ("build_log_history=" + arg)), "o:" -> (arg => options = options + arg), "s:" -> (arg => - space_explode('x', arg).map(Value.Int.parse(_)) match { + space_explode('x', arg).map(Value.Int.parse) match { case List(w, h) if w > 0 && h > 0 => image_size = (w, h) case _ => error("Error bad PNG image size: " + quote(arg)) }), diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Admin/isabelle_cronjob.scala --- a/src/Pure/Admin/isabelle_cronjob.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Admin/isabelle_cronjob.scala Sun Dec 12 11:18:42 2021 +0100 @@ -314,7 +314,7 @@ { List( List(Remote_Build("Linux A", "augsburg1", - options = "-m32 -B -M1x2,2,4" + + options = "-m32 -B -M4" + " -e ISABELLE_OCAML=ocaml -e ISABELLE_OCAMLC=ocamlc -e ISABELLE_OCAMLFIND=ocamlfind" + " -e ISABELLE_GHC_SETUP=true" + " -e ISABELLE_MLTON=mlton" + diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/General/mailman.scala --- a/src/Pure/General/mailman.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/General/mailman.scala Sun Dec 12 11:18:42 2021 +0100 @@ -9,63 +9,93 @@ import java.net.URL +import scala.util.matching.Regex + object Mailman { /* mailing list archives */ - def archive(url: URL, name: String = ""): Archive = + def archive(url: URL, msg_format: Msg_Format, name: String = ""): Archive = { - val text = Url.read(url) - val hrefs = """href="([^"]+\.txt(?:\.gz)?)"""".r.findAllMatchIn(text).map(_.group(1)).toList - val title = - """The ([^</>]*) Archives""".r.findFirstMatchIn(text).map(_.group(1)) val list_url = Url(Library.take_suffix[Char](_ == '/', Url.trim_index(url).toString.toList)._1.mkString + "/") + + val html = Url.read(list_url) + val title = + """The ([^</>]*) Archives""".r.findFirstMatchIn(html).map(_.group(1)) + val hrefs_text = + """href="([^"]+\.txt(?:\.gz)?)"""".r.findAllMatchIn(html).map(_.group(1)).toList + val list_name = (proper_string(name) orElse title).getOrElse(error("Failed to determine mailing list name")) - new Archive(list_url, list_name, hrefs) + new Archive(list_url, list_name, msg_format, hrefs_text) } - class Archive private[Mailman](val list_url: URL, val list_name: String, hrefs: List[String]) + abstract class Msg_Format + { + def regex: Regex + } + + class Archive private[Mailman]( + val list_url: URL, + val list_name: String, + msg_format: Msg_Format, + hrefs_text: List[String]) { override def toString: String = list_name - def download(target_dir: Path, progress: Progress = new Progress): List[Path] = + private def hrefs_msg: List[String] = + (for { + href <- """href="([^"]+)/date.html"""".r.findAllMatchIn(Url.read(list_url)).map(_.group(1)) + html = Url.read(new URL(list_url, href + "/date.html")) + msg <- msg_format.regex.findAllMatchIn(html).map(_.group(1)) + } yield href + "/" + msg).toList + + def get(target_dir: Path, href: String, progress: Progress = new Progress): Option[Path] = { val dir = target_dir + Path.basic(list_name) - Isabelle_System.make_directory(dir) + val path = dir + Path.explode(href) + val url = new URL(list_url, href) + val connection = url.openConnection + try { + val length = connection.getContentLengthLong + val timestamp = connection.getLastModified + val file = path.file + if (file.isFile && file.length == length && file.lastModified == timestamp) None + else { + Isabelle_System.make_directory(path.dir) + progress.echo("Getting " + url) + val bytes = + using(connection.getInputStream)(Bytes.read_stream(_, hint = length.toInt max 1024)) + Bytes.write(file, bytes) + file.setLastModified(timestamp) + Some(path) + } + } + finally { connection.getInputStream.close() } + } - hrefs.flatMap(name => - { - val path = dir + Path.basic(name) - val url = new URL(list_url, name) - val connection = url.openConnection - try { - val length = connection.getContentLengthLong - val timestamp = connection.getLastModified - val file = path.file - if (file.isFile && file.length == length && file.lastModified == timestamp) None - else { - progress.echo("Getting " + url) - val bytes = - using(connection.getInputStream)(Bytes.read_stream(_, hint = length.toInt max 1024)) - Bytes.write(file, bytes) - file.setLastModified(timestamp) - Some(path) - } - } - finally { connection.getInputStream.close() } - }) - } + def download_text(target_dir: Path, progress: Progress = new Progress): List[Path] = + hrefs_text.flatMap(get(target_dir, _, progress = progress)) + + def download_msg(target_dir: Path, progress: Progress = new Progress): List[Path] = + hrefs_msg.flatMap(get(target_dir, _, progress = progress)) + + def download(target_dir: Path, progress: Progress = new Progress): List[Path] = + download_text(target_dir, progress = progress) ::: + download_msg(target_dir, progress = progress) } /* Isabelle mailing lists */ def isabelle_users: Archive = - archive(Url("https://lists.cam.ac.uk/pipermail/cl-isabelle-users"), name = "isabelle-users") + archive(Url("https://lists.cam.ac.uk/pipermail/cl-isabelle-users"), name = "isabelle-users", + msg_format = + new Msg_Format { val regex: Regex = """
  • """.r }) def isabelle_dev: Archive = - archive(Url("https://mailmanbroy.in.tum.de/pipermail/isabelle-dev")) + archive(Url("https://mailmanbroy.in.tum.de/pipermail/isabelle-dev"), + new Msg_Format { val regex: Regex = """
  • """.r }) } diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/General/scan.scala --- a/src/Pure/General/scan.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/General/scan.scala Sun Dec 12 11:18:42 2021 +0100 @@ -24,7 +24,6 @@ abstract class Line_Context case object Finished extends Line_Context case class Quoted(quote: String) extends Line_Context - case object Verbatim extends Line_Context case class Cartouche(depth: Int) extends Line_Context case class Comment_Prefix(symbol: Symbol.Symbol) extends Line_Context case class Cartouche_Comment(depth: Int) extends Line_Context @@ -136,41 +135,6 @@ quote ~ quoted_body(quote) ^^ { case x ~ y => x + y } - /* verbatim text */ - - private def verbatim_body: Parser[String] = - rep(many1(sym => sym != "*") | """\*(?!\})""".r) ^^ (_.mkString) - - def verbatim: Parser[String] = - { - "{*" ~ verbatim_body ~ "*}" ^^ { case x ~ y ~ z => x + y + z } - }.named("verbatim") - - def verbatim_content(source: String): String = - { - require(parseAll(verbatim, source).successful, "no verbatim text") - source.substring(2, source.length - 2) - } - - def verbatim_line(ctxt: Line_Context): Parser[(String, Line_Context)] = - { - ctxt match { - case Finished => - "{*" ~ verbatim_body ~ opt_term("*}") ^^ - { case x ~ y ~ Some(z) => (x + y + z, Finished) - case x ~ y ~ None => (x + y, Verbatim) } - case Verbatim => - verbatim_body ~ opt_term("*}") ^^ - { case x ~ Some(y) => (x + y, Finished) - case x ~ None => (x, Verbatim) } - case _ => failure("") - } - }.named("verbatim_line") - - val recover_verbatim: Parser[String] = - "{*" ~ verbatim_body ^^ { case x ~ y => x + y } - - /* nested text cartouches */ def cartouche_depth(depth: Int): Parser[(String, Int)] = new Parser[(String, Int)] diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Isar/args.ML --- a/src/Pure/Isar/args.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Isar/args.ML Sun Dec 12 11:18:42 2021 +0100 @@ -27,9 +27,6 @@ val name_position: (string * Position.T) parser val cartouche_inner_syntax: string parser val cartouche_input: Input.source parser - val text_token: Token.T parser - val text_input: Input.source parser - val text: string parser val binding: binding parser val alt_name: string parser val liberal_name: string parser @@ -47,8 +44,7 @@ val named_fact: (string -> string option * thm list) -> thm list parser val named_attribute: (string * Position.T -> morphism -> attribute) -> (morphism -> attribute) parser - val text_declaration: (Input.source -> declaration) -> declaration parser - val cartouche_declaration: (Input.source -> declaration) -> declaration parser + val embedded_declaration: (Input.source -> declaration) -> declaration parser val typ_abbrev: typ context_parser val typ: typ context_parser val term: term context_parser @@ -110,10 +106,6 @@ val cartouche_inner_syntax = cartouche >> Token.inner_syntax_of; val cartouche_input = cartouche >> Token.input_of; -val text_token = Parse.token (Parse.embedded || Parse.verbatim); -val text_input = text_token >> Token.input_of; -val text = text_token >> Token.content_of; - val binding = Parse.input name >> (Binding.make o Input.source_content); val alt_name = alt_string >> Token.content_of; val liberal_name = (symbolic >> Token.content_of) || name; @@ -157,11 +149,9 @@ name_token >> Token.evaluate Token.Attribute (fn tok => att (Token.content_of tok, Token.pos_of tok)); -fun text_declaration read = - internal_declaration || text_token >> Token.evaluate Token.Declaration (read o Token.input_of); - -fun cartouche_declaration read = - internal_declaration || cartouche >> Token.evaluate Token.Declaration (read o Token.input_of); +fun embedded_declaration read = + internal_declaration || + Parse.token Parse.embedded >> Token.evaluate Token.Declaration (read o Token.input_of); (* terms and types *) diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Isar/method.ML --- a/src/Pure/Isar/method.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Isar/method.ML Sun Dec 12 11:18:42 2021 +0100 @@ -327,7 +327,7 @@ val parse_tactic = Scan.state :|-- (fn context => - Scan.lift (Args.text_declaration (fn source => + Scan.lift (Args.embedded_declaration (fn source => let val tac = context @@ -749,7 +749,7 @@ in Parse.read_embedded ctxt keywords (Scan.many Token.not_eof) #> read_closure ctxt end; val text_closure = - Args.context -- Scan.lift (Parse.token Parse.text) >> (fn (ctxt, tok) => + Args.context -- Scan.lift (Parse.token Parse.embedded) >> (fn (ctxt, tok) => (case Token.get_value tok of SOME (Token.Source src) => read ctxt src | _ => diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Isar/parse.ML --- a/src/Pure/Isar/parse.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Isar/parse.ML Sun Dec 12 11:18:42 2021 +0100 @@ -30,7 +30,6 @@ val string: string parser val string_position: (string * Position.T) parser val alt_string: string parser - val verbatim: string parser val cartouche: string parser val control: Antiquote.control parser val eof: string parser @@ -70,7 +69,6 @@ val embedded_inner_syntax: string parser val embedded_input: Input.source parser val embedded_position: (string * Position.T) parser - val text: string parser val path_input: Input.source parser val path: string parser val path_binding: (string * Position.T) parser @@ -120,7 +118,6 @@ val thms1: (Facts.ref * Token.src list) list parser val options: ((string * Position.T) * (string * Position.T)) list parser val embedded_ml: ML_Lex.token Antiquote.antiquote list parser - val embedded_ml_underscore: ML_Lex.token Antiquote.antiquote list parser val read_antiq: Keyword.keywords -> 'a parser -> Symbol_Pos.T list * Position.T -> 'a val read_embedded: Proof.context -> Keyword.keywords -> 'a parser -> Input.source -> 'a val read_embedded_src: Proof.context -> Keyword.keywords -> 'a parser -> Token.src -> 'a @@ -200,7 +197,6 @@ val float_number = kind Token.Float; val string = kind Token.String; val alt_string = kind Token.Alt_String; -val verbatim = kind Token.Verbatim; val cartouche = kind Token.Cartouche; val control = token (kind Token.control_kind) >> (the o Token.get_control); val eof = kind Token.EOF; @@ -289,8 +285,6 @@ val embedded_input = input embedded; val embedded_position = embedded_input >> Input.source_content; -val text = group (fn () => "text") (embedded || verbatim); - val path_input = group (fn () => "file name/path specification") embedded_input; val path = path_input >> Input.string_of; val path_binding = group (fn () => "path binding (strict file name)") (position embedded); @@ -400,8 +394,8 @@ (* embedded source text *) -val ML_source = input (group (fn () => "ML source") text); -val document_source = input (group (fn () => "document source") text); +val ML_source = input (group (fn () => "ML source") embedded); +val document_source = input (group (fn () => "document source") embedded); val document_marker = group (fn () => "document marker") @@ -441,7 +435,7 @@ val argument_kinds = [Token.Ident, Token.Long_Ident, Token.Sym_Ident, Token.Var, Token.Type_Ident, Token.Type_Var, - Token.Nat, Token.Float, Token.String, Token.Alt_String, Token.Cartouche, Token.Verbatim]; + Token.Nat, Token.Float, Token.String, Token.Alt_String, Token.Cartouche]; fun arguments is_symid = let @@ -505,12 +499,10 @@ (* embedded ML *) val embedded_ml = + input underscore >> ML_Lex.read_source || embedded_input >> ML_Lex.read_source || control >> (ML_Lex.read_symbols o Antiquote.control_symbols); -val embedded_ml_underscore = - input underscore >> ML_Lex.read_source || embedded_ml; - (* read embedded source, e.g. for antiquotations *) diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Isar/parse.scala --- a/src/Pure/Isar/parse.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Isar/parse.scala Sun Dec 12 11:18:42 2021 +0100 @@ -65,9 +65,9 @@ def nat: Parser[Int] = atom("natural number", _.is_nat) ^^ (s => Integer.parseInt(s)) def name: Parser[String] = atom("name", _.is_name) def embedded: Parser[String] = atom("embedded content", _.is_embedded) - def text: Parser[String] = atom("text", _.is_text) - def ML_source: Parser[String] = atom("ML source", _.is_text) - def document_source: Parser[String] = atom("document source", _.is_text) + def text: Parser[String] = atom("text", _.is_embedded) + def ML_source: Parser[String] = atom("ML source", _.is_embedded) + def document_source: Parser[String] = atom("document source", _.is_embedded) def opt_keyword(s: String): Parser[Boolean] = ($$$("(") ~! $$$(s) ~ $$$(")")) ^^ { case _ => true } | success(false) diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Isar/token.ML --- a/src/Pure/Isar/token.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Isar/token.ML Sun Dec 12 11:18:42 2021 +0100 @@ -11,7 +11,7 @@ Command | Keyword | Ident | Long_Ident | Sym_Ident | Var | Type_Ident | Type_Var | Nat | Float | Space | (*delimited content*) - String | Alt_String | Verbatim | Cartouche | + String | Alt_String | Cartouche | Control of Antiquote.control | Comment of Comment.kind option | (*special content*) @@ -123,7 +123,7 @@ Command | Keyword | Ident | Long_Ident | Sym_Ident | Var | Type_Ident | Type_Var | Nat | Float | Space | (*delimited content*) - String | Alt_String | Verbatim | Cartouche | + String | Alt_String | Cartouche | Control of Antiquote.control | Comment of Comment.kind option | (*special content*) @@ -151,7 +151,6 @@ | Space => "white space" | String => "quoted string" | Alt_String => "back-quoted string" - | Verbatim => "verbatim text" | Cartouche => "text cartouche" | Control _ => "control cartouche" | Comment NONE => "informal comment" @@ -166,7 +165,6 @@ val delimited_kind = (fn String => true | Alt_String => true - | Verbatim => true | Cartouche => true | Control _ => true | Comment _ => true @@ -323,7 +321,6 @@ | Type_Var => (Markup.tvar, "") | String => (Markup.string, "") | Alt_String => (Markup.alt_string, "") - | Verbatim => (Markup.verbatim, "") | Cartouche => (Markup.cartouche, "") | Control _ => (Markup.cartouche, "") | Comment _ => (Markup.comment, "") @@ -374,7 +371,6 @@ (case kind of String => Symbol_Pos.quote_string_qq x | Alt_String => Symbol_Pos.quote_string_bq x - | Verbatim => enclose "{*" "*}" x | Cartouche => cartouche x | Control control => Symbol_Pos.content (Antiquote.control_symbols control) | Comment NONE => enclose "(*" "*)" x @@ -624,22 +620,6 @@ | ident_or_symbolic s = Symbol_Pos.is_identifier s orelse is_symid s; -(* scan verbatim text *) - -val scan_verb = - $$$ "*" --| Scan.ahead (~$$ "}") || - Scan.one (fn (s, _) => s <> "*" andalso Symbol.not_eof s) >> single; - -val scan_verbatim = - Scan.ahead ($$ "{" -- $$ "*") |-- - !!! "unclosed verbatim text" - ((Symbol_Pos.scan_pos --| $$ "{" --| $$ "*") -- - (Scan.repeats scan_verb -- ($$ "*" |-- $$ "}" |-- Symbol_Pos.scan_pos))); - -val recover_verbatim = - $$$ "{" @@@ $$$ "*" @@@ Scan.repeats scan_verb; - - (* scan cartouche *) val scan_cartouche = @@ -678,7 +658,6 @@ fun scan_token keywords = !!! "bad input" (Symbol_Pos.scan_string_qq err_prefix >> token_range String || Symbol_Pos.scan_string_bq err_prefix >> token_range Alt_String || - scan_verbatim >> token_range Verbatim || scan_comment >> token_range (Comment NONE) || Comment.scan_outer >> (fn (k, ss) => token (Comment (SOME k)) ss) || scan_cartouche >> token_range Cartouche || @@ -701,7 +680,6 @@ fun recover msg = (Symbol_Pos.recover_string_qq || Symbol_Pos.recover_string_bq || - recover_verbatim || Symbol_Pos.recover_cartouche || Symbol_Pos.recover_comment || Scan.one (Symbol.not_eof o Symbol_Pos.symbol) >> single) diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Isar/token.scala --- a/src/Pure/Isar/token.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Isar/token.scala Sun Dec 12 11:18:42 2021 +0100 @@ -32,7 +32,6 @@ /*delimited content*/ val STRING = Value("string") val ALT_STRING = Value("back-quoted string") - val VERBATIM = Value("verbatim text") val CARTOUCHE = Value("text cartouche") val CONTROL = Value("control cartouche") val INFORMAL_COMMENT = Value("informal comment") @@ -53,13 +52,12 @@ { val string = quoted("\"") ^^ (x => Token(Token.Kind.STRING, x)) val alt_string = quoted("`") ^^ (x => Token(Token.Kind.ALT_STRING, x)) - val verb = verbatim ^^ (x => Token(Token.Kind.VERBATIM, x)) val cmt = comment ^^ (x => Token(Token.Kind.INFORMAL_COMMENT, x)) val formal_cmt = comment_cartouche ^^ (x => Token(Token.Kind.FORMAL_COMMENT, x)) val cart = cartouche ^^ (x => Token(Token.Kind.CARTOUCHE, x)) val ctrl = control_cartouche ^^ (x => Token(Token.Kind.CONTROL, x)) - string | (alt_string | (verb | (cmt | (formal_cmt | (cart | ctrl))))) + string | (alt_string | (cmt | (formal_cmt | (cart | ctrl)))) } private def other_token(keywords: Keyword.Keywords): Parser[Token] = @@ -99,8 +97,7 @@ val recover_delimited = (recover_quoted("\"") | (recover_quoted("`") | - (recover_verbatim | - (recover_cartouche | recover_comment)))) ^^ (x => Token(Token.Kind.ERROR, x)) + (recover_cartouche | recover_comment))) ^^ (x => Token(Token.Kind.ERROR, x)) val bad = one(_ => true) ^^ (x => Token(Token.Kind.ERROR, x)) @@ -119,14 +116,13 @@ quoted_line("\"", ctxt) ^^ { case (x, c) => (Token(Token.Kind.STRING, x), c) } val alt_string = quoted_line("`", ctxt) ^^ { case (x, c) => (Token(Token.Kind.ALT_STRING, x), c) } - val verb = verbatim_line(ctxt) ^^ { case (x, c) => (Token(Token.Kind.VERBATIM, x), c) } val cart = cartouche_line(ctxt) ^^ { case (x, c) => (Token(Token.Kind.CARTOUCHE, x), c) } val cmt = comment_line(ctxt) ^^ { case (x, c) => (Token(Token.Kind.INFORMAL_COMMENT, x), c) } val formal_cmt = comment_cartouche_line(ctxt) ^^ { case (x, c) => (Token(Token.Kind.FORMAL_COMMENT, x), c) } val other = other_token(keywords) ^^ { case x => (x, Scan.Finished) } - string | (alt_string | (verb | (cart | (cmt | (formal_cmt | other))))) + string | (alt_string | (cart | (cmt | (formal_cmt | other)))) } } @@ -286,7 +282,6 @@ kind == Token.Kind.VAR || kind == Token.Kind.TYPE_IDENT || kind == Token.Kind.TYPE_VAR - def is_text: Boolean = is_embedded || kind == Token.Kind.VERBATIM def is_space: Boolean = kind == Token.Kind.SPACE def is_informal_comment: Boolean = kind == Token.Kind.INFORMAL_COMMENT def is_formal_comment: Boolean = kind == Token.Kind.FORMAL_COMMENT @@ -302,7 +297,6 @@ def is_unfinished: Boolean = is_error && (source.startsWith("\"") || source.startsWith("`") || - source.startsWith("{*") || source.startsWith("(*") || source.startsWith(Symbol.open) || source.startsWith(Symbol.open_decoded)) @@ -319,7 +313,6 @@ def content: String = if (kind == Token.Kind.STRING) Scan.Parsers.quoted_content("\"", source) else if (kind == Token.Kind.ALT_STRING) Scan.Parsers.quoted_content("`", source) - else if (kind == Token.Kind.VERBATIM) Scan.Parsers.verbatim_content(source) else if (kind == Token.Kind.CARTOUCHE) Scan.Parsers.cartouche_content(source) else if (kind == Token.Kind.INFORMAL_COMMENT) Scan.Parsers.comment_content(source) else if (kind == Token.Kind.FORMAL_COMMENT) Comment.content(source) diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/ML/ml_antiquotations.ML --- a/src/Pure/ML/ml_antiquotations.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/ML/ml_antiquotations.ML Sun Dec 12 11:18:42 2021 +0100 @@ -205,14 +205,14 @@ val keywords = Keyword.add_minor_keywords ["for", "=>"] Keyword.empty_keywords; -val parse_name = Parse.input Parse.name; +val parse_name_args = + Parse.input Parse.name -- Scan.repeat Parse.embedded_ml; -val parse_args = Scan.repeat Parse.embedded_ml_underscore; -val parse_for_args = Scan.optional (Parse.$$$ "for" |-- Parse.!!! parse_args) []; +val parse_for_args = + Scan.optional (Parse.$$$ "for" |-- Parse.!!! (Scan.repeat1 Parse.embedded_ml)) []; fun parse_body b = - if b then Parse.$$$ "=>" |-- Parse.!!! Parse.embedded_input >> (ML_Lex.read_source #> single) - else Scan.succeed []; + if b then Parse.$$$ "=>" |-- Parse.!!! (Parse.embedded_ml >> single) else Scan.succeed []; fun is_dummy [Antiquote.Text tok] = ML_Lex.content_of tok = "_" | is_dummy _ = false; @@ -233,7 +233,7 @@ (fn range => fn src => fn ctxt => let val ((s, type_args), fn_body) = src - |> Parse.read_embedded_src ctxt keywords (parse_name -- parse_args -- parse_body function); + |> Parse.read_embedded_src ctxt keywords (parse_name_args -- parse_body function); val pos = Input.pos_of s; val Type (c, Ts) = @@ -269,7 +269,7 @@ let val (((s, type_args), term_args), fn_body) = src |> Parse.read_embedded_src ctxt keywords - (parse_name -- parse_args -- parse_for_args -- parse_body function); + (parse_name_args -- parse_for_args -- parse_body function); val Const (c, T) = Proof_Context.read_const {proper = true, strict = true} ctxt diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/ML/ml_statistics.scala --- a/src/Pure/ML/ml_statistics.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/ML/ml_statistics.scala Sun Dec 12 11:18:42 2021 +0100 @@ -194,7 +194,7 @@ val empty: ML_Statistics = apply(Nil) def apply(ml_statistics0: List[Properties.T], heading: String = "", - domain: String => Boolean = (key: String) => true): ML_Statistics = + domain: String => Boolean = _ => true): ML_Statistics = { require(ml_statistics0.forall(props => Now.unapply(props).isDefined), "missing \"now\" field") @@ -260,6 +260,11 @@ val time_start: Double, val duration: Double) { + override def toString: String = + if (content.isEmpty) "ML_Statistics.empty" + else "ML_Statistics(length = " + content.length + ", fields = " + fields.size + ")" + + /* content */ def maximum(field: String): Double = @@ -286,7 +291,7 @@ def update_data(data: XYSeriesCollection, selected_fields: List[String]): Unit = { - data.removeAllSeries + data.removeAllSeries() for (field <- selected_fields) { val series = new XYSeries(field) content.foreach(entry => series.add(entry.time, entry.get(field))) diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/PIDE/command.ML --- a/src/Pure/PIDE/command.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/PIDE/command.ML Sun Dec 12 11:18:42 2021 +0100 @@ -147,14 +147,6 @@ val token_reports = map (reports_of_token keywords) span; val _ = Position.reports_text (maps #2 token_reports @ maps command_reports span); - val verbatim = - span |> map_filter (fn tok => - if Token.kind_of tok = Token.Verbatim then SOME (Token.pos_of tok) else NONE); - val _ = - if null verbatim then () - else legacy_feature ("Old-style {* verbatim *} token -- use \cartouche\ instead" ^ - Position.here_list verbatim); - val core_range = Token.core_range_of span; val tr = if exists #1 token_reports diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/PIDE/markup.scala --- a/src/Pure/PIDE/markup.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/PIDE/markup.scala Sun Dec 12 11:18:42 2021 +0100 @@ -433,7 +433,6 @@ val OPERATOR = "operator" val STRING = "string" val ALT_STRING = "alt_string" - val VERBATIM = "verbatim" val CARTOUCHE = "cartouche" val COMMENT = "comment" diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/PIDE/rendering.scala --- a/src/Pure/PIDE/rendering.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/PIDE/rendering.scala Sun Dec 12 11:18:42 2021 +0100 @@ -117,7 +117,6 @@ Markup.OPERATOR -> Color.operator, Markup.STRING -> Color.main, Markup.ALT_STRING -> Color.main, - Markup.VERBATIM -> Color.main, Markup.CARTOUCHE -> Color.main, Markup.LITERAL -> Color.keyword1, Markup.DELIMITER -> Color.main, @@ -151,7 +150,6 @@ Map( Markup.STRING -> Color.quoted, Markup.ALT_STRING -> Color.quoted, - Markup.VERBATIM -> Color.quoted, Markup.CARTOUCHE -> Color.quoted, Markup.ANTIQUOTED -> Color.antiquoted) @@ -209,7 +207,7 @@ Markup.Elements(Markup.COMPLETION, Markup.NO_COMPLETION) val language_context_elements = - Markup.Elements(Markup.STRING, Markup.ALT_STRING, Markup.VERBATIM, + Markup.Elements(Markup.STRING, Markup.ALT_STRING, Markup.CARTOUCHE, Markup.COMMENT, Markup.LANGUAGE, Markup.ML_STRING, Markup.ML_COMMENT) diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Pure.thy --- a/src/Pure/Pure.thy Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Pure.thy Sun Dec 12 11:18:42 2021 +0100 @@ -301,13 +301,13 @@ val _ = Outer_Syntax.local_theory \<^command_keyword>\attribute_setup\ "define attribute in ML" (Parse.name_position -- - Parse.!!! (\<^keyword>\=\ |-- Parse.ML_source -- Scan.optional Parse.text "") + Parse.!!! (\<^keyword>\=\ |-- Parse.ML_source -- Scan.optional Parse.embedded "") >> (fn (name, (txt, cmt)) => Attrib.attribute_setup name txt cmt)); val _ = Outer_Syntax.local_theory \<^command_keyword>\method_setup\ "define proof method in ML" (Parse.name_position -- - Parse.!!! (\<^keyword>\=\ |-- Parse.ML_source -- Scan.optional Parse.text "") + Parse.!!! (\<^keyword>\=\ |-- Parse.ML_source -- Scan.optional Parse.embedded "") >> (fn (name, (txt, cmt)) => Method.method_setup name txt cmt)); val _ = @@ -572,7 +572,7 @@ val _ = Outer_Syntax.local_theory \<^command_keyword>\named_theorems\ "declare named collection of theorems" - (Parse.and_list1 (Parse.binding -- Scan.optional Parse.text "") >> + (Parse.and_list1 (Parse.binding -- Scan.optional Parse.embedded "") >> fold (fn (b, descr) => snd o Named_Theorems.declare b descr)); in end\ diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Thy/bibtex.ML --- a/src/Pure/Thy/bibtex.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Thy/bibtex.ML Sun Dec 12 11:18:42 2021 +0100 @@ -42,8 +42,7 @@ Theory.setup (Document_Antiquotation.setup_option \<^binding>\cite_macro\ (Config.put cite_macro) #> Document_Output.antiquotation_raw \<^binding>\cite\ - (Scan.lift - (Scan.option (Parse.verbatim || Parse.cartouche) -- Parse.and_list1 Args.name_position)) + (Scan.lift (Scan.option Parse.cartouche -- Parse.and_list1 Args.name_position)) (fn ctxt => fn (opt, citations) => let val _ = diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Thy/document_antiquotations.ML --- a/src/Pure/Thy/document_antiquotations.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Thy/document_antiquotations.ML Sun Dec 12 11:18:42 2021 +0100 @@ -195,7 +195,7 @@ Input.source_content #> #1 #> Document_Antiquotation.prepare_lines ctxt; fun text_antiquotation name = - Document_Output.antiquotation_raw_embedded name (Scan.lift Args.text_input) + Document_Output.antiquotation_raw_embedded name (Scan.lift Parse.embedded_input) (fn ctxt => fn text => let val _ = report_text ctxt text; @@ -206,7 +206,7 @@ end); val theory_text_antiquotation = - Document_Output.antiquotation_raw_embedded \<^binding>\theory_text\ (Scan.lift Args.text_input) + Document_Output.antiquotation_raw_embedded \<^binding>\theory_text\ (Scan.lift Parse.embedded_input) (fn ctxt => fn text => let val keywords = Thy_Header.get_keywords' ctxt; @@ -273,7 +273,7 @@ (* verbatim text *) val _ = Theory.setup - (Document_Output.antiquotation_verbatim_embedded \<^binding>\verbatim\ (Scan.lift Args.text_input) + (Document_Output.antiquotation_verbatim_embedded \<^binding>\verbatim\ (Scan.lift Parse.embedded_input) (fn ctxt => fn text => let val pos = Input.pos_of text; @@ -327,17 +327,17 @@ ML_Lex.read (ML_Syntax.print_string (ML_Lex.content_of tok)) | test_functor _ = raise Fail "Bad ML functor specification"; -val parse_ml0 = Args.text_input >> (fn source => ("", (source, Input.empty))); +val parse_ml0 = Parse.embedded_input >> (fn source => ("", (source, Input.empty))); val parse_ml = - Args.text_input -- Scan.optional (Args.colon |-- Args.text_input) Input.empty >> pair ""; + Parse.embedded_input -- Scan.optional (Args.colon |-- Parse.embedded_input) Input.empty >> pair ""; val parse_exn = - Args.text_input -- Scan.optional (Args.$$$ "of" |-- Args.text_input) Input.empty >> pair ""; + Parse.embedded_input -- Scan.optional (Args.$$$ "of" |-- Parse.embedded_input) Input.empty >> pair ""; val parse_type = (Parse.type_args >> (fn [] => "" | [a] => a ^ " " | bs => enclose "(" ") " (commas bs))) -- - (Args.text_input -- Scan.optional (Args.$$$ "=" |-- Args.text_input) Input.empty); + (Parse.embedded_input -- Scan.optional (Args.$$$ "=" |-- Parse.embedded_input) Input.empty); fun eval ctxt pos ml = ML_Context.eval_in (SOME ctxt) ML_Compiler.flags pos ml diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Thy/document_output.ML --- a/src/Pure/Thy/document_output.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Thy/document_output.ML Sun Dec 12 11:18:42 2021 +0100 @@ -92,7 +92,7 @@ fun output_block (Markdown.Par lines) = separate (XML.Text "\n") (map (Latex.block o output_line) lines) | output_block (Markdown.List {kind, body, ...}) = - Latex.environment_text (Markdown.print_kind kind) (output_blocks body) + Latex.environment (Markdown.print_kind kind) (output_blocks body) and output_blocks blocks = separate (XML.Text "\n\n") (map (Latex.block o output_block) blocks); in @@ -172,7 +172,6 @@ else output false "" "" | Token.String => output false "{\\isachardoublequoteopen}" "{\\isachardoublequoteclose}" | Token.Alt_String => output false "{\\isacharbackquoteopen}" "{\\isacharbackquoteclose}" - | Token.Verbatim => output true "{\\isacharverbatimopen}" "{\\isacharverbatimclose}" | Token.Cartouche => output false "{\\isacartoucheopen}" "{\\isacartoucheclose}" | Token.Control control => output_body ctxt false "" "" (Antiquote.control_symbols control) | _ => output false "" "") diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Thy/latex.ML --- a/src/Pure/Thy/latex.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Thy/latex.ML Sun Dec 12 11:18:42 2021 +0100 @@ -14,15 +14,12 @@ val macro0: string -> text val macro: string -> text -> text val environment: string -> text -> text - val enclose_text: string -> string -> text -> text - val output_name: string -> string val output_ascii: string -> string val output_ascii_breakable: string -> string -> string val output_symbols: Symbol.symbol list -> string val output_syms: string -> string val symbols: Symbol_Pos.T list -> text val symbols_output: Symbol_Pos.T list -> text - val environment_text: string -> text -> text val isabelle_body: string -> text -> text val theory_entry: string -> string type index_item = {text: text, like: string} @@ -30,9 +27,7 @@ val index_entry: index_entry -> text val index_variants: (binding -> bool option -> 'a -> 'a) -> binding -> 'a -> 'a val latexN: string - val latex_output: string -> string * int val latex_markup: string * Properties.T -> Markup.output - val latex_indent: string -> int -> string end; structure Latex: LATEX = @@ -57,8 +52,6 @@ fun macro name body = [XML.Elem (Markup.latex_macro name, body)]; fun environment name body = [XML.Elem (Markup.latex_environment name, body)]; -fun enclose_text bg en body = string bg @ body @ string en; - (* output name for LaTeX macros *) @@ -194,13 +187,8 @@ (* theory presentation *) -fun environment_text name = - enclose_text - ("%\n\\begin{" ^ output_name name ^ "}%\n") - ("%\n\\end{" ^ output_name name ^ "}"); - fun isabelle_body name = - enclose_text + XML.enclose ("%\n\\begin{isabellebody}%\n\\setisabellecontext{" ^ output_syms name ^ "}%\n") "%\n\\end{isabellebody}%\n"; @@ -230,22 +218,29 @@ val latexN = "latex"; +local + fun latex_output str = let val syms = Symbol.explode str in (output_symbols syms, length_symbols syms) end; +val command_markup = YXML.output_markup (Markup.latex_macro "isacommand"); +val keyword_markup = YXML.output_markup (Markup.latex_macro "isakeyword"); +val indent_markup = YXML.output_markup (Markup.latex_macro "isaindent"); + +in + fun latex_markup (s, _: Properties.T) = - if s = Markup.commandN orelse s = Markup.keyword1N orelse s = Markup.keyword3N - then ("\\isacommand{", "}") - else if s = Markup.keyword2N - then ("\\isakeyword{", "}") + if member (op =) [Markup.commandN, Markup.keyword1N, Markup.keyword3N] s then command_markup + else if s = Markup.keyword2N then keyword_markup else Markup.no_output; -fun latex_indent "" _ = "" - | latex_indent s _ = enclose "\\isaindent{" "}" s; - val _ = Output.add_mode latexN latex_output (prefix Symbol.latex o cartouche); val _ = Markup.add_mode latexN latex_markup; -val _ = Pretty.add_mode latexN latex_indent; + +val _ = Pretty.add_mode latexN + (fn s => fn _ => if s = "" then s else uncurry enclose indent_markup s); end; + +end; diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Thy/sessions.ML --- a/src/Pure/Thy/sessions.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Thy/sessions.ML Sun Dec 12 11:18:42 2021 +0100 @@ -52,7 +52,7 @@ Scan.optional (Parse.$$$ "in" |-- Parse.!!! Parse.path_input) (Input.string ".") -- (Parse.$$$ "=" |-- Parse.!!! (Scan.option (Parse.session_name --| Parse.!!! (Parse.$$$ "+")) -- - Scan.optional (Parse.$$$ "description" |-- Parse.!!! (Parse.input Parse.text)) Input.empty -- + Scan.optional (Parse.$$$ "description" |-- Parse.!!! (Parse.input Parse.embedded)) Input.empty -- Scan.optional (Parse.$$$ "options" |-- Parse.!!! Parse.options) [] -- Scan.optional (Parse.$$$ "sessions" |-- Parse.!!! (Scan.repeat1 Parse.session_name)) [] -- diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Thy/thy_header.ML --- a/src/Pure/Thy/thy_header.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Thy/thy_header.ML Sun Dec 12 11:18:42 2021 +0100 @@ -147,7 +147,7 @@ val abbrevs = Parse.and_list1 - (Scan.repeat1 Parse.text -- (Parse.$$$ "=" |-- Parse.!!! (Scan.repeat1 Parse.text)) + (Scan.repeat1 Parse.embedded -- (Parse.$$$ "=" |-- Parse.!!! (Scan.repeat1 Parse.embedded)) >> uncurry (map_product pair)) >> flat; val keyword_decls = Parse.and_list1 keyword_decl >> flat; diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Tools/rail.ML --- a/src/Pure/Tools/rail.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Tools/rail.ML Sun Dec 12 11:18:42 2021 +0100 @@ -384,10 +384,10 @@ output "" rail' @ Latex.string "\\rail@end\n" end; - in Latex.environment_text "railoutput" (maps output_rule rules) end; + in Latex.environment "railoutput" (maps output_rule rules) end; val _ = Theory.setup - (Document_Output.antiquotation_raw_embedded \<^binding>\rail\ (Scan.lift Args.text_input) + (Document_Output.antiquotation_raw_embedded \<^binding>\rail\ (Scan.lift Parse.embedded_input) (fn ctxt => output_rules ctxt o read ctxt)); end; diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Tools/update_cartouches.scala --- a/src/Pure/Tools/update_cartouches.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Tools/update_cartouches.scala Sun Dec 12 11:18:42 2021 +0100 @@ -14,8 +14,6 @@ { /* update cartouches */ - private val Verbatim_Body = """(?s)[ \t]*(.*?)[ \t]*""".r - val Text_Antiq: Regex = """(?s)@\{\s*text\b\s*(.+)\}""".r def update_text(content: String): String = @@ -46,12 +44,6 @@ (for (tok <- Token.explode(Keyword.Keywords.empty, text0).iterator) yield { if (tok.kind == Token.Kind.ALT_STRING) Symbol.cartouche(tok.content) - else if (tok.kind == Token.Kind.VERBATIM) { - tok.content match { - case Verbatim_Body(s) => Symbol.cartouche(s) - case s => tok.source - } - } else tok.source } ).mkString @@ -96,7 +88,7 @@ -t replace @{text} antiquotations within text tokens Recursively find .thy or ROOT files and update theory syntax to use - cartouches instead of old-style {* verbatim *} or `alt_string` tokens. + cartouches instead of `alt_string` tokens. Old versions of files are preserved by appending "~~". """, diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/Tools/update_comments.scala --- a/src/Pure/Tools/update_comments.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/Tools/update_comments.scala Sun Dec 12 11:18:42 2021 +0100 @@ -23,7 +23,7 @@ case tok :: rest if tok.source == "--" || tok.source == Symbol.comment => rest.dropWhile(_.is_space) match { - case tok1 :: rest1 if tok1.is_text => + case tok1 :: rest1 if tok1.is_embedded => update(rest1, make_comment(tok1) :: result) case _ => update(rest, tok.source :: result) } diff -r 70be57333ea1 -r cdd2284c8047 src/Pure/pure_syn.ML --- a/src/Pure/pure_syn.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Pure/pure_syn.ML Sun Dec 12 11:18:42 2021 +0100 @@ -43,7 +43,7 @@ Outer_Syntax.command ("text_raw", \<^here>) "LaTeX text (without surrounding environment)" (Parse.opt_target -- Parse.document_source >> Document_Output.document_output - {markdown = true, markup = Latex.enclose_text "%\n" "\n"}); + {markdown = true, markup = XML.enclose "%\n" "\n"}); val _ = Outer_Syntax.command ("theory", \<^here>) "begin theory" diff -r 70be57333ea1 -r cdd2284c8047 src/Tools/Code/code_target.ML --- a/src/Tools/Code/code_target.ML Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Tools/Code/code_target.ML Sun Dec 12 11:18:42 2021 +0100 @@ -746,7 +746,7 @@ Outer_Syntax.command \<^command_keyword>\code_printing\ "declare dedicated printing for code symbols" (parse_symbol_pragmas (Code_Printer.parse_const_syntax) (Code_Printer.parse_tyco_syntax) Parse.string (Parse.minus >> K ()) (Parse.minus >> K ()) - (Parse.text -- Scan.optional (\<^keyword>\for\ |-- parse_simple_symbols) []) + (Parse.embedded -- Scan.optional (\<^keyword>\for\ |-- parse_simple_symbols) []) >> (Toplevel.theory o fold set_printings_cmd)); val _ = diff -r 70be57333ea1 -r cdd2284c8047 src/Tools/VSCode/extension/README.md --- a/src/Tools/VSCode/extension/README.md Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Tools/VSCode/extension/README.md Sun Dec 12 11:18:42 2021 +0100 @@ -1,14 +1,15 @@ # Isabelle Prover IDE support This extension connects VSCode to the Isabelle Prover IDE infrastructure: it -requires Isabelle2021-1. +requires a suitable repository version of Isabelle. The implementation is centered around the VSCode Language Server protocol, but with many add-ons that are specific to VSCode and Isabelle/PIDE. See also: - * + * + * ## Screenshot @@ -57,8 +58,8 @@ ### Isabelle/VSCode Installation - * Download Isabelle2021-1 from - or any of its mirror sites. + * Download a recent Isabelle development snapshot from + * Unpack and run the main Isabelle/jEdit application as usual, to ensure that the logic image is built properly and Isabelle works as expected. @@ -88,17 +89,17 @@ + Linux: ``` - "isabelle.home": "/home/makarius/Isabelle2021-1" + "isabelle.home": "/home/makarius/Isabelle" ``` + Mac OS X: ``` - "isabelle.home": "/Users/makarius/Isabelle.app/Isabelle2021-1" + "isabelle.home": "/Users/makarius/Isabelle.app/Isabelle" ``` + Windows: ``` - "isabelle.home": "C:\\Users\\makarius\\Isabelle2021-1" + "isabelle.home": "C:\\Users\\makarius\\Isabelle" ``` * Restart the VSCode application to ensure that all extensions are properly diff -r 70be57333ea1 -r cdd2284c8047 src/Tools/VSCode/extension/package.json --- a/src/Tools/VSCode/extension/package.json Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Tools/VSCode/extension/package.json Sun Dec 12 11:18:42 2021 +0100 @@ -1,6 +1,6 @@ { - "name": "Isabelle2021-1", - "displayName": "Isabelle2021-1", + "name": "Isabelle", + "displayName": "Isabelle", "description": "Isabelle Prover IDE", "keywords": [ "theorem prover", diff -r 70be57333ea1 -r cdd2284c8047 src/Tools/jEdit/src/jedit_rendering.scala --- a/src/Tools/jEdit/src/jedit_rendering.scala Sun Dec 12 10:42:51 2021 +0100 +++ b/src/Tools/jEdit/src/jedit_rendering.scala Sun Dec 12 11:18:42 2021 +0100 @@ -70,7 +70,6 @@ Token.Kind.SPACE -> NULL, Token.Kind.STRING -> LITERAL1, Token.Kind.ALT_STRING -> LITERAL2, - Token.Kind.VERBATIM -> COMMENT3, Token.Kind.CARTOUCHE -> COMMENT3, Token.Kind.CONTROL -> COMMENT3, Token.Kind.INFORMAL_COMMENT -> COMMENT1,