Theory Equality_Generator

theory Equality_Generator
imports Generator_Aux Derive_Manager
(*  Title:       Deriving class instances for datatypes
    Author:      Christian Sternagel and René Thiemann  <christian.sternagel|rene.thiemann@uibk.ac.at>
    Maintainer:  Christian Sternagel and René Thiemann 
    License:     LGPL
*)
section ‹Checking Equality Without "="›

theory Equality_Generator
imports
  "../Generator_Aux"
  "../Derive_Manager"
begin

typedecl ('a,'b,'c,'z)type

text ‹In the following, we define a generator which for a given datatype @{typ "('a,'b,'c,'z)type"}
  constructs an equality-test function of type 
  @{typ "('a ⇒ 'a ⇒ bool) ⇒ ('b ⇒ 'b ⇒ bool) ⇒ ('c ⇒ 'c ⇒ bool) ⇒ ('z ⇒ 'z ⇒ bool) ⇒ 
    (('a,'b,'c,'z)type ⇒ ('a,'b,'c,'z)type ⇒ bool)"}.
  These functions are essential to synthesize conditional equality functions in the container framework,
  where a strict membership in the @{class equal}-class must not be enforced.
›

hide_type "type"

text ‹Just a constant to define conjunction on lists of booleans, which will
  be used to merge the results when having compared the arguments of identical
  constructors.›

definition list_all_eq :: "bool list ⇒ bool" where
  "list_all_eq = list_all id "

subsection ‹Improved Code for Non-Lazy Languages›

text ‹The following equations will eliminate all occurrences of @{term list_all_eq}
  in the generated code of the equality functions.›

lemma list_all_eq_unfold: 
  "list_all_eq [] = True"
  "list_all_eq [b] = b"
  "list_all_eq (b1 # b2 # bs) = (b1 ∧ list_all_eq (b2 # bs))"
  unfolding list_all_eq_def
  by auto

lemma list_all_eq: "list_all_eq bs ⟷ (∀ b ∈ set bs. b)" 
  unfolding list_all_eq_def list_all_iff by auto  

subsection ‹Partial Equality Property›

text ‹We require a partial property which can be used in inductive proofs.›

type_synonym 'a equality = "'a ⇒ 'a ⇒ bool"

definition pequality :: "'a equality ⇒ 'a ⇒ bool"
where
  "pequality aeq x ⟷ (∀ y. aeq x y ⟷ x = y)"

lemma pequalityD: "pequality aeq x ⟹ aeq x y ⟷ x = y"
  unfolding pequality_def by auto

lemma pequalityI: "(⋀ y. aeq x y ⟷ x = y) ⟹ pequality aeq x"
  unfolding pequality_def by auto


subsection ‹Global equality property›

definition equality :: "'a equality ⇒ bool" where
  "equality aeq ⟷ (∀ x. pequality aeq x)"

lemma equalityD2: "equality aeq ⟹ pequality aeq x"
  unfolding equality_def by blast

lemma equalityI2: "(⋀ x. pequality aeq x) ⟹ equality aeq" 
  unfolding equality_def by blast
    
lemma equalityD: "equality aeq ⟹ aeq x y ⟷ x = y"
  by (rule pequalityD[OF equalityD2])

lemma equalityI: "(⋀ x y. aeq x y ⟷ x = y) ⟹ equality aeq"
  by (intro equalityI2 pequalityI)

lemma equality_imp_eq:
  "equality aeq ⟹ aeq = (=)" 
  by (intro ext, auto dest: equalityD)

lemma eq_equality: "equality (=)"
  by (rule equalityI, simp)

lemma equality_def': "equality f = (f = (=))" 
  using equality_imp_eq eq_equality by blast


subsection ‹The Generator›

ML_file ‹equality_generator.ML›

hide_fact (open) equalityI

end