Merge commit '59b082d09d55d55ef6c6f8bd8e821122dddf3574' into isabelle_nightly

This commit is contained in:
Achim D. Brucker 2023-08-03 03:35:29 +01:00
commit 0a3259fbca
8 changed files with 2952 additions and 54 deletions

View File

@ -113,9 +113,9 @@ doc_class inv_test4 = inv_test2 +
invariant inv_test4' :: "a (d \<sigma>) = 2"
text*[inv_test1_instance::inv_test1, a=2]\<open>\<close>
text*[inv_test3_instance::inv_test3, a=2, b="@{inv-test1 \<open>inv_test1_instance\<close>}" ]\<open>\<close>
text*[inv_test4_instance::inv_test4, b="@{inv-test1 \<open>inv_test1_instance\<close>}"
, c=1, d="@{inv-test3 \<open>inv_test3_instance\<close>}"]\<open>\<close>
text*[inv_test3_instance::inv_test3, a=2, b="@{inv_test1 \<open>inv_test1_instance\<close>}" ]\<open>\<close>
text*[inv_test4_instance::inv_test4, b="@{inv_test1 \<open>inv_test1_instance\<close>}"
, c=1, d="@{inv_test3 \<open>inv_test3_instance\<close>}"]\<open>\<close>
text\<open>To support invariant on attributes in attributes
and invariant on attributes of the superclasses,
@ -207,15 +207,15 @@ update_instance*[introduction2::Introduction
text\<open>Use of the instance @{docitem_name "church'"}
to instantiate a \<^doc_class>\<open>scholarly_paper.introduction\<close> class:\<close>
text*[introduction2'::scholarly_paper.introduction,
main_author = "Some @{scholarly-paper.author \<open>church'\<close>}", level = "Some 2"]\<open>\<close>
main_author = "Some @{scholarly_paper.author \<open>church'\<close>}", level = "Some 2"]\<open>\<close>
value*\<open>@{scholarly-paper.author \<open>church'\<close>}\<close>
value*\<open>@{scholarly_paper.author \<open>church'\<close>}\<close>
value*\<open>@{author \<open>church\<close>}\<close>
value*\<open>@{Concept-High-Level-Invariants.author \<open>church\<close>}\<close>
value*\<open>@{Concept_High_Level_Invariants.author \<open>church\<close>}\<close>
value*\<open>@{scholarly-paper.author-instances}\<close>
value*\<open>@{author-instances}\<close>
value*\<open>@{Concept-High-Level-Invariants.author-instances}\<close>
value*\<open>@{scholarly_paper.author_instances}\<close>
value*\<open>@{author_instances}\<close>
value*\<open>@{Concept_High_Level_Invariants.author_instances}\<close>
text*[introduction3::introduction, authored_by = "{@{author \<open>church\<close>}}", level = "Some 2"]\<open>\<close>
text*[introduction4::introduction, authored_by = "{@{author \<open>curry\<close>}}", level = "Some 4"]\<open>\<close>

View File

@ -99,7 +99,7 @@ text*[cc_assumption_test_ref::cc_assumption_test]\<open>\<close>
definition tag_l :: "'a \<Rightarrow> 'b \<Rightarrow> 'b" where "tag_l \<equiv> \<lambda>x y. y"
lemma* tagged : "tag_l @{cc-assumption-test \<open>cc_assumption_test_ref\<close>} AA \<Longrightarrow> AA"
lemma* tagged : "tag_l @{cc_assumption_test \<open>cc_assumption_test_ref\<close>} AA \<Longrightarrow> AA"
by (simp add: tag_l_def)
find_theorems name:tagged "(_::cc_assumption_test \<Rightarrow> _ \<Rightarrow> _) _ _ \<Longrightarrow>_"

View File

@ -150,10 +150,7 @@ term*\<open>r @{F \<open>xcv4\<close>}\<close>
text\<open>We declare a new text element. Note that the class name contains an underscore "\_".\<close>
text*[te::text_element]\<open>Lorem ipsum...\<close>
text\<open>Unfortunately due to different lexical conventions for constant symbols and mixfix symbols
this term antiquotation has to be denoted like this: @{term_ \<open>@{text-element \<open>te\<close>}\<close>}.
We need to substitute an hyphen "-" for the underscore "\_".\<close>
term*\<open>@{text-element \<open>te\<close>}\<close>
term*\<open>@{text_element \<open>te\<close>}\<close>
text\<open>Terms containing term antiquotations can be checked and evaluated
using \<^theory_text>\<open>term_\<close> and \<^theory_text>\<open>value_\<close> text antiquotations respectively:

View File

@ -146,17 +146,17 @@ text*[test2Z::Z, z=4]\<open>lorem ipsum...\<close>
text*[test3Z::Z, z=3]\<open>lorem ipsum...\<close>
text\<open>We want to get all the instances of the @{doc_class Z}:\<close>
value*\<open>@{Z-instances}\<close>
value*\<open>@{Z_instances}\<close>
text\<open>Now we want to get the instances of the @{doc_class Z} whose attribute z > 2:\<close>
value*\<open>filter (\<lambda>\<sigma>. Z.z \<sigma> > 2) @{Z-instances}\<close>
value*\<open>filter (\<lambda>\<sigma>. Z.z \<sigma> > 2) @{Z_instances}\<close>
text\<open>We can check that we have the list of instances we wanted:\<close>
value*\<open>filter (\<lambda>\<sigma>. Z.z \<sigma> > 2) @{Z-instances} = [@{Z \<open>test3Z\<close>}, @{Z \<open>test2Z\<close>}]
\<or> filter (\<lambda>\<sigma>. Z.z \<sigma> > 2) @{Z-instances} = [@{Z \<open>test2Z\<close>}, @{Z \<open>test3Z\<close>}]\<close>
value*\<open>filter (\<lambda>\<sigma>. Z.z \<sigma> > 2) @{Z_instances} = [@{Z \<open>test3Z\<close>}, @{Z \<open>test2Z\<close>}]
\<or> filter (\<lambda>\<sigma>. Z.z \<sigma> > 2) @{Z_instances} = [@{Z \<open>test2Z\<close>}, @{Z \<open>test3Z\<close>}]\<close>
text\<open>Now, we want to get all the instances of the @{doc_class A}\<close>
value*\<open>@{A-instances}\<close>
value*\<open>@{A_instances}\<close>
(*<*)
text\<open>Warning: If you make a request on attributes that are undefined in some instances,
@ -166,7 +166,7 @@ But we have defined an instance @{docitem \<open>sdf\<close>} in theory @{theory
whose our theory inherits from, and this docitem instance does not initialize its attribute \<^emph>\<open>x\<close>.
So in the request result we get an unresolved case because the evaluator can not get
the value of the \<^emph>\<open>x\<close> attribute of the instance @{docitem \<open>sdf\<close>}:\<close>
value*\<open>filter (\<lambda>\<sigma>. A.x \<sigma> > 5) @{A-instances}\<close>
value*\<open>filter (\<lambda>\<sigma>. A.x \<sigma> > 5) @{A_instances}\<close>
(*>*)
section\<open>Limitations\<close>
@ -201,12 +201,12 @@ Consequently, it has the same limitations as \<^emph>\<open>value*\<close>.
text\<open>Using the ontology defined in \<^theory>\<open>Isabelle_DOF-Unit-Tests.Concept_High_Level_Invariants\<close>
we can check logical statements:\<close>
term*\<open>authored_by @{Concept-High-Level-Invariants.introduction \<open>introduction2\<close>}
= authored_by @{Concept-High-Level-Invariants.introduction \<open>introduction3\<close>}\<close>
assert*\<open>authored_by @{Concept-High-Level-Invariants.introduction \<open>introduction2\<close>}
= authored_by @{Concept-High-Level-Invariants.introduction \<open>introduction3\<close>}\<close>
assert*\<open>\<not>(authored_by @{Concept-High-Level-Invariants.introduction \<open>introduction2\<close>}
= authored_by @{Concept-High-Level-Invariants.introduction \<open>introduction4\<close>})\<close>
term*\<open>authored_by @{Concept_High_Level_Invariants.introduction \<open>introduction2\<close>}
= authored_by @{Concept_High_Level_Invariants.introduction \<open>introduction3\<close>}\<close>
assert*\<open>authored_by @{Concept_High_Level_Invariants.introduction \<open>introduction2\<close>}
= authored_by @{Concept_High_Level_Invariants.introduction \<open>introduction3\<close>}\<close>
assert*\<open>\<not>(authored_by @{Concept_High_Level_Invariants.introduction \<open>introduction2\<close>}
= authored_by @{Concept_High_Level_Invariants.introduction \<open>introduction4\<close>})\<close>
text\<open>Assertions must be boolean expressions, so the following assertion triggers an error:\<close>
(* Error:
@ -226,7 +226,7 @@ text\<open>... and here we reference @{A \<open>assertionA\<close>}.\<close>
assert*\<open>evidence @{result \<open>resultProof\<close>} = evidence @{result \<open>resultProof2\<close>}\<close>
text\<open>The optional evaluator of \<open>value*\<close> and \<open>assert*\<close> must be specified after the meta arguments:\<close>
value* [optional_test_A::A, x=6] [nbe] \<open>filter (\<lambda>\<sigma>. A.x \<sigma> > 5) @{A-instances}\<close>
value* [optional_test_A::A, x=6] [nbe] \<open>filter (\<lambda>\<sigma>. A.x \<sigma> > 5) @{A_instances}\<close>
assert* [resultProof3::result, evidence = "proof", property="[@{thm \<open>HOL.sym\<close>}]"] [nbe]
\<open>evidence @{result \<open>resultProof3\<close>} = evidence @{result \<open>resultProof2\<close>}\<close>

View File

@ -0,0 +1,463 @@
(* Title: HOL/Record.thy
Author: Wolfgang Naraschewski, TU Muenchen
Author: Markus Wenzel, TU Muenchen
Author: Norbert Schirmer, TU Muenchen
Author: Thomas Sewell, NICTA
Author: Florian Haftmann, TU Muenchen
*)
section \<open>Extensible records with structural subtyping\<close>
theory Test
imports HOL.Quickcheck_Exhaustive
keywords
"record*" :: thy_defn and
"print_record*" :: diag
begin
subsection \<open>Introduction\<close>
text \<open>
Records are isomorphic to compound tuple types. To implement
efficient records, we make this isomorphism explicit. Consider the
record access/update simplification \<open>alpha (beta_update f
rec) = alpha rec\<close> for distinct fields alpha and beta of some record
rec with n fields. There are \<open>n ^ 2\<close> such theorems, which
prohibits storage of all of them for large n. The rules can be
proved on the fly by case decomposition and simplification in O(n)
time. By creating O(n) isomorphic-tuple types while defining the
record, however, we can prove the access/update simplification in
\<open>O(log(n)^2)\<close> time.
The O(n) cost of case decomposition is not because O(n) steps are
taken, but rather because the resulting rule must contain O(n) new
variables and an O(n) size concrete record construction. To sidestep
this cost, we would like to avoid case decomposition in proving
access/update theorems.
Record types are defined as isomorphic to tuple types. For instance,
a record type with fields \<open>'a\<close>, \<open>'b\<close>, \<open>'c\<close>
and \<open>'d\<close> might be introduced as isomorphic to \<open>'a \<times>
('b \<times> ('c \<times> 'd))\<close>. If we balance the tuple tree to \<open>('a \<times>
'b) \<times> ('c \<times> 'd)\<close> then accessors can be defined by converting to the
underlying type then using O(log(n)) fst or snd operations.
Updators can be defined similarly, if we introduce a \<open>fst_update\<close> and \<open>snd_update\<close> function. Furthermore, we can
prove the access/update theorem in O(log(n)) steps by using simple
rewrites on fst, snd, \<open>fst_update\<close> and \<open>snd_update\<close>.
The catch is that, although O(log(n)) steps were taken, the
underlying type we converted to is a tuple tree of size
O(n). Processing this term type wastes performance. We avoid this
for large n by taking each subtree of size K and defining a new type
isomorphic to that tuple subtree. A record can now be defined as
isomorphic to a tuple tree of these O(n/K) new types, or, if \<open>n > K*K\<close>, we can repeat the process, until the record can be
defined in terms of a tuple tree of complexity less than the
constant K.
If we prove the access/update theorem on this type with the
analogous steps to the tuple tree, we consume \<open>O(log(n)^2)\<close>
time as the intermediate terms are \<open>O(log(n))\<close> in size and
the types needed have size bounded by K. To enable this analogous
traversal, we define the functions seen below: \<open>iso_tuple_fst\<close>, \<open>iso_tuple_snd\<close>, \<open>iso_tuple_fst_update\<close>
and \<open>iso_tuple_snd_update\<close>. These functions generalise tuple
operations by taking a parameter that encapsulates a tuple
isomorphism. The rewrites needed on these functions now need an
additional assumption which is that the isomorphism works.
These rewrites are typically used in a structured way. They are here
presented as the introduction rule \<open>isomorphic_tuple.intros\<close>
rather than as a rewrite rule set. The introduction form is an
optimisation, as net matching can be performed at one term location
for each step rather than the simplifier searching the term for
possible pattern matches. The rule set is used as it is viewed
outside the locale, with the locale assumption (that the isomorphism
is valid) left as a rule assumption. All rules are structured to aid
net matching, using either a point-free form or an encapsulating
predicate.
\<close>
subsection \<open>Operators and lemmas for types isomorphic to tuples\<close>
datatype (dead 'a, dead 'b, dead 'c) tuple_isomorphism =
Tuple_Isomorphism "'a \<Rightarrow> 'b \<times> 'c" "'b \<times> 'c \<Rightarrow> 'a"
primrec
repr :: "('a, 'b, 'c) tuple_isomorphism \<Rightarrow> 'a \<Rightarrow> 'b \<times> 'c" where
"repr (Tuple_Isomorphism r a) = r"
primrec
abst :: "('a, 'b, 'c) tuple_isomorphism \<Rightarrow> 'b \<times> 'c \<Rightarrow> 'a" where
"abst (Tuple_Isomorphism r a) = a"
definition
iso_tuple_fst :: "('a, 'b, 'c) tuple_isomorphism \<Rightarrow> 'a \<Rightarrow> 'b" where
"iso_tuple_fst isom = fst \<circ> repr isom"
definition
iso_tuple_snd :: "('a, 'b, 'c) tuple_isomorphism \<Rightarrow> 'a \<Rightarrow> 'c" where
"iso_tuple_snd isom = snd \<circ> repr isom"
definition
iso_tuple_fst_update ::
"('a, 'b, 'c) tuple_isomorphism \<Rightarrow> ('b \<Rightarrow> 'b) \<Rightarrow> ('a \<Rightarrow> 'a)" where
"iso_tuple_fst_update isom f = abst isom \<circ> apfst f \<circ> repr isom"
definition
iso_tuple_snd_update ::
"('a, 'b, 'c) tuple_isomorphism \<Rightarrow> ('c \<Rightarrow> 'c) \<Rightarrow> ('a \<Rightarrow> 'a)" where
"iso_tuple_snd_update isom f = abst isom \<circ> apsnd f \<circ> repr isom"
definition
iso_tuple_cons ::
"('a, 'b, 'c) tuple_isomorphism \<Rightarrow> 'b \<Rightarrow> 'c \<Rightarrow> 'a" where
"iso_tuple_cons isom = curry (abst isom)"
subsection \<open>Logical infrastructure for records\<close>
definition
iso_tuple_surjective_proof_assist :: "'a \<Rightarrow> 'b \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool" where
"iso_tuple_surjective_proof_assist x y f \<longleftrightarrow> f x = y"
definition
iso_tuple_update_accessor_cong_assist ::
"(('b \<Rightarrow> 'b) \<Rightarrow> ('a \<Rightarrow> 'a)) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool" where
"iso_tuple_update_accessor_cong_assist upd ac \<longleftrightarrow>
(\<forall>f v. upd (\<lambda>x. f (ac v)) v = upd f v) \<and> (\<forall>v. upd id v = v)"
definition
iso_tuple_update_accessor_eq_assist ::
"(('b \<Rightarrow> 'b) \<Rightarrow> ('a \<Rightarrow> 'a)) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'a \<Rightarrow> ('b \<Rightarrow> 'b) \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> bool" where
"iso_tuple_update_accessor_eq_assist upd ac v f v' x \<longleftrightarrow>
upd f v = v' \<and> ac v = x \<and> iso_tuple_update_accessor_cong_assist upd ac"
lemma update_accessor_congruence_foldE:
assumes uac: "iso_tuple_update_accessor_cong_assist upd ac"
and r: "r = r'" and v: "ac r' = v'"
and f: "\<And>v. v' = v \<Longrightarrow> f v = f' v"
shows "upd f r = upd f' r'"
using uac r v [symmetric]
apply (subgoal_tac "upd (\<lambda>x. f (ac r')) r' = upd (\<lambda>x. f' (ac r')) r'")
apply (simp add: iso_tuple_update_accessor_cong_assist_def)
apply (simp add: f)
done
lemma update_accessor_congruence_unfoldE:
"iso_tuple_update_accessor_cong_assist upd ac \<Longrightarrow>
r = r' \<Longrightarrow> ac r' = v' \<Longrightarrow> (\<And>v. v = v' \<Longrightarrow> f v = f' v) \<Longrightarrow>
upd f r = upd f' r'"
apply (erule(2) update_accessor_congruence_foldE)
apply simp
done
lemma iso_tuple_update_accessor_cong_assist_id:
"iso_tuple_update_accessor_cong_assist upd ac \<Longrightarrow> upd id = id"
by rule (simp add: iso_tuple_update_accessor_cong_assist_def)
lemma update_accessor_noopE:
assumes uac: "iso_tuple_update_accessor_cong_assist upd ac"
and ac: "f (ac x) = ac x"
shows "upd f x = x"
using uac
by (simp add: ac iso_tuple_update_accessor_cong_assist_id [OF uac, unfolded id_def]
cong: update_accessor_congruence_unfoldE [OF uac])
lemma update_accessor_noop_compE:
assumes uac: "iso_tuple_update_accessor_cong_assist upd ac"
and ac: "f (ac x) = ac x"
shows "upd (g \<circ> f) x = upd g x"
by (simp add: ac cong: update_accessor_congruence_unfoldE[OF uac])
lemma update_accessor_cong_assist_idI:
"iso_tuple_update_accessor_cong_assist id id"
by (simp add: iso_tuple_update_accessor_cong_assist_def)
lemma update_accessor_cong_assist_triv:
"iso_tuple_update_accessor_cong_assist upd ac \<Longrightarrow>
iso_tuple_update_accessor_cong_assist upd ac"
by assumption
lemma update_accessor_accessor_eqE:
"iso_tuple_update_accessor_eq_assist upd ac v f v' x \<Longrightarrow> ac v = x"
by (simp add: iso_tuple_update_accessor_eq_assist_def)
lemma update_accessor_updator_eqE:
"iso_tuple_update_accessor_eq_assist upd ac v f v' x \<Longrightarrow> upd f v = v'"
by (simp add: iso_tuple_update_accessor_eq_assist_def)
lemma iso_tuple_update_accessor_eq_assist_idI:
"v' = f v \<Longrightarrow> iso_tuple_update_accessor_eq_assist id id v f v' v"
by (simp add: iso_tuple_update_accessor_eq_assist_def update_accessor_cong_assist_idI)
lemma iso_tuple_update_accessor_eq_assist_triv:
"iso_tuple_update_accessor_eq_assist upd ac v f v' x \<Longrightarrow>
iso_tuple_update_accessor_eq_assist upd ac v f v' x"
by assumption
lemma iso_tuple_update_accessor_cong_from_eq:
"iso_tuple_update_accessor_eq_assist upd ac v f v' x \<Longrightarrow>
iso_tuple_update_accessor_cong_assist upd ac"
by (simp add: iso_tuple_update_accessor_eq_assist_def)
lemma iso_tuple_surjective_proof_assistI:
"f x = y \<Longrightarrow> iso_tuple_surjective_proof_assist x y f"
by (simp add: iso_tuple_surjective_proof_assist_def)
lemma iso_tuple_surjective_proof_assist_idE:
"iso_tuple_surjective_proof_assist x y id \<Longrightarrow> x = y"
by (simp add: iso_tuple_surjective_proof_assist_def)
locale isomorphic_tuple =
fixes isom :: "('a, 'b, 'c) tuple_isomorphism"
assumes repr_inv: "\<And>x. abst isom (repr isom x) = x"
and abst_inv: "\<And>y. repr isom (abst isom y) = y"
begin
lemma repr_inj: "repr isom x = repr isom y \<longleftrightarrow> x = y"
by (auto dest: arg_cong [of "repr isom x" "repr isom y" "abst isom"]
simp add: repr_inv)
lemma abst_inj: "abst isom x = abst isom y \<longleftrightarrow> x = y"
by (auto dest: arg_cong [of "abst isom x" "abst isom y" "repr isom"]
simp add: abst_inv)
lemmas simps = Let_def repr_inv abst_inv repr_inj abst_inj
lemma iso_tuple_access_update_fst_fst:
"f \<circ> h g = j \<circ> f \<Longrightarrow>
(f \<circ> iso_tuple_fst isom) \<circ> (iso_tuple_fst_update isom \<circ> h) g =
j \<circ> (f \<circ> iso_tuple_fst isom)"
by (clarsimp simp: iso_tuple_fst_update_def iso_tuple_fst_def simps
fun_eq_iff)
lemma iso_tuple_access_update_snd_snd:
"f \<circ> h g = j \<circ> f \<Longrightarrow>
(f \<circ> iso_tuple_snd isom) \<circ> (iso_tuple_snd_update isom \<circ> h) g =
j \<circ> (f \<circ> iso_tuple_snd isom)"
by (clarsimp simp: iso_tuple_snd_update_def iso_tuple_snd_def simps
fun_eq_iff)
lemma iso_tuple_access_update_fst_snd:
"(f \<circ> iso_tuple_fst isom) \<circ> (iso_tuple_snd_update isom \<circ> h) g =
id \<circ> (f \<circ> iso_tuple_fst isom)"
by (clarsimp simp: iso_tuple_snd_update_def iso_tuple_fst_def simps
fun_eq_iff)
lemma iso_tuple_access_update_snd_fst:
"(f \<circ> iso_tuple_snd isom) \<circ> (iso_tuple_fst_update isom \<circ> h) g =
id \<circ> (f \<circ> iso_tuple_snd isom)"
by (clarsimp simp: iso_tuple_fst_update_def iso_tuple_snd_def simps
fun_eq_iff)
lemma iso_tuple_update_swap_fst_fst:
"h f \<circ> j g = j g \<circ> h f \<Longrightarrow>
(iso_tuple_fst_update isom \<circ> h) f \<circ> (iso_tuple_fst_update isom \<circ> j) g =
(iso_tuple_fst_update isom \<circ> j) g \<circ> (iso_tuple_fst_update isom \<circ> h) f"
by (clarsimp simp: iso_tuple_fst_update_def simps apfst_compose fun_eq_iff)
lemma iso_tuple_update_swap_snd_snd:
"h f \<circ> j g = j g \<circ> h f \<Longrightarrow>
(iso_tuple_snd_update isom \<circ> h) f \<circ> (iso_tuple_snd_update isom \<circ> j) g =
(iso_tuple_snd_update isom \<circ> j) g \<circ> (iso_tuple_snd_update isom \<circ> h) f"
by (clarsimp simp: iso_tuple_snd_update_def simps apsnd_compose fun_eq_iff)
lemma iso_tuple_update_swap_fst_snd:
"(iso_tuple_snd_update isom \<circ> h) f \<circ> (iso_tuple_fst_update isom \<circ> j) g =
(iso_tuple_fst_update isom \<circ> j) g \<circ> (iso_tuple_snd_update isom \<circ> h) f"
by (clarsimp simp: iso_tuple_fst_update_def iso_tuple_snd_update_def
simps fun_eq_iff)
lemma iso_tuple_update_swap_snd_fst:
"(iso_tuple_fst_update isom \<circ> h) f \<circ> (iso_tuple_snd_update isom \<circ> j) g =
(iso_tuple_snd_update isom \<circ> j) g \<circ> (iso_tuple_fst_update isom \<circ> h) f"
by (clarsimp simp: iso_tuple_fst_update_def iso_tuple_snd_update_def simps
fun_eq_iff)
lemma iso_tuple_update_compose_fst_fst:
"h f \<circ> j g = k (f \<circ> g) \<Longrightarrow>
(iso_tuple_fst_update isom \<circ> h) f \<circ> (iso_tuple_fst_update isom \<circ> j) g =
(iso_tuple_fst_update isom \<circ> k) (f \<circ> g)"
by (clarsimp simp: iso_tuple_fst_update_def simps apfst_compose fun_eq_iff)
lemma iso_tuple_update_compose_snd_snd:
"h f \<circ> j g = k (f \<circ> g) \<Longrightarrow>
(iso_tuple_snd_update isom \<circ> h) f \<circ> (iso_tuple_snd_update isom \<circ> j) g =
(iso_tuple_snd_update isom \<circ> k) (f \<circ> g)"
by (clarsimp simp: iso_tuple_snd_update_def simps apsnd_compose fun_eq_iff)
lemma iso_tuple_surjective_proof_assist_step:
"iso_tuple_surjective_proof_assist v a (iso_tuple_fst isom \<circ> f) \<Longrightarrow>
iso_tuple_surjective_proof_assist v b (iso_tuple_snd isom \<circ> f) \<Longrightarrow>
iso_tuple_surjective_proof_assist v (iso_tuple_cons isom a b) f"
by (clarsimp simp: iso_tuple_surjective_proof_assist_def simps
iso_tuple_fst_def iso_tuple_snd_def iso_tuple_cons_def)
lemma iso_tuple_fst_update_accessor_cong_assist:
assumes "iso_tuple_update_accessor_cong_assist f g"
shows "iso_tuple_update_accessor_cong_assist
(iso_tuple_fst_update isom \<circ> f) (g \<circ> iso_tuple_fst isom)"
proof -
from assms have "f id = id"
by (rule iso_tuple_update_accessor_cong_assist_id)
with assms show ?thesis
by (clarsimp simp: iso_tuple_update_accessor_cong_assist_def simps
iso_tuple_fst_update_def iso_tuple_fst_def)
qed
lemma iso_tuple_snd_update_accessor_cong_assist:
assumes "iso_tuple_update_accessor_cong_assist f g"
shows "iso_tuple_update_accessor_cong_assist
(iso_tuple_snd_update isom \<circ> f) (g \<circ> iso_tuple_snd isom)"
proof -
from assms have "f id = id"
by (rule iso_tuple_update_accessor_cong_assist_id)
with assms show ?thesis
by (clarsimp simp: iso_tuple_update_accessor_cong_assist_def simps
iso_tuple_snd_update_def iso_tuple_snd_def)
qed
lemma iso_tuple_fst_update_accessor_eq_assist:
assumes "iso_tuple_update_accessor_eq_assist f g a u a' v"
shows "iso_tuple_update_accessor_eq_assist
(iso_tuple_fst_update isom \<circ> f) (g \<circ> iso_tuple_fst isom)
(iso_tuple_cons isom a b) u (iso_tuple_cons isom a' b) v"
proof -
from assms have "f id = id"
by (auto simp add: iso_tuple_update_accessor_eq_assist_def
intro: iso_tuple_update_accessor_cong_assist_id)
with assms show ?thesis
by (clarsimp simp: iso_tuple_update_accessor_eq_assist_def
iso_tuple_fst_update_def iso_tuple_fst_def
iso_tuple_update_accessor_cong_assist_def iso_tuple_cons_def simps)
qed
lemma iso_tuple_snd_update_accessor_eq_assist:
assumes "iso_tuple_update_accessor_eq_assist f g b u b' v"
shows "iso_tuple_update_accessor_eq_assist
(iso_tuple_snd_update isom \<circ> f) (g \<circ> iso_tuple_snd isom)
(iso_tuple_cons isom a b) u (iso_tuple_cons isom a b') v"
proof -
from assms have "f id = id"
by (auto simp add: iso_tuple_update_accessor_eq_assist_def
intro: iso_tuple_update_accessor_cong_assist_id)
with assms show ?thesis
by (clarsimp simp: iso_tuple_update_accessor_eq_assist_def
iso_tuple_snd_update_def iso_tuple_snd_def
iso_tuple_update_accessor_cong_assist_def iso_tuple_cons_def simps)
qed
lemma iso_tuple_cons_conj_eqI:
"a = c \<and> b = d \<and> P \<longleftrightarrow> Q \<Longrightarrow>
iso_tuple_cons isom a b = iso_tuple_cons isom c d \<and> P \<longleftrightarrow> Q"
by (clarsimp simp: iso_tuple_cons_def simps)
lemmas intros =
iso_tuple_access_update_fst_fst
iso_tuple_access_update_snd_snd
iso_tuple_access_update_fst_snd
iso_tuple_access_update_snd_fst
iso_tuple_update_swap_fst_fst
iso_tuple_update_swap_snd_snd
iso_tuple_update_swap_fst_snd
iso_tuple_update_swap_snd_fst
iso_tuple_update_compose_fst_fst
iso_tuple_update_compose_snd_snd
iso_tuple_surjective_proof_assist_step
iso_tuple_fst_update_accessor_eq_assist
iso_tuple_snd_update_accessor_eq_assist
iso_tuple_fst_update_accessor_cong_assist
iso_tuple_snd_update_accessor_cong_assist
iso_tuple_cons_conj_eqI
end
lemma isomorphic_tuple_intro:
fixes repr abst
assumes repr_inj: "\<And>x y. repr x = repr y \<longleftrightarrow> x = y"
and abst_inv: "\<And>z. repr (abst z) = z"
and v: "v \<equiv> Tuple_Isomorphism repr abst"
shows "isomorphic_tuple v"
proof
fix x have "repr (abst (repr x)) = repr x"
by (simp add: abst_inv)
then show "Test.abst v (Test.repr v x) = x"
by (simp add: v repr_inj)
next
fix y
show "Test.repr v (Test.abst v y) = y"
by (simp add: v) (fact abst_inv)
qed
definition
"tuple_iso_tuple \<equiv> Tuple_Isomorphism id id"
lemma tuple_iso_tuple:
"isomorphic_tuple tuple_iso_tuple"
by (simp add: isomorphic_tuple_intro [OF _ _ reflexive] tuple_iso_tuple_def)
lemma refl_conj_eq: "Q = R \<Longrightarrow> P \<and> Q \<longleftrightarrow> P \<and> R"
by simp
lemma iso_tuple_UNIV_I: "x \<in> UNIV \<equiv> True"
by simp
lemma iso_tuple_True_simp: "(True \<Longrightarrow> PROP P) \<equiv> PROP P"
by simp
lemma prop_subst: "s = t \<Longrightarrow> PROP P t \<Longrightarrow> PROP P s"
by simp
lemma K_record_comp: "(\<lambda>x. c) \<circ> f = (\<lambda>x. c)"
by (simp add: comp_def)
subsection \<open>Concrete record syntax\<close>
nonterminal
ident and
field_type and
field_types and
field and
fields and
field_update and
field_updates
syntax
"_constify" :: "id => ident" ("_")
"_constify" :: "longid => ident" ("_")
"_field_type" :: "ident => type => field_type" ("(2_ ::/ _)")
"" :: "field_type => field_types" ("_")
"_field_types" :: "field_type => field_types => field_types" ("_,/ _")
"_record_type" :: "field_types => type" ("(3\<lparr>_\<rparr>)")
"_record_type_scheme" :: "field_types => type => type" ("(3\<lparr>_,/ (2\<dots> ::/ _)\<rparr>)")
"_field" :: "ident => 'a => field" ("(2_ =/ _)")
"" :: "field => fields" ("_")
"_fields" :: "field => fields => fields" ("_,/ _")
"_record" :: "fields => 'a" ("(3\<lparr>_\<rparr>)")
"_record_scheme" :: "fields => 'a => 'a" ("(3\<lparr>_,/ (2\<dots> =/ _)\<rparr>)")
"_field_update" :: "ident => 'a => field_update" ("(2_ :=/ _)")
"" :: "field_update => field_updates" ("_")
"_field_updates" :: "field_update => field_updates => field_updates" ("_,/ _")
"_record_update" :: "'a => field_updates => 'b" ("_/(3\<lparr>_\<rparr>)" [900, 0] 900)
syntax (ASCII)
"_record_type" :: "field_types => type" ("(3'(| _ |'))")
"_record_type_scheme" :: "field_types => type => type" ("(3'(| _,/ (2... ::/ _) |'))")
"_record" :: "fields => 'a" ("(3'(| _ |'))")
"_record_scheme" :: "fields => 'a => 'a" ("(3'(| _,/ (2... =/ _) |'))")
"_record_update" :: "'a => field_updates => 'b" ("_/(3'(| _ |'))" [900, 0] 900)
subsection \<open>Record package\<close>
ML_file "test.ML"
hide_const (open) Tuple_Isomorphism repr abst iso_tuple_fst iso_tuple_snd
iso_tuple_fst_update iso_tuple_snd_update iso_tuple_cons
iso_tuple_surjective_proof_assist iso_tuple_update_accessor_cong_assist
iso_tuple_update_accessor_eq_assist tuple_iso_tuple
end

File diff suppressed because it is too large Load Diff

View File

@ -1132,13 +1132,10 @@ fun ML_isa_elaborate_generic (_:theory) isa_name ty term_option _ =
NONE => error("Wrong term option. You must use a defined term")
| SOME term => Const (isa_name, ty) $ term
(* Convert excluded mixfix symbols.
Unfortunately due to different lexical conventions for constant symbols and mixfix symbols
we can not use "_" or "'" for classes names in term antiquotation.
We chose to convert the excluded characters to "-". *)
val clean_string = translate_string
(fn "_" => "-"
| "'" => "-"
(* Convert some excluded mixfix symbols that can appear in an inner syntax name. *)
val clean_mixfix = translate_string
(fn "_" => "'_"
| "'" => "''"
| c => c);
fun rm_mixfix name mixfix thy =
@ -1177,8 +1174,8 @@ fun declare_ISA_class_accessor_and_check_instance (doc_class_name, bind_pos) thy
|> pair bind_pos |> swap |> Binding.make
val const_typ = \<^typ>\<open>string\<close> --> Syntax.read_typ (Proof_Context.init_global thy) doc_class_name
fun mixfix_enclose name = name |> enclose "@{" " _}"
val mixfix = clean_string bname |> mixfix_enclose
val mixfix' = clean_string doc_class_name |> mixfix_enclose
val mixfix = clean_mixfix bname |> mixfix_enclose
val mixfix' = clean_mixfix doc_class_name |> mixfix_enclose
in
thy |> rm_mixfix bname' mixfix
|> Sign.add_consts [(bind, const_typ, Mixfix.mixfix mixfix)]
@ -1216,8 +1213,8 @@ fun declare_class_instances_annotation (doc_class_name, bind_pos) thy =
|> suffix instances_of_suffixN |> pair bind_pos |> swap |> Binding.make
val class_typ = doc_class_name |> Proof_Context.read_typ (Proof_Context.init_global thy)
fun mixfix_enclose name = name |> enclose "@{" "}"
val mixfix = clean_string (bname ^ instances_of_suffixN) |> mixfix_enclose
val mixfix' = clean_string (doc_class_name ^ instances_of_suffixN) |> mixfix_enclose
val mixfix = clean_mixfix (bname ^ instances_of_suffixN) |> mixfix_enclose
val mixfix' = clean_mixfix (doc_class_name ^ instances_of_suffixN) |> mixfix_enclose
in
thy |> rm_mixfix bname' mixfix
|> Sign.add_consts [(bind, \<^Type>\<open>list class_typ\<close>, Mixfix.mixfix mixfix)]

View File

@ -451,7 +451,7 @@ text*[cc_assumption_test_ref::cc_assumption_test]\<open>\<close>
definition tag_l :: "'a \<Rightarrow> 'b \<Rightarrow> 'b" where "tag_l \<equiv> \<lambda>x y. y"
lemma* tagged : "tag_l @{cc-assumption-test \<open>cc_assumption_test_ref\<close>} AA \<Longrightarrow> AA"
lemma* tagged : "tag_l @{cc_assumption_test \<open>cc_assumption_test_ref\<close>} AA \<Longrightarrow> AA"
by (simp add: tag_l_def)
find_theorems name:tagged "(_::cc_assumption_test \<Rightarrow> _ \<Rightarrow> _) _ _ \<Longrightarrow>_"
@ -463,7 +463,7 @@ b::int
text*[b::B'_test']\<open>\<close>
term*\<open>@{B--test- \<open>b\<close>}\<close>
term*\<open>@{B'_test' \<open>b\<close>}\<close>
declare_reference*["text-elements-expls"::technical]
(*>*)
@ -484,19 +484,6 @@ text\<open>
\<close>
For a declared class \<^theory_text>\<open>cid\<close>, there exists a term-antiquotation of the form \<^theory_text>\<open>@{cid \<open>oid\<close>}\<close>.
Due to implementation of term-antiquotation using mixfix annotation
(see @{cite "wenzel:isabelle-isar:2020"}),
should a class \<open>cid\<close> contains an underscore or a single quote,
they will be converted to hyphens in the term-antiquotation.
For example:
@{boxed_theory_text [display]
\<open>doc_class B'_test' =
b::int
text*[b::B'_test']\<open>\<close>
term*\<open>@{B--test- \<open>b\<close>}\<close>\<close>}
The major commands providing term-contexts are\<^footnote>\<open>The meta-argument list is optional.\<close>
\<^item> \<^theory_text>\<open>term*[oid::cid, ...] \<open> \<dots> HOL-term \<dots> \<close>\<close>,
\<^item> \<^theory_text>\<open>value*[oid::cid, ...] \<open> \<dots> HOL-term \<dots> \<close>\<close>, and
@ -561,7 +548,7 @@ lemma* tagged : "tag_l @{cc-assumption-test \<open>cc_assumption_test_ref\<close
find_theorems name:tagged "(_::cc_assumption_test \<Rightarrow> _ \<Rightarrow> _) _ _ \<Longrightarrow>_"\<close>}
In this example, the definition \<^const>\<open>tag_l\<close> adds a tag to the \<open>tagged\<close> lemma using
the term-antiquotation @{term_ [source] \<open>@{cc-assumption-test \<open>cc_assumption_test_ref\<close>}\<close>}
the term-antiquotation @{term_ [source] \<open>@{cc_assumption_test \<open>cc_assumption_test_ref\<close>}\<close>}
inside the \<open>prop\<close> declaration.
Note unspecified attribute values were represented by free fresh variables which constrains \<^dof>