(* Title: HOL/Examples/Records.thy Author: Wolfgang Naraschewski, TU Muenchen Author: Norbert Schirmer, TU Muenchen Author: Norbert Schirmer, Apple, 2022 Author: Markus Wenzel, TU Muenchen
*)
section \<open>Using extensible records in HOL -- points and coloured points\<close>
theory Records imports Main begin
subsection \<open>Points\<close>
record point =
xpos :: nat
ypos :: nat
text\<open>
Apart many other things, above recorddeclaration produces the
following theorems: \<close>
thm point.simps thm point.iffs thm point.defs
text\<open>
The set of theorems @{thm [source] point.simps} is added
automatically to the standard simpset, @{thm [source] point.iffs} is
added to the Classical Reasoner and Simplifier context.
\<^medskip> Record declarations define new types and type abbreviations:
@{text [display] \<open>point = \<lparr>xpos :: nat, ypos :: nat\<rparr> = () point_ext_type 'a point_scheme = \xpos :: nat, ypos :: nat, ... :: 'a\ = 'a point_ext_type\} \<close>
text\<open>Updating a record field with an identical value is simplified.\<close> lemma"r\xpos := xpos r\ = r" by simp
text\<open>Only the most recent update to a component survives simplification.\<close> lemma"r\xpos := x, ypos := y, xpos := x'\ = r\ypos := y, xpos := x'\" by simp
text\<open> In some cases its convenient to automatically split (quantified) records. For this purpose there is the simproc @{ML [source] "Record.split_simproc"} and the tactic @{ML [source] "Record.split_simp_tac"}. The simplification
procedure only splits the records, whereas the tactic also simplifies the
resulting goal with the standard record simplification rules. A
(generalized) predicate on the recordis passed as parameter that decides
whether or how `deep' to split the record. It can peek on the subterm
starting at the quantified occurrence of the record (including the
quantifier). The value\<^ML>\<open>0\<close> indicates no split, a value greater \<^ML>\<open>0\<close> splits up to the given bound of record extension and finally the value\<^ML>\<open>~1\<close> completely splits the record. @{ML [source] "Record.split_simp_tac"} additionally takes a list of equations for
simplification and can also split fixed record variables. \<close>
lemma"(\r. P (xpos r)) \ (\x. P x)" apply (tactic \<open>Record.split_simp_tac \<^context> [] (K ~1) 1\<close>) apply simp done
lemma"\r. P (xpos r) \ (\x. P x)" apply (tactic \<open>simp_tac (put_simpset HOL_basic_ss \<^context>
|> Simplifier.add_proc (Record.split_simproc (K ~1))) 1\<close>) apply auto done
lemma"\r. P (xpos r) \ (\x. P x)" apply (tactic \<open>Record.split_simp_tac \<^context> [] (K ~1) 1\<close>) apply auto done
lemma"P (xpos r) \ (\x. P x)" apply (tactic \<open>Record.split_simp_tac \<^context> [] (K ~1) 1\<close>) apply auto done
notepad begin have"\x. P x" if"P (xpos r)"for P r apply (insert that) apply (tactic \<open>Record.split_simp_tac \<^context> [] (K ~1) 1\<close>) apply auto done end
text\<open>
The effect of simproc @{ML [source] Record.ex_sel_eq_simproc} is illustrated by the following lemma.\<close>
subsection \<open>Simprocs for update and equality\<close>
record alph1 =
a :: nat
b :: nat
record alph2 = alph1 +
c :: nat
d :: nat
record alph3 = alph2 +
e :: nat
f :: nat
text\<open>
The simprocs that are activated by default are: \<^item> @{ML [source] Record.simproc}: field selection of (nested) record updates. \<^item> @{ML [source] Record.upd_simproc}: nested record updates. \<^item> @{ML [source] Record.eq_simproc}: (componentwise) equality of records. \<close>
text\<open>By default record updates are not ordered by simplification.\<close>
schematic_goal "r\b := x, a:= y\ = ?X" by simp
text\<open>Normalisation towards an update ordering (string ordering of update function names) can
be configured as follows.\<close>
schematic_goal "r\b := y, a := x\ = ?X"
supply [[record_sort_updates]] by simp
text\<open>Note the interplay between update ordering and record equality. Without update ordering
the following equality is handled by @{ML [source] Record.eq_simproc}. Record equality isthus
solved by componentwise comparison of all the fields of the records which can be expensive in the presence of many fields.\<close>
setup\<open> let
val N = 300 in Record.add_record {overloaded = false} ([], \<^binding>\<open>large_record\<close>) NONE
(map (fn i => (Binding.make ("fld_" ^ string_of_int i, \<^here>), @{typ nat}, Mixfix.NoSyn))
(1 upto N)) end \<close>
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.16Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.