(* 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(2 ) apply (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(2 ) apply (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=93 H=97 G=94
¤ Dauer der Verarbeitung: 0.30 Sekunden
¤
*© Formatika GbR, Deutschland
Wurzel
Suchen
NIST Cobol Testsuite
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.