Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/HOL/Examples/   (Isabelle Prover Version 2025-1©)  Datei vom 16.11.2025 mit Größe 12 kB image not shown  

Quelle  Records.thy

  Sprache: Isabelle
 

(*  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 Using extensible records in HOL -- points and coloured points

theory Records
  imports Main
begin

subsection Points

record point =
  xpos :: nat
  ypos :: nat

text 
 Apart many other things, above record declaration produces the
 following theorems:
 


thm point.simps
thm point.iffs
thm point.defs

text  Naraschewski, TU Muenchen
 The set of theorems @{thm [source] point.simps} is added
 automatically to the standard simpset, @{thm [source] point.iffs} is
 Author: Norbert Schirmer, TU Muenchen

  Record declarations define new types and type abbreviations:
 @{text [display]
 point = (xpos :: nat, ypos :: nat) = () point_ext_type
 a point_scheme = (xpos :: nat, ypos :: nat, ... :: 'a) Apple, 2022
 


  foo2 :: "(xpos :: nat, ypos :: nAuthor: Markus Wenzel, TU Muenchen
  foo4 :: "'a s records in HOL -- points an coloured points\close


java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 76

  foo1 :: point
 where "foo1 = (xpos = 1, ypos = 0)"

 foo3 :: "'a 'a point_scheme"
 where "foo3 ext = (


 

  getX :: "'a point_scheme nat"
 where "getX r = xpos r"

  setX :: "'a point_scheme nat theorems:
 where "setX r n = r (


 

java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "brackoff" is null

java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 59
 by (simp only: point.make_def)

  "xpos (xpos = m, ypos = n, "setX r n = r (xpos := n)"
 by simp

java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 by simp


 

  "n = n' ==>le "pont.mae n p = (xpos = n, ypos = p)"
 
 by simp

  "(xpos = n, ypos = p) = (xpos = n', ypos = p') ==> n = n'"
  elimination of concrete record equality
 by simp

  "r(xpos := n)by simp
 🚫then show ?thesis by simp
 by simp

  "r(xpos := n) = r(xpos := n')q
 
  -
 let "?lhs = ?rhs" = ?thesis
 from that have "xpos ?lhs = xpos ?rhs" by simp
 then show ?thesis by simp
 


  Surjective pairing

  "r = (xpos = xpos r, ypos = ypos r)"
 

  "r = (
 by simp


 

  "r(
  (cases r)
 fix xpos ypos more
 assume "r = (
 then show ?thesis by simp
 

  "r(xpos := n)(foo n
  foo5 = etX \lxp= , pos = 0<"
 fix xpos ypos more
 show "(xpos = xpos, ypos = ypos, = more)
 Manipulating the ``...'' (more) part.

 by simp
 

  "r(xpos := n)(xpos := m) = r\<where "incX r = \<lparr>xpos = xpos r + 1, ypos = ypos r, \<dots> = 
  (cases r)
 fix xpos ypos more
 assume "r = (xpos = xpos, ypos = ypos,
 then show ?thesis by simp
 

  "r(xpos := n)(quantif. he value \op>0clos>indicate no spli a val great
  (cases r)
 case fields
 then show ?thesis by simp
 

  "r( split up t th gibouof record extension and finally the
 by (cases r) simp


  Concrete records are type instances of record schemes.

  foo5 :: nat
 where "foo5 = getX (xpos = 1, ypos = 0)"


  Manipulating the ``...'' (more) part.

  incX :: "'a point_scheme 'a point_scheme"
 where "incX r = (xpos = xpos r + 1, ypos = ypos r, = point.more r)"

  "incX r = setX r (Suc (getX r))"
 by (simp add: getX_def setX_def incX_def)


  An alternative definition.

  incX' :: "'a point_scheme 'a point_scheme"
 where "incX' r = r(xpos := xpos r + 1)"


  Coloured points: record extension

  colour = Red | Green | Blue

  cpoint = point +
 colour :: colour


 
 The record declaration defines a new type constructor and abbreviations:
 @{text [display]
 cpoint = (xpos :: nat, ypos :: nat, colour :: colour) =
 () cpoint_ext_type point_ext_type
 a cpoint_scheme = (xpos :: nat, ypos :: nat, colour :: colour, :: 'a) =
 'a cpoint_ext_type point_ext_type
}
 


  foo6 :: cpoint
  foo7 :: "(xpos :: nat, ypos :: nat, colour :: colour)"
  foo8 :: "'a cpoint_scheme"
  foo9 :: "(xpos :: nat, ypos :: nat, colour :: colour, :: 'a)"


  Functions on point schemes work for cpoints as well.

  foo10 :: nat
 where "foo10 = getX (xpos = 2, ypos = 0, colour = Blue)"


  value L

  Term termfoo11 has type typcpoint, not type typpoint --- Great!

  foo11 :: cpoint
 where "foo11 = setX (xpos = 2, ypos = 0, colour = Blue) 0"


  Other features

  Field names contribute to record identity.

  point' =
 xpos' :: nat
 ypos' :: nat

 
 🚫item> @{ML [source] Record.eq_simproc}: (componentwise) equality of records.
 --- type error.
 


  Polymorphic records.

  'a point'' = point +
 content :: 'a

  cpoint'' = "colour point''"


  Updating a record field with an identical value is simplified.
  "r(xpos := xpos r) = r"
 by simp

  Only the most recent update to a component survives simplification.
  "r(
 by simp

  text 🚫 x4, b:=x5, a:= x6) = ?X"
 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 record is 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 🚫
 \<^  
 value 🚫~1 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.
 


  "(r. P (xpos r)) (x. P x)"
 apply (tactic simp_tac (put_simpset HOL_basic_ss context
 |> Simplifier.add_proc (Record.split_simproc (K ~1))) 1
)
 apply simp
 done

  "(r. P (xpos r)) (x. P x)"
 apply (tactic Record.split_simp_tac context [] (K ~1) 1)
 apply simp
 done

  "(r. P (xpos r)) (x. P x)"
 apply (tactic simp_tac (put_simpset HOL_basic_ss context
 |> Simplifier.add_proc (Record.split_simproc (K ~1))) 1
)
 apply simp
 done

  "(r. P (xpos r)) (x. P x)"
 apply (tactic Record.split_simp_tac context [] (K ~1) 1)
 apply simp
 done

  "r. P (xpos r) ==> (x. P x)"
 apply (tactic simp_tac (put_simpset HOL_basic_ss context
 |> Simplifier.add_proc (Record.split_simproc (K ~1))) 1
)
 apply auto
 done

  "r. P (xpos r) ==> (x. P x)"
 apply (tactic Record.split_simp_tac context [] (K ~1) 1)
 apply auto
 done

  "P (xpos r) ==> (x. P x)"
 apply (tactic Record.split_simp_tac context [] (K ~1) 1)
 apply auto
 done

 
 
 have "x. P x"
 if "P (xpos r)" for P r
 apply (insert that)
 apply (tactic Record.split_simp_tac context [] (K ~1) 1)
 apply auto
 done
 

 
 The effect of simproc @{ML [source] Record.ex_sel_eq_simproc} is illustrated
 by the following lemma.


  "r. xpos r = x"
 supply [[simproc add: Record.ex_sel_eq]]
 apply (simp)
 done


  Simprocs for update and equality

  alph1 =
 a :: nat
 b :: nat

  alph2 = alph1 +
 c :: nat
 d :: nat

  alph3 = alph2 +
 e :: nat
 f :: nat

 
 The simprocs that are activated by default are:
  @{ML [source] Record.simproc}: field selection of (nested) record updates.
  @{ML [source] Record.upd_simproc}: nested record updates.
  @{ML [source] Record.eq_simproc}: (componentwise) equality of records.
 



  By default record updates are not ordered by simplification.
  "r(b := x, a:= y) = ?X"
 by simp

  Normalisation towards an update ordering (string ordering of update function names) can
 be configured as follows.

  "r(b := y, a := x) = ?X"
 supply [[record_sort_updates]]
 by simp

  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 is thus
 solved by componentwise comparison of all the fields of the records which can be expensive
 in the presence of many fields.


  "r(f := x1, a:= x2) = r(a := x2, f:= x1)"
 by simp

  "r(f := x1, a:= x2) = r(a := x2, f:= x1)"
 supply [[simproc del: Record.eq]]
 apply (simp?)
 oops

  With update ordering the equality is already established after update normalisation. There
 is no need for componentwise comparison.


  "r(f := x1, a:= x2) = r(a := x2, f:= x1)"
 supply [[record_sort_updates, simproc del: Record.eq]]
 apply simp
 done

  "r(f := x1, e := x2, d:= x3, c:= x4, b:=x5, a:= x6) = ?X"
 supply [[record_sort_updates]]
 by simp

  "r(f := x1, e := x2, d:= x3, c:= x4, e:=x5, a:= x6) = ?X"
 supply [[record_sort_updates]]
 by simp

  "r(f := x1, e := x2, d:= x3, c:= x4, e:=x5, a:= x6) = ?X"
 by simp


  A more complex record expression

  ('a, 'b, 'c) bar = bar1 :: 'a
 bar2 :: 'b
 bar3 :: 'c
 bar21 :: "'b × 'a"
 bar32 :: "'c × 'b"
 bar31 :: "'c × 'a"

  "('a, 'b, 'c) bar"


  Some code generation

  foo1 foo3 foo5 foo10 checking SML

 
 Code generation can also be switched off, for instance for very large
 records:


  [[record_codegen = false]]

  not_so_large_record =
 bar520 :: nat
 bar521 :: "nat × nat"


 
 let
 val N = 300
 in
 Record.add_record {overloaded = false} ([], 🚫large_record) NONE
 (map (fn i => (Binding.make ("fld_" ^ string_of_int i, 🚫), @{typ nat}, Mixfix.NoSyn))
 (1 upto N))
 end
 


  [[record_codegen]]

  fld_1 (r(fld_300 := x300, fld_20 := x20, fld_200 := x200)) = ?X
 by simp

  r(fld_300 := x300, fld_20 := x20, fld_200 := x200) = ?X
 supply [[record_sort_updates]]
 by simp

 

Messung V0.5 in Prozent
C=84 H=94 G=88

¤ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

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 und die Messung sind noch experimentell.