(* Title: Safe OCL Author:DenisNikiforov,March2019 Maintainer:DenisNikiforov<denis.nikifatgmail.com> License:LGPL
*) (* TODO: There are a lot of similar lemmas in the theory.
They should be generalized *) section‹Tuples› theory Tuple imports Finite_Map_Ext Transitive_Closure_Ext begin
subsection‹Definitions›
abbreviation"subtuple f xm ym ≡ fmrel_on_fset (fmdom ym) f xm ym"
abbreviation"strict_subtuple f xm ym ≡ subtuple f xm ym ∧ xm ≠ ym"
lemma subtuple_refl: "reflp R ==> subtuple R xm xm" by (simp add: fmrel_on_fsetI option.rel_reflp reflpD)
lemma subtuple_mono [mono]: "(∧x y. x ∈ fmran' xm ==> y ∈ fmran' ym ==> f x y ⟶ g x y) ==> subtuple f xm ym ⟶ subtuple g xm ym" apply (auto) apply (rule fmrel_on_fsetI) apply (drule_tac ?P="f"and ?m="xm"and ?n="ym"in fmrel_on_fsetD, simp) apply (erule option.rel_cases, simp) by (auto simp add: option.rel_sel fmran'I)
lemma strict_subtuple_mono [mono]: "(∧x y. x ∈ fmran' xm ==> y ∈ fmran' ym ==> f x y ⟶ g x y) ==> strict_subtuple f xm ym ⟶ strict_subtuple g xm ym" using subtuple_mono by blast
lemma subtuple_antisym: assumes"subtuple (λx y. f x y ∨ x = y) xm ym" assumes"subtuple (λx y. f x y ∧¬ f y x ∨ x = y) ym xm" shows"xm = ym" proof (rule fmap_ext) fix x from assms have"fmdom xm = fmdom ym" using subtuple_fmdom by blast with assms have"fmrel (λx y. f x y ∨ x = y) xm ym" and"fmrel (λx y. f x y ∧¬ f y x ∨ x = y) ym xm" by (metis (mono_tags, lifting) fmrel_code fmrel_on_fset_alt_def)+ thus"fmlookup xm x = fmlookup ym x" apply (erule_tac ?x="x"in fmrel_cases) by (erule_tac ?x="x"in fmrel_cases, auto)+ qed
lemma strict_subtuple_antisym: "strict_subtuple (λx y. f x y ∨ x = y) xm ym ==> strict_subtuple (λx y. f x y ∧¬ f y x ∨ x = y) ym xm ==> False" by (auto simp add: subtuple_antisym)
lemma subtuple_acyclic: assumes"acyclicP_on (fmran' xm) P" assumes"subtuple (λx y. P x y ∨ x = y)++ xm ym" assumes"subtuple (λx y. P x y ∨ x = y) ym xm" shows"xm = ym" proof (rule fmap_ext) fix x from assms have fmdom_eq: "fmdom xm = fmdom ym" using subtuple_fmdom by blast have"∧x a b. acyclicP_on (fmran' xm) P ==> fmlookup xm x = Some a ==> fmlookup ym x = Some b ==> P** a b ==> P b a ∨ a = b ==> a = b" by (meson Nitpick.tranclp_unfold fmran'I rtranclp_into_tranclp1) moreoverfrom fmdom_eq assms(2) have"fmrel P** xm ym" unfolding fmrel_on_fset_fmrel_restrict apply auto by (metis fmrestrict_fset_dom) moreoverfrom fmdom_eq assms(3) have"fmrel (λx y. P x y ∨ x = y) ym xm" unfolding fmrel_on_fset_fmrel_restrict apply auto by (metis fmrestrict_fset_dom) ultimatelyshow"fmlookup xm x = fmlookup ym x" apply (erule_tac ?x="x"in fmrel_cases) apply (erule_tac ?x="x"in fmrel_cases, simp_all)+ using assms(1) by blast qed
lemma subtuple_acyclic': assumes"acyclicP_on (fmran' ym) P" assumes"subtuple (λx y. P x y ∨ x = y)++ xm ym" assumes"subtuple (λx y. P x y ∨ x = y) ym xm" shows"xm = ym" proof (rule fmap_ext) fix x from assms have fmdom_eq: "fmdom xm = fmdom ym" using subtuple_fmdom by blast have"∧x a b. acyclicP_on (fmran' ym) P ==> fmlookup xm x = Some a ==> fmlookup ym x = Some b ==> P** a b ==> P b a ∨ a = b ==> a = b" by (meson Nitpick.tranclp_unfold fmran'I rtranclp_into_tranclp2) moreoverfrom fmdom_eq assms(2) have"fmrel P** xm ym" unfolding fmrel_on_fset_fmrel_restrict apply auto by (metis fmrestrict_fset_dom) moreoverfrom fmdom_eq assms(3) have"fmrel (λx y. P x y ∨ x = y) ym xm" unfolding fmrel_on_fset_fmrel_restrict apply auto by (metis fmrestrict_fset_dom) ultimatelyshow"fmlookup xm x = fmlookup ym x" apply (erule_tac ?x="x"in fmrel_cases) apply (erule_tac ?x="x"in fmrel_cases, simp_all)+ using assms(1) by blast qed
lemma subtuple_acyclic'': "acyclicP_on (fmran' ym) R ==> subtuple R** xm ym ==> subtuple R ym xm ==> xm = ym" by (metis (no_types, lifting) subtuple_acyclic' subtuple_mono tranclp_eq_rtranclp)
lemma strict_subtuple_trans: "acyclicP_on (fmran' xm) P ==> strict_subtuple (λx y. P x y ∨ x = y)++ xm ym ==> strict_subtuple (λx y. P x y ∨ x = y) ym zm ==> strict_subtuple (λx y. P x y ∨ x = y)++ xm zm" apply auto apply (rule fmrel_on_fset_trans, auto) by (drule_tac ?ym="ym"in subtuple_acyclic; auto)
lemma strict_subtuple_trans': "acyclicP_on (fmran' zm) P ==> strict_subtuple (λx y. P x y ∨ x = y) xm ym ==> strict_subtuple (λx y. P x y ∨ x = y)++ ym zm ==> strict_subtuple (λx y. P x y ∨ x = y)++ xm zm" apply auto apply (rule fmrel_on_fset_trans, auto) by (drule_tac ?xm="ym"in subtuple_acyclic'; auto)
lemma strict_subtuple_trans'': "acyclicP_on (fmran' zm) R ==> strict_subtuple R xm ym ==> strict_subtuple R** ym zm ==> strict_subtuple R** xm zm" apply auto apply (rule fmrel_on_fset_trans, auto) by (drule_tac ?xm="ym"in subtuple_acyclic''; auto)
lemma strict_subtuple_trans''': "acyclicP_on (fmran' zm) P ==> strict_subtuple (λx y. P x y ∨ x = y) xm ym ==> strict_subtuple (λx y. P x y ∨ x = y)** ym zm ==> strict_subtuple (λx y. P x y ∨ x = y)** xm zm" apply auto apply (rule fmrel_on_fset_trans, auto) by (drule_tac ?xm="ym"in subtuple_acyclic'; auto)
lemma subtuple_fmmerge2 [intro]: "(∧x y. x ∈ fmran' xm ==> f x (g x y)) ==> subtuple f xm (fmmerge g xm ym)" by (rule_tac ?S="fmdom ym"in fmrel_on_fsubset; auto)
lemma subtuple_to_trancl: "reflp r ==> subtuple r++ xm ym ==> (subtuple r)++ xm ym" apply (rule fmrel_to_subtuple_trancl) unfolding fmrel_on_fset_fmrel_restrict by (simp_all add: fmrel_to_trancl)
lemma trancl_to_strict_subtuple: "acyclicP_on (fmran' ym) R ==> (strict_subtuple R)++ xm ym ==> strict_subtuple R** xm ym" apply (erule converse_tranclp_induct) apply (metis r_into_rtranclp strict_subtuple_mono) using strict_subtuple_trans'' by blast
lemma trancl_to_strict_subtuple': "acyclicP_on (fmran' ym) R ==> (strict_subtuple (λx y. R x y ∨ x = y))++ xm ym ==> strict_subtuple (λx y. R x y ∨ x = y)** xm ym" apply (erule converse_tranclp_induct) apply (metis (no_types, lifting) r_into_rtranclp strict_subtuple_mono) using strict_subtuple_trans''' by blast
lemma subtuple_rtranclp_intro: assumes"∧xm ym. R (f xm) (f ym) ==> subtuple R xm ym" and"bij_on_trancl R f" and"R** (f xm) (f ym)" shows"subtuple R** xm ym" proof - have"(λxm ym. R (f xm) (f ym))** xm ym" apply (insert assms(2) assms(3)) by (rule reflect_rtranclp; auto) with assms(1) have"(subtuple R)** xm ym" by (metis (mono_tags, lifting) mono_rtranclp) hence"subtuple R** xm ym" by (rule rtrancl_to_subtuple) thus ?thesis by simp qed
lemma strict_subtuple_rtranclp_intro: assumes"∧xm ym. R (f xm) (f ym) ==> strict_subtuple (λx y. R x y ∨ x = y) xm ym" and"bij_on_trancl R f" and"acyclicP_on (fmran' ym) R" and"R++ (f xm) (f ym)" shows"strict_subtuple R** xm ym" proof - have"(λxm ym. R (f xm) (f ym))++ xm ym" apply (insert assms(1) assms(2) assms(4)) by (rule reflect_tranclp; auto) hence"(strict_subtuple (λx y. R x y ∨ x = y))++ xm ym" by (rule tranclp_trans_induct;
auto simp add: assms(1) tranclp.r_into_trancl) with assms(3) have"strict_subtuple (λx y. R x y ∨ x = y)** xm ym" by (rule trancl_to_strict_subtuple') thus ?thesis by simp qed
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.