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

Quelle  Fixpoints.thy

  Sprache: Isabelle
 

(* Author: Andreas Lochbihler, ETH Zurich
   Author: Joshua Schneider, ETH Zurich *)


section Least and greatest fixpoints

theory Fixpoints imports
  Axiomatised_BNF_CC
begin

subsection Least fixpoint

subsubsection \BNFCC{} structure

context notes [[typedef_overloaded, bnf_internals]]
begin

datatype (set_T: 'l1, 'co1, 'co2, 'contra1, 'contra2, 'f) T =
  C_T (D_T: "(('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) T, 'l1, 'co1, 'co2, 'contra1, 'contra2, 'f) G")
  for
    map: mapl_T
    rel: rell_T

end

inductive rel_T :: "('l1 ==> 'l1' ==> bool) ==>
    ('co1 ==> 'co1' ==> bool) ==> ('co2 ==> 'co2' ==> bool) ==>
    ('contra1 ==> 'contra1' ==> bool) ==> ('contra2 ==> 'contra2' ==> bool) ==>
    ('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) T ==>
    ('l1', 'co1', 'co2', 'contra1', 'contra2', 'f) T ==> bool"
  for L1 Co1 Co2 Contra1 Contra2 where
  "rel_T L1 Co1 Co2 Contra1 Contra2 (C_T x) (C_T y)"
    if "rel_G (rel_T L1 Co1 Co2 Contra1 Contra2) L1 Co1 Co2 Contra1 Contra2 x y"

primrec map_T :: "('l1 ==> 'l1') ==> ('co1 ==> 'co1') ==> ('co2 ==> 'co2') ==>
    ('contra1' ==> 'contra1) ==> ('contra2' ==> 'contra2) ==>
    ('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) T ==>
    ('l1', 'co1', 'co2', 'contra1', 'contra2', 'f) T" where
  "map_T l1 co1 co2 contra1 contra2 (C_T x) =
    C_T (map_G id id co1 co2 contra1 contra2 (mapl_G (map_T l1 co1 co2 contra1 contra2) l1 x))"

text 
 The mapper and relator generated by the datatype package coincide with our generalised definitions
 restricted to live arguments.
 


lemma rell_T_alt_def: "rell_T L1 = rel_T L1 (=) (=) (=) (=)"
  apply (intro ext iffI)
   apply (erule T.rel_induct)
   apply (unfold rell_G_def)
   apply (erule rel_T.intros)
  apply (erule rel_T.induct)
  apply (rule T.rel_intros)
  apply (unfold rell_G_def)
  apply (erule rel_G_mono')
       apply (auto)
  done

lemma mapl_T_alt_def: "mapl_T l1 = map_T l1 id id id id"
  supply id_apply[simp del]
  apply (rule ext)
  subgoal for x
    apply (induction x)
    apply (simp add: mapl_G_def map_G_comp[THEN fun_cong, simplified])
    apply (fold mapl_G_def)
    apply (erule mapl_G_cong)
    apply (rule refl)
    done
  done

lemma rel_T_mono [mono]:
  "[ L1 L1'; Co1 Co1'; Co2 Co2'; Contra1' Contra1; Contra2' Contra2 ] ==>
  rel_T L1 Co1 Co2 Contra1 Contra2 rel_T L1' Co1' Co2' Contra1' Contra2'"
  apply (rule predicate2I)
  apply (erule rel_T.induct)
  apply (rule rel_T.intros)
  apply (erule rel_G_mono')
       apply (auto)
  done

lemma rel_T_eq: "rel_T (=) (=) (=) (=) (=) = (=)"
  unfolding rell_T_alt_def[symmetric] T.rel_eq ..

lemma rel_T_conversep:
  "rel_T L1-1-1 Co1-1-1 Co2-1-1 Contra1-1-1 Contra2-1-1 = (rel_T L1 Co1 Co2 Contra1 Contra2)-1-1"
  apply (intro ext iffI)
   apply (simp)
   apply (erule rel_T.induct)
   apply (rule rel_T.intros)
   apply (rewrite conversep_iff[symmetric])
   apply (fold rel_G_conversep)
   apply (erule rel_G_mono'; blast)
  apply (simp)
  apply (erule rel_T.induct)
  apply (rule rel_T.intros)
  apply (rewrite conversep_iff[symmetric])
  apply (unfold rel_G_conversep[symmetric] conversep_conversep)
  apply (erule rel_G_mono'; blast)
  done

lemma map_T_id0: "map_T id id id id id = id"
  unfolding mapl_T_alt_def[symmetric] T.map_id0 ..

lemma map_T_id: "map_T id id id id id x = x"
  by (simp add: map_T_id0)

lemma map_T_comp: "map_T l1 co1 co2 contra1 contra2 map_T l1' co1' co2' contra1' contra2' =
  map_T (l1 l1') (co1 co1') (co2 co2') (contra1' contra1) (contra2' contra2)"
  apply (rule ext)
  subgoal for x
    apply (induction x)
    apply (simp add: mapl_G_def map_G_comp[THEN fun_cong, simplified])
    apply (fold comp_def)
    apply (subst (1 2) map_G_mapl_G)
    apply (rule arg_cong[where f="map_G _ _ _ _ _ _"])
    apply (rule mapl_G_cong)
     apply (simp_all)
    done
  done

lemma map_T_parametric: "rel_fun (rel_fun L1 L1')
  (rel_fun (rel_fun Co1 Co1') (rel_fun (rel_fun Co2 Co2')
  (rel_fun (rel_fun Contra1' Contra1) (rel_fun (rel_fun Contra2' Contra2)
  (rel_fun (rel_T L1 Co1 Co2 Contra1 Contra2) (rel_T L1' Co1' Co2' Contra1' Contra2'))))))
  map_T map_T"
  apply (intro rel_funI)
  apply (erule rel_T.induct)
  apply (simp)
  apply (rule rel_T.intros)
  apply (fold map_G_mapl_G)
  apply (erule map_G_rel_cong)
       apply (blast elim: rel_funE)+
  done

definition rel_T_pos_distr_cond :: "('co1 ==> 'co1' ==> bool) ==> ('co1' ==> 'co1'' ==> bool) ==>
    ('co2 ==> 'co2' ==> bool) ==> ('co2' ==> 'co2'' ==> bool) ==>
    ('contra1 ==> 'contra1' ==> bool) ==> ('contra1' ==> 'contra1'' ==> bool) ==>
    ('contra2 ==> 'contra2' ==> bool) ==> ('contra2' ==> 'contra2'' ==> bool) ==>
    ('l1 × 'l1' × 'l1'' × 'f) itself ==> bool" where
  "rel_T_pos_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' _
  ((L1 :: 'l1 ==> 'l1' ==> bool) (L1' :: 'l1' ==> 'l1'' ==> bool).
    (rel_T L1 Co1 Co2 Contra1 Contra2 :: (_, _, _, _, _, 'f) T ==> _) OO
      rel_T L1' Co1' Co2' Contra1' Contra2'
    rel_T (L1 OO L1') (Co1 OO Co1') (Co2 OO Co2') (Contra1 OO Contra1') (Contra2 OO Contra2'))"

definition rel_T_neg_distr_cond :: "('co1 ==> 'co1' ==> bool) ==> ('co1' ==> 'co1'' ==> bool) ==>
    ('co2 ==> 'co2' ==> bool) ==> ('co2' ==> 'co2'' ==> bool) ==>
    ('contra1 ==> 'contra1' ==> bool) ==> ('contra1' ==> 'contra1'' ==> bool) ==>
    ('contra2 ==> 'contra2' ==> bool) ==> ('contra2' ==> 'contra2'' ==> bool) ==>
    ('l1 × 'l1' × 'l1'' × 'f) itself ==> bool" where
  "rel_T_neg_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' _
  ((L1 :: 'l1 ==> 'l1' ==> bool) (L1' :: 'l1' ==> 'l1'' ==> bool).
    rel_T (L1 OO L1') (Co1 OO Co1') (Co2 OO Co2') (Contra1 OO Contra1') (Contra2 OO Contra2')
    (rel_T L1 Co1 Co2 Contra1 Contra2 :: (_, _, _, _, _, 'f) T ==> _) OO
      rel_T L1' Co1' Co2' Contra1' Contra2')"

text 
 We inherit the conditions for subdistributivity over relation composition via
 a composition witness, which is derived from a witness for the underlying functor @{type G}.
 


primrec rel_T_witness :: "('l1 ==> 'l1'' ==> bool) ==>
    ('co1 ==> 'co1' ==> bool) ==> ('co1' ==> 'co1'' ==> bool) ==>
    ('co2 ==> 'co2' ==> bool) ==> ('co2' ==> 'co2'' ==> bool) ==>
    ('contra1 ==> 'contra1' ==> bool) ==> ('contra1' ==> 'contra1'' ==> bool) ==>
    ('contra2 ==> 'contra2' ==> bool) ==> ('contra2' ==> 'contra2'' ==> bool) ==>
    ('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) T ==>
    ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) T ==>
    ('l1 × 'l1'', 'co1', 'co2', 'contra1', 'contra2', 'f) T" where
  "rel_T_witness L1 Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' (C_T x) Cy = C_T
  (mapl_G (λ((x, f), y). f y) id
    (rel_G_witness (λ(x, f) y. rel_T (λx (x', y). x' = x L1 x y) Co1 Co2 Contra1 Contra2 x (f y)
      rel_T (λ(x, y') y. y' = y L1 x y) Co1' Co2' Contra1' Contra2' (f y) y)
    L1 Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2'
    (mapl_G (λx. (x, rel_T_witness L1 Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' x)) id x,
      D_T Cy)))"

lemma rel_T_pos_distr_imp:
  fixes Co1 :: "'co1 ==> 'co1' ==> bool" and Co1' :: "'co1' ==> 'co1'' ==> bool"
    and Co2 :: "'co2 ==> 'co2' ==> bool" and Co2' :: "'co2' ==> 'co2'' ==> bool"
    and Contra1 :: "'contra1 ==> 'contra1' ==> bool" and Contra1' :: "'contra1' ==> 'contra1'' ==> bool"
    and Contra2 :: "'contra2 ==> 'contra2' ==> bool" and Contra2' :: "'contra2' ==> 'contra2'' ==> bool"
    and tytok_G :: "(('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) T ×
      ('l1', 'co1', 'co2', 'contra1', 'contra2', 'f) T ×
      ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) T × 'l1 × 'l1' × 'l1'' × 'f) itself"
    and tytok_T :: "('l1 × 'l1' × 'l1'' × 'f) itself"
  assumes "rel_G_pos_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' tytok_G"
  shows "rel_T_pos_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' tytok_T"
  unfolding rel_T_pos_distr_cond_def
  apply (intro allI predicate2I)
  apply (erule relcomppE)
  subgoal premises prems for L1 L1' x z y
    using prems apply (induction arbitrary: z)
    apply (erule rel_T.cases)
    apply (simp)
    apply (rule rel_T.intros)
    apply (drule (1) rel_G_pos_distr[THEN predicate2D, OF assms relcomppI])
    apply (erule rel_G_mono'; blast)
    done
  done

lemma
  fixes L1 :: "'l1 ==> 'l1'' ==> bool"
    and Co1 :: "'co1 ==> 'co1' ==> bool" and Co1' :: "'co1' ==> 'co1'' ==> bool"
    and Co2 :: "'co2 ==> 'co2' ==> bool" and Co2' :: "'co2' ==> 'co2'' ==> bool"
    and Contra1 :: "'contra1 ==> 'contra1' ==> bool" and Contra1' :: "'contra1' ==> 'contra1'' ==> bool"
    and Contra2 :: "'contra2 ==> 'contra2' ==> bool" and Contra2' :: "'contra2' ==> 'contra2'' ==> bool"
    and tytok_G :: "((('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) T ×
         (('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) T
          ==> ('l1 × 'l1'', 'co1', 'co2', 'contra1', 'contra2', 'f) T)) ×
        ((('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) T ×
          (('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) T
           ==> ('l1 × 'l1'', 'co1', 'co2', 'contra1', 'contra2', 'f) T)) ×
         ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) T) ×
        ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) T ×
        'l1 × ('l1 × 'l1'') × 'l1'' × 'f) itself"
    and x :: "(_, _, _, _, _, 'f) T"
  assumes cond: "rel_G_neg_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' tytok_G"
    and rel_OO: "rel_T L1 (Co1 OO Co1') (Co2 OO Co2') (Contra1 OO Contra1') (Contra2 OO Contra2') x y"
  shows rel_T_witness1: "rel_T (λx (x', y). x' = x L1 x y) Co1 Co2 Contra1 Contra2 x
      (rel_T_witness L1 Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' x y)"
    and rel_T_witness2: "rel_T (λ(x, y') y. y' = y L1 x y) Co1' Co2' Contra1' Contra2'
      (rel_T_witness L1 Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' x y) y"
  using rel_OO apply (induction)
  subgoal premises prems for x y
  proof-
    have x_expansion: "x = mapl_G fst id (mapl_G (λx.
      (x, rel_T_witness L1 Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' x)) id x)"
      by (simp add: mapl_G_def map_G_comp[THEN fun_cong, simplified] map_G_id[unfolded id_def] comp_def)
    show ?thesis
      apply (simp)
      apply (rule rel_T.intros)
      apply (rewrite in "rel_G _ _ _ _ _ _ 🍋 _" x_expansion)
      apply (rewrite in "rel_G _ _ _ _ _ _ _ 🍋" mapl_G_def)
      apply (subst mapl_G_def)
      apply (rule map_G_rel_cong)
            apply (rule rel_G_witness1[OF cond])
            apply (rewrite in "rel_G _ _ _ _ _ _ 🍋 _" mapl_G_def)
            apply (rewrite in "rel_G _ _ _ _ _ _ _ 🍋" map_G_id[symmetric])
            apply (rule map_G_rel_cong[OF prems])
                 apply (clarsimp)+
      done
  qed
  subgoal for x y
    apply (simp)
    apply (rule rel_T.intros)
    apply (rewrite in "rel_G _ _ _ _ _ _ 🍋 _" mapl_G_def)
    apply (rewrite in "rel_G _ _ _ _ _ _ _ 🍋" map_G_id[symmetric])
    apply (rule map_G_rel_cong)
          apply (rule rel_G_witness2[OF cond[unfolded rel_T_neg_distr_cond_def]])
          apply (rewrite in "rel_G _ _ _ _ _ _ 🍋 _" mapl_G_def)
          apply (rewrite in "rel_G _ _ _ _ _ _ _ 🍋" map_G_id[symmetric])
          apply (erule map_G_rel_cong)
               apply (clarsimp)+
    done
  done

lemma rel_T_neg_distr_imp:
  fixes Co1 :: "'co1 ==> 'co1' ==> bool" and Co1' :: "'co1' ==> 'co1'' ==> bool"
    and Co2 :: "'co2 ==> 'co2' ==> bool" and Co2' :: "'co2' ==> 'co2'' ==> bool"
    and Contra1 :: "'contra1 ==> 'contra1' ==> bool" and Contra1' :: "'contra1' ==> 'contra1'' ==> bool"
    and Contra2 :: "'contra2 ==> 'contra2' ==> bool" and Contra2' :: "'contra2' ==> 'contra2'' ==> bool"
    and tytok_G :: "((('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) T ×
         (('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) T
          ==> ('l1 × 'l1'', 'co1', 'co2', 'contra1', 'contra2', 'f) T)) ×
        ((('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) T ×
          (('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) T
           ==> ('l1 × 'l1'', 'co1', 'co2', 'contra1', 'contra2', 'f) T)) ×
         ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) T) ×
        ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) T ×
        'l1 × ('l1 × 'l1'') × 'l1'' × 'f) itself"
    and tytok_T :: "('l1 × 'l1' × 'l1'' × 'f) itself"
  assumes "rel_G_neg_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' tytok_G"
  shows "rel_T_neg_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' tytok_T"
  unfolding rel_T_neg_distr_cond_def
proof (intro allI predicate2I relcomppI)
  fix L1 :: "'l1 ==> 'l1' ==> bool" and L1' :: "'l1' ==> 'l1'' ==> bool"
    and x :: "(_, _, _, _, _, 'f) T" and y :: "(_, _, _, _, _, 'f) T"
  assume *: "rel_T (L1 OO L1') (Co1 OO Co1') (Co2 OO Co2')
    (Contra1 OO Contra1') (Contra2 OO Contra2') x y"
  let ?z = "map_T (relcompp_witness L1 L1') id id id id
    (rel_T_witness (L1 OO L1') Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' x y)"
  show "rel_T L1 Co1 Co2 Contra1 Contra2 x ?z"
    apply(subst map_T_id[symmetric])
    apply(rule map_T_parametric[unfolded rel_fun_def, rule_format, rotated -1])
         apply(rule rel_T_witness1[OF assms *])
        apply(auto simp add: vimage2p_def del: relcomppE elim!: relcompp_witness)
    done
  show "rel_T L1' Co1' Co2' Contra1' Contra2' ?z y"
    apply(rewrite in "rel_T _ _ _ _ _ _ 🍋" map_T_id[symmetric])
    apply(rule map_T_parametric[unfolded rel_fun_def, rule_format, rotated -1])
         apply(rule rel_T_witness2[OF assms *])
        apply(auto simp add: vimage2p_def del: relcomppE elim!: relcompp_witness)
    done
qed

lemma rel_T_pos_distr_cond_eq:
  "tytok. rel_T_pos_distr_cond (=) (=) (=) (=) (=) (=) (=) (=) tytok"
  by (intro rel_T_pos_distr_imp rel_G_pos_distr_cond_eq)

lemma rel_T_neg_distr_cond_eq:
  "tytok. rel_T_neg_distr_cond (=) (=) (=) (=) (=) (=) (=) (=) tytok"
  by (intro rel_T_neg_distr_imp rel_G_neg_distr_cond_eq)

text The BNF axioms are proved by the datatype package.

thm T.set_map T.bd_card_order T.bd_cinfinite T.set_bd T.map_cong[OF refl]
  T.rel_mono_strong T.wit


subsubsection Parametricity laws

context includes lifting_syntax begin

lemma C_T_parametric: "(rel_G (rel_T L1 Co1 Co2 Contra1 Contra2) L1 Co1 Co2 Contra1 Contra2 ===>
  rel_T L1 Co1 Co2 Contra1 Contra2) C_T C_T"
  by (fast elim: rel_T.intros)

lemma D_T_parametric: "(rel_T L1 Co1 Co2 Contra1 Contra2 ===>
  rel_G (rel_T L1 Co1 Co2 Contra1 Contra2) L1 Co1 Co2 Contra1 Contra2) D_T D_T"
  by (fastforce elim: rel_T.cases)

lemma rec_T_parametric:
  "((rel_G (rel_prod (rel_T L1 Co1 Co2 Contra1 Contra2) A) L1 Co1 Co2 Contra1 Contra2 ===> A) ===>
  rel_T L1 Co1 Co2 Contra1 Contra2 ===> A) rec_T rec_T"
  apply (intro rel_funI)
  subgoal premises prems for f g x y
    using prems(2apply (induction)
    apply (simp)
    apply (rule prems(1)[THEN rel_funD])
    apply (unfold mapl_G_def)
    apply (erule map_G_rel_cong)
         apply (auto)
    done
  done

end


subsection Greatest fixpoints

subsubsection \BNFCC{} structure

context notes [[typedef_overloaded, bnf_internals]]
begin

codatatype (set_U: 'l1, 'co1, 'co2, 'contra1, 'contra2, 'f) U =
  C_U (D_U: "(('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) U, 'l1, 'co1, 'co2, 'contra1, 'contra2, 'f) G")
  for
    map: mapl_U
    rel: rell_U

end

coinductive rel_U :: "('l1 ==> 'l1' ==> bool) ==>
    ('co1 ==> 'co1' ==> bool) ==> ('co2 ==> 'co2' ==> bool) ==>
    ('contra1 ==> 'contra1' ==> bool) ==> ('contra2 ==> 'contra2' ==> bool) ==>
    ('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) U ==>
    ('l1', 'co1', 'co2', 'contra1', 'contra2', 'f) U ==> bool"
  for L1 Co1 Co2 Contra1 Contra2 where
  "rel_U L1 Co1 Co2 Contra1 Contra2 x y"
    if "rel_G (rel_U L1 Co1 Co2 Contra1 Contra2) L1 Co1 Co2 Contra1 Contra2 (D_U x) (D_U y)"

primcorec map_U :: "('l1 ==> 'l1') ==> ('co1 ==> 'co1') ==> ('co2 ==> 'co2') ==>
    ('contra1' ==> 'contra1) ==> ('contra2' ==> 'contra2) ==>
    ('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) U ==>
    ('l1', 'co1', 'co2', 'contra1', 'contra2', 'f) U" where
  "D_U (map_U l1 co1 co2 contra1 contra2 x) =
    mapl_G (map_U l1 co1 co2 contra1 contra2) l1 (map_G id id co1 co2 contra1 contra2 (D_U x))"

lemma rell_U_alt_def: "rell_U L1 = rel_U L1 (=) (=) (=) (=)"
  apply (intro ext iffI)
   apply (erule rel_U.coinduct)
   apply (erule U.rel_cases)
   apply (simp add: rell_G_def)
   apply (erule rel_G_mono'; blast)
  apply (erule U.rel_coinduct)
  apply (erule rel_U.cases)
  apply (simp add: rell_G_def)
  done

lemma mapl_U_alt_def: "mapl_U l1 = map_U l1 id id id id"
  supply id_apply[simp del]
  apply (rule ext)
  subgoal for x
    apply (coinduction arbitrary: x)
    apply (simp add: mapl_G_def map_G_comp[THEN fun_cong, simplified] U.map_sel)
    apply (unfold rell_G_def)
    apply (rule map_G_rel_cong[OF rel_G_eq_refl])
         apply (auto)
    done
  done

lemma rel_U_mono [mono]:
  "[ L1 L1'; Co1 Co1'; Co2 Co2'; Contra1' Contra1; Contra2' Contra2 ] ==>
  rel_U L1 Co1 Co2 Contra1 Contra2 rel_U L1' Co1' Co2' Contra1' Contra2'"
  apply (rule predicate2I)
  apply (erule rel_U.coinduct[of "rel_U L1 Co1 Co2 Contra1 Contra2"])
  apply (erule rel_U.cases)
  apply (simp)
  apply (erule rel_G_mono')
       apply (blast)+
  done

lemma rel_U_eq: "rel_U (=) (=) (=) (=) (=) = (=)"
  unfolding rell_U_alt_def[symmetric] U.rel_eq ..

lemma rel_U_conversep:
  "rel_U L1-1-1 Co1-1-1 Co2-1-1 Contra1-1-1 Contra2-1-1 = (rel_U L1 Co1 Co2 Contra1 Contra2)-1-1"
  apply (intro ext iffI)
   apply (simp)
   apply (erule rel_U.coinduct)
   apply (erule rel_U.cases)
   apply (simp del: conversep_iff)
   apply (rewrite conversep_iff[symmetric])
   apply (fold rel_G_conversep)
   apply (erule rel_G_mono'; blast)
  apply (erule rel_U.coinduct)
  apply (subst (asm) conversep_iff)
  apply (erule rel_U.cases)
  apply (simp del: conversep_iff)
  apply (rewrite conversep_iff[symmetric])
  apply (unfold rel_G_conversep[symmetric] conversep_conversep)
  apply (erule rel_G_mono'; blast)
  done

lemma map_U_id0: "map_U id id id id id = id"
  unfolding mapl_U_alt_def[symmetric] U.map_id0 ..

lemma map_U_id: "map_U id id id id id x = x"
  by (simp add: map_U_id0)

lemma map_U_comp: "map_U l1 co1 co2 contra1 contra2 map_U l1' co1' co2' contra1' contra2' =
  map_U (l1 l1') (co1 co1') (co2 co2') (contra1' contra1) (contra2' contra2)"
  apply (rule ext)
  subgoal for x
    apply (coinduction arbitrary: x)
    apply (simp add: mapl_G_def map_G_comp[THEN fun_cong, simplified])
    apply (unfold rell_G_def)
    apply (rule map_G_rel_cong[OF rel_G_eq_refl])
         apply (auto)
    done
  done

lemma map_U_parametric: "rel_fun (rel_fun L1 L1')
  (rel_fun (rel_fun Co1 Co1') (rel_fun (rel_fun Co2 Co2')
  (rel_fun (rel_fun Contra1' Contra1) (rel_fun (rel_fun Contra2' Contra2)
  (rel_fun (rel_U L1 Co1 Co2 Contra1 Contra2) (rel_U L1' Co1' Co2' Contra1' Contra2'))))))
  map_U map_U"
  apply (intro rel_funI)
  apply (coinduction)
  apply (simp add: mapl_G_def map_G_comp[THEN fun_cong, simplified])
  apply (erule rel_U.cases)
  apply (hypsubst)
  apply (erule map_G_rel_cong)
       apply (blast elim: rel_funE)+
  done

definition rel_U_pos_distr_cond :: "('co1 ==> 'co1' ==> bool) ==> ('co1' ==> 'co1'' ==> bool) ==>
    ('co2 ==> 'co2' ==> bool) ==> ('co2' ==> 'co2'' ==> bool) ==>
    ('contra1 ==> 'contra1' ==> bool) ==> ('contra1' ==> 'contra1'' ==> bool) ==>
    ('contra2 ==> 'contra2' ==> bool) ==> ('contra2' ==> 'contra2'' ==> bool) ==>
    ('l1 × 'l1' × 'l1'' × 'f) itself ==> bool" where
  "rel_U_pos_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' _
  ((L1 :: 'l1 ==> 'l1' ==> bool) (L1' :: 'l1' ==> 'l1'' ==> bool).
    (rel_U L1 Co1 Co2 Contra1 Contra2 :: (_, _, _, _, _, 'f) U ==> _) OO
      rel_U L1' Co1' Co2' Contra1' Contra2'
    rel_U (L1 OO L1') (Co1 OO Co1') (Co2 OO Co2') (Contra1 OO Contra1') (Contra2 OO Contra2'))"

definition rel_U_neg_distr_cond :: "('co1 ==> 'co1' ==> bool) ==> ('co1' ==> 'co1'' ==> bool) ==>
    ('co2 ==> 'co2' ==> bool) ==> ('co2' ==> 'co2'' ==> bool) ==>
    ('contra1 ==> 'contra1' ==> bool) ==> ('contra1' ==> 'contra1'' ==> bool) ==>
    ('contra2 ==> 'contra2' ==> bool) ==> ('contra2' ==> 'contra2'' ==> bool) ==>
    ('l1 × 'l1' × 'l1'' × 'f) itself ==> bool" where
  "rel_U_neg_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' _
  ((L1 :: 'l1 ==> 'l1' ==> bool) (L1' :: 'l1' ==> 'l1'' ==> bool).
    rel_U (L1 OO L1') (Co1 OO Co1') (Co2 OO Co2') (Contra1 OO Contra1') (Contra2 OO Contra2')
    (rel_U L1 Co1 Co2 Contra1 Contra2 :: (_, _, _, _, _, 'f) U ==> _) OO
      rel_U L1' Co1' Co2' Contra1' Contra2')"

primcorec rel_U_witness :: "('l1 ==> 'l1'' ==> bool) ==>
    ('co1 ==> 'co1' ==> bool) ==> ('co1' ==> 'co1'' ==> bool) ==>
    ('co2 ==> 'co2' ==> bool) ==> ('co2' ==> 'co2'' ==> bool) ==>
    ('contra1 ==> 'contra1' ==> bool) ==> ('contra1' ==> 'contra1'' ==> bool) ==>
    ('contra2 ==> 'contra2' ==> bool) ==> ('contra2' ==> 'contra2'' ==> bool) ==>
    ('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) U ×
    ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) U ==>
    ('l1 × 'l1'', 'co1', 'co2', 'contra1', 'contra2', 'f) U" where
  "D_U (rel_U_witness L1 Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' xy) =
  mapl_G (rel_U_witness L1 Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2') id
    (rel_G_witness (rel_U L1 (Co1 OO Co1') (Co2 OO Co2') (Contra1 OO Contra1') (Contra2 OO Contra2'))
    L1 Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' (D_U (fst xy), D_U (snd xy)))"

lemma rel_U_pos_distr_imp:
  fixes Co1 :: "'co1 ==> 'co1' ==> bool" and Co1' :: "'co1' ==> 'co1'' ==> bool"
    and Co2 :: "'co2 ==> 'co2' ==> bool" and Co2' :: "'co2' ==> 'co2'' ==> bool"
    and Contra1 :: "'contra1 ==> 'contra1' ==> bool" and Contra1' :: "'contra1' ==> 'contra1'' ==> bool"
    and Contra2 :: "'contra2 ==> 'contra2' ==> bool" and Contra2' :: "'contra2' ==> 'contra2'' ==> bool"
    and tytok_G :: "(('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) U ×
      ('l1', 'co1', 'co2', 'contra1', 'contra2', 'f) U ×
      ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) U × 'l1 × 'l1' × 'l1'' × 'f) itself"
    and tytok_T :: "('l1 × 'l1' × 'l1'' × 'f) itself"
  assumes "rel_G_pos_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' tytok_G"
  shows "rel_U_pos_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' tytok_T"
  unfolding rel_U_pos_distr_cond_def
  apply (intro allI predicate2I)
  apply (erule relcomppE)
  subgoal premises prems for L1 L1' x z y
    using prems apply (coinduction arbitrary: x y z)
    apply (simp)
    apply (rule rel_G_pos_distr[THEN predicate2D,
          OF assms relcomppI, THEN rel_G_mono'])
           apply (auto elim: rel_U.cases)
    done
  done

lemma rel_U_witness1:
  fixes L1 :: "'l1 ==> 'l1'' ==> bool"
    and Co1 :: "'co1 ==> 'co1' ==> bool" and Co1' :: "'co1' ==> 'co1'' ==> bool"
    and Co2 :: "'co2 ==> 'co2' ==> bool" and Co2' :: "'co2' ==> 'co2'' ==> bool"
    and Contra1 :: "'contra1 ==> 'contra1' ==> bool" and Contra1' :: "'contra1' ==> 'contra1'' ==> bool"
    and Contra2 :: "'contra2 ==> 'contra2' ==> bool" and Contra2' :: "'contra2' ==> 'contra2'' ==> bool"
    and tytok_G :: "(('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) U ×
             (('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) U ×
              ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) U) ×
             ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) U ×
             'l1 × ('l1 × 'l1'') × 'l1'' × 'f) itself"
    and x :: "(_, _, _, _, _, 'f) U"
  assumes cond: "rel_G_neg_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' tytok_G"
    and rel_OO: "rel_U L1 (Co1 OO Co1') (Co2 OO Co2') (Contra1 OO Contra1') (Contra2 OO Contra2') x y"
  shows "rel_U (λx (x', y). x' = x L1 x y) Co1 Co2 Contra1 Contra2 x
      (rel_U_witness L1 Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' (x, y))"
  using rel_OO apply (coinduction arbitrary: x y)
  apply (erule rel_U.cases)
  apply (clarsimp)
  apply (rewrite in "rel_G _ _ _ _ _ _ 🍋 _" map_G_id[symmetric])
  apply (subst mapl_G_def)
  apply (rule map_G_rel_cong)
        apply (erule rel_G_witness1[OF cond])
       apply (auto)
  done

lemma rel_U_witness2:
  fixes L1 :: "'l1 ==> 'l1'' ==> bool"
    and Co1 :: "'co1 ==> 'co1' ==> bool" and Co1' :: "'co1' ==> 'co1'' ==> bool"
    and Co2 :: "'co2 ==> 'co2' ==> bool" and Co2' :: "'co2' ==> 'co2'' ==> bool"
    and Contra1 :: "'contra1 ==> 'contra1' ==> bool" and Contra1' :: "'contra1' ==> 'contra1'' ==> bool"
    and Contra2 :: "'contra2 ==> 'contra2' ==> bool" and Contra2' :: "'contra2' ==> 'contra2'' ==> bool"
    and tytok_G :: "(('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) U ×
             (('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) U ×
              ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) U) ×
             ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) U ×
             'l1 × ('l1 × 'l1'') × 'l1'' × 'f) itself"
    and x :: "(_, _, _, _, _, 'f) U"
  assumes cond: "rel_G_neg_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' tytok_G"
    and rel_OO: "rel_U L1 (Co1 OO Co1') (Co2 OO Co2') (Contra1 OO Contra1') (Contra2 OO Contra2') x y"
  shows "rel_U (λ(x, y') y. y' = y L1 x y) Co1' Co2' Contra1' Contra2'
      (rel_U_witness L1 Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' (x, y)) y"
  using rel_OO apply (coinduction arbitrary: x y)
  apply (erule rel_U.cases)
  apply (clarsimp)
  apply (rewrite in "rel_G _ _ _ _ _ _ _ 🍋" map_G_id[symmetric])
  apply (subst mapl_G_def)
  apply (rule map_G_rel_cong)
        apply (erule rel_G_witness2[OF cond])
       apply (auto)
  done

lemma rel_U_neg_distr_imp:
  fixes Co1 :: "'co1 ==> 'co1' ==> bool" and Co1' :: "'co1' ==> 'co1'' ==> bool"
    and Co2 :: "'co2 ==> 'co2' ==> bool" and Co2' :: "'co2' ==> 'co2'' ==> bool"
    and Contra1 :: "'contra1 ==> 'contra1' ==> bool" and Contra1' :: "'contra1' ==> 'contra1'' ==> bool"
    and Contra2 :: "'contra2 ==> 'contra2' ==> bool" and Contra2' :: "'contra2' ==> 'contra2'' ==> bool"
    and tytok_G :: "(('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) U ×
          (('l1, 'co1, 'co2, 'contra1, 'contra2, 'f) U ×
           ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) U) ×
          ('l1'', 'co1'', 'co2'', 'contra1'', 'contra2'', 'f) U ×
          'l1 × ('l1 × 'l1'') × 'l1'' × 'f) itself"
    and tytok_T :: "('l1 × 'l1' × 'l1'' × 'f) itself"
  assumes "rel_G_neg_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' tytok_G"
  shows "rel_U_neg_distr_cond Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' tytok_T"
  unfolding rel_U_neg_distr_cond_def
proof (intro allI predicate2I relcomppI)
  fix L1 :: "'l1 ==> 'l1' ==> bool" and L1' :: "'l1' ==> 'l1'' ==> bool"
    and x :: "(_, _, _, _, _, 'f) U" and y :: "(_, _, _, _, _, 'f) U"
  assume *: "rel_U (L1 OO L1') (Co1 OO Co1') (Co2 OO Co2')
    (Contra1 OO Contra1') (Contra2 OO Contra2') x y"
  let ?z = "map_U (relcompp_witness L1 L1') id id id id
    (rel_U_witness (L1 OO L1') Co1 Co1' Co2 Co2' Contra1 Contra1' Contra2 Contra2' (x, y))"
  show "rel_U L1 Co1 Co2 Contra1 Contra2 x ?z"
    apply(subst map_U_id[symmetric])
    apply(rule map_U_parametric[unfolded rel_fun_def, rule_format, rotated -1])
         apply(rule rel_U_witness1[OF assms *])
        apply(auto simp add: vimage2p_def del: relcomppE elim!: relcompp_witness)
    done
  show "rel_U L1' Co1' Co2' Contra1' Contra2' ?z y"
    apply(rewrite in "rel_U _ _ _ _ _ _ 🍋" map_U_id[symmetric])
    apply(rule map_U_parametric[unfolded rel_fun_def, rule_format, rotated -1])
         apply(rule rel_U_witness2[OF assms *])
        apply(auto simp add: vimage2p_def del: relcomppE elim!: relcompp_witness)
    done
qed

lemma rel_U_pos_distr_cond_eq:
  "tytok. rel_U_pos_distr_cond (=) (=) (=) (=) (=) (=) (=) (=) tytok"
  by (intro rel_U_pos_distr_imp rel_G_pos_distr_cond_eq)

lemma rel_U_neg_distr_cond_eq:
  "tytok. rel_U_neg_distr_cond (=) (=) (=) (=) (=) (=) (=) (=) tytok"
  by (intro rel_U_neg_distr_imp rel_G_neg_distr_cond_eq)

text The BNF axioms are proved by the datatype package.

thm U.set_map U.bd_card_order U.bd_cinfinite U.set_bd U.map_cong[OF refl]
  U.rel_mono_strong U.wit


subsubsection Parametricity laws

context includes lifting_syntax begin

lemma C_U_parametric: "(rel_G (rel_U L1 Co1 Co2 Contra1 Contra2) L1 Co1 Co2 Contra1 Contra2 ===>
  rel_U L1 Co1 Co2 Contra1 Contra2) C_U C_U"
  by (fastforce intro: rel_U.intros)

lemma D_U_parametric: "(rel_U L1 Co1 Co2 Contra1 Contra2 ===>
  rel_G (rel_U L1 Co1 Co2 Contra1 Contra2) L1 Co1 Co2 Contra1 Contra2) D_U D_U"
  by (fast elim: rel_U.cases)

lemma corec_U_parametric:
  "((A ===> rel_G (rel_sum (rel_U L1 Co1 Co2 Contra1 Contra2) A) L1 Co1 Co2 Contra1 Contra2) ===>
  A ===> rel_U L1 Co1 Co2 Contra1 Contra2) corec_U corec_U"
  apply (intro rel_funI)
  subgoal premises prems for f g x y
    using prems(2apply (coinduction arbitrary: x y)
    apply (simp)
    apply (unfold mapl_G_def)
    apply (rule map_G_rel_cong)
          apply (erule prems(1)[THEN rel_funD])
         apply (fastforce elim: rel_sum.cases)
        apply (simp_all)
    done
  done

end

end

Messung V0.5 in Prozent
C=72 H=96 G=84

¤ Dauer der Verarbeitung: 0.14 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.