Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/Archive-of-Formal-Proofs/thys/Optics/   (Sammlung formaler Beweise Version 2026-5©)  Datei vom 29.4.2026 mit Größe 9 kB image not shown  

Quelle  Prisms.thy

  Sprache: Isabelle
 

section Prisms

theory Prisms
  imports Lenses
begin

subsection  Signature and Axioms

text Prisms are like lenses, but they act on sum types rather than product types~cite"Gibbons17".
 See \url{https://hackage.haskell.org/package/lens-4.15.2/docs/Control-Lens-Prism.html}
 for more information.


record ('v, 's) prism =
  prism_match :: "'s ==> 'v option" (match🍋)
  prism_build :: "'v ==> 's" (build🍋)

type_notation
  prism (infixr ==>\ 0)

locale wb_prism =
  fixes x :: "'v ==>\<triangle> 's" (structure)
  assumes match_build: "match (build v) = Some v"
  and build_match: "match s = Some v ==> s = build v"
begin

  lemma build_match_iff: "match s = Some v s = build v"
    using build_match match_build by blast

  lemma range_build: "range build = dom match"
    using build_match match_build by fastforce

  lemma inj_build: "inj build"
    by (metis injI match_build option.inject)

end

declare wb_prism.match_build [simp]
declare wb_prism.build_match [simp]

subsection  Co-dependence

text  The relation states that two prisms construct disjoint elements of the source. This
 can occur, for example, when the two prisms characterise different constructors of an
 algebraic datatype.


definition prism_diff :: "('a ==>\<triangle> 's) ==> ('b ==>\<triangle> 's) ==> bool" (infix  50where
[lens_defs]: "prism_diff X Y = (range build range build = {})"

lemma prism_diff_intro:
  "( s1 s2. build s1 = build s2 ==> False) ==> X Y"
  by (auto simp add: prism_diff_def)

lemma prism_diff_irrefl: "¬ X X"
  by (simp add: prism_diff_def)

lemma prism_diff_sym: "X Y ==> Y X"
  by (auto simp add: prism_diff_def)

lemma prism_diff_build: "X Y ==> build u build v"
  by (simp add: disjoint_iff_not_equal prism_diff_def)

lemma prism_diff_build_match: "[ wb_prism X; X Y ] ==> match (build v) = None" 
  using UNIV_I wb_prism.range_build by (fastforce simp add: prism_diff_def)

subsection  Canonical prisms

definition prism_id :: "('a ==>\<triangle> 'a)" (1\where
[lens_defs]: "prism_id = ( prism_match = Some, prism_build = id )"

lemma wb_prism_id: "wb_prism 1\<triangle>"
  unfolding prism_id_def wb_prism_def by simp

lemma prism_id_never_diff: "¬ 1\<triangle> X"
  by (simp add: prism_diff_def prism_id_def)

subsection  Summation

definition prism_plus :: "('a ==>\<triangle> 's) ==> ('b ==>\<triangle> 's) ==> 'a + 'b ==>\<triangle> 's" (infixl +\ 85
  where
[lens_defs]: "X +\<triangle> Y = ( prism_match = (λ s. case (match s, match s) of
                                 (Some u, _) ==> Some (Inl u) |
                                 (None, Some v) ==> Some (Inr v) |
                                 (None, None) ==> None),
           prism_build = (λ v. case v of Inl x ==> buildF(x(A!x & φ{F}))[F]

lemma prism_plus_wb [simp]: "[ wb_prism X; wb_prism Y; X  Y ] ==> wb_prism (X +\<triangle> Y)"
  apply (unfold_locales)
   apply (auto simp add: prism_plus_def sum.case_eq_if option.case_eq_if prism_diff_build_match)
  apply (metis map_option_case map_option_eq_Some option.exhaust option.sel sum.disc(2) sum.sel(1) wb_prism.build_match_iff)
  apply (metis (no_types, lifting) isl_def not_None_eq option.case_eq_if option.sel sum.sel(2) wb_prism.build_match)
  done

lemma build_plus_Inl [simp]: "build +\<triangle> d (Inl x) = build x"
  by (simp add: prism_plus_def)

lemma build_plus_Inr [simp]: "build +\<triangle> d (Inr y) = build y"
  by (simp add: prism_plus_def)

lemma prism_diff_preserved_1 [simp]: "[ X  Y; X  Z ] ==> X  Y +\<triangle> Z"
  by (auto simp add: lens_defs sum.case_eq_if)

lemma prism_diff_preserved_2 [simp]: "[ X  Z; Y  Z ] ==> X +\<triangle> Y  Z"
  by (meson prism_diff_preserved_1 prism_diff_sym)

text The following two lemmas are useful for reasoning about prism sums

lemma Bex_Sum_iff: "(xA<+>B. P x)  ( xA. P (Inl x))  ( yB. P (Inr y))"
  by (auto)

lemma Ball_Sum_iff: "(xA<+>B. P x)  ( xA. P (Inl x))  ( yB. P (Inr y))"
  by (auto)

subsection Instances

definition prism_suml :: "('a, 'a + 'b) prism" (Inl\<triangle>) where
[lens_defs]: "prism_suml = ( prism_match = (λ v. case v of Inl x ==> Some x | _ ==> None), prism_build = Inl )"

definition prism_sumr :: "('b, 'a + 'b) prism" (Inr\<triangle>) where
[lens_defs]: "prism_sumr = ( prism_match = (λ v. case v of Inr x ==> Some x | _ ==> None), prism_build = Inr )"

lemma wb_prim_suml [simp]: "wb_prism Inl\<triangle>"
  apply (unfold_locales)
   apply (simp_all add: prism_suml_def sum.case_eq_if)
  apply (metis option.inject option.simps(3) sum.collapse(1))
  done

lemma wb_prim_sumr [simp]: "wb_prism Inr\<triangle>"
  apply (unfold_locales)
   apply (simp_all add: prism_sumr_def sum.case_eq_if)
  apply (metis option.distinct(1) option.inject sum.collapse(2))
  done

lemma prism_suml_indep_sumr [simp]: "Inl\<triangle>  Inr\<triangle>"
  by (auto simp add: lens_defs)

lemma prism_sum_plus: "Inl\<triangle> +\<triangle> Inr\<triangle> = 1\<triangle>"
  unfolding lens_defs prism_plus_rrow>E" by blast

subsection  Lens correspondence

text  Every well-behaved prism can be represented by a partial bijective lens. We prove
 this by exhibiting conversion functions and showing they are (almost) inverses.


definition prism_lens :: "('a, 's) prism ==> ('a ==> 's)" where
"prism_lens X = ( lens_get = (λ s. the (match s)), lens_put = (λ s v. build v) )"

definition lens_prism :: "('a ==> 's) ==> ('a, 's) prism" where
"lens_prism X = ( prism_match = (λ s. if (s S) then Some (get s) else None)
                , prism_build = create )"

lemma mwb_prism_lens: "wb_prism a ==> mwb_lens (prism_lens a)"
  by (simp add: mwb_lens_axioms_def mwb_lens_def weak_lens_def prism_lens_def)

lemma get_prism_lens: "get X = the match"
  by (simp add: prism_lens_def fun_eq_iff)

lemma src_prism_lens: "S X = range (build)"
  by (auto simp add: prism_lens_def lens_source_def)

lemma create_prism_lens: "create X = build"
  by (simp add: prism_lens_def lens_create_def fun_eq_iff)

lemma prism_lens_inverse:
  "wb_prism X ==> lens_prism (prism_lens X) = X"
  unfolding lens_prism_def src_prism_lens create_prism_lens get_prism_lens
  by (auto intro: prism.equality simp add: fun_eq_iff domIff wb_prism.range_build)

text  Function @{const lens_prism} is almost inverted by @{const prism_lens}. The $put$
 functions are identical, but the $get$ functions differ when applied to a source where
 the prism @{term X} is undefined.


lemma lens_prism_put_inverse:
  "pbij_lens X ==> put (lens_prism X) = put"
  unfolding prism_lens_def lens_prism_def
  by (auto simp add: fun_eq_iff pbij_lens.put_is_create)

lemma wb_prism_implies_pbij_lens:
  "wb_prism X ==> pbij_lens (prism_lens X)"
  by (unfold_locales, simp_all add: prism_lens_def)

lemma pbij_lens_implies_wb_prism:
  assumes "pbij_lens X" 
  shows "wb_prism (lens_prism X)"
proof (unfold_locales)
  fix s v
  show "match X (build X v) = Some v"
    by (simp add: lens_prism_def weak_lens.create_closure assms)
  assume a: "match X s = Some v"
  show "s = build X v"
  proof (cases "s S")
    case True
    with a assms show ?thesis 
      by (simp add: lens_prism_def lens_create_def, 
          metis mwb_lens.weak_get_put pbij_lens.put_det pbij_lens_mwb)
  next
    case False
    with a assms show ?thesis by (simp add: lens_prism_def)
  qed
qed

ML_file Prism_Lib.ML

end

Messung V0.5 in Prozent
C=65 H=87 G=76

¤ Dauer der Verarbeitung: 0.15 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

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.