(*
introduction of the Isabelle introduction
https://qiita.com/myuon_myon/items/11bb5bfc2e274fdaea7c
*)

theory "intro_intro"
imports Main
begin

lemma ex:
  fixes n :: nat
  assumes "n \<ge> 2"
  shows "2*n \<le> n^2"
  using assms
  apply (induct n, simp)
  apply simp
  apply (subst Suc_eq_plus1)+
  apply (subst power2_sum)
  apply auto
  done

lemma ex':
  fixes n :: nat
  assumes "n \<ge> 2"
  shows "2 * n \<le> n^2"
  using assms     (* this is "assums" *)

proof (induct n, simp)
  fix n :: nat
  assume a : "2 \<le> n \<Longrightarrow> 2 * n \<le> n^2" and b: "2 \<le> Suc n"
  have "2 * Suc n \<le> 2 * (n + 1)" using a b by simp
  also have "\<dots> \<le> 2 * n + 2" by simp
  also have "\<dots> \<le> n^2 + 2 * n + 1" using b by simp
  also have "\<dots> = (n + 1)^2" using power2_sum [of n 1] by simp
  finally
  show "2 * Suc n \<le> (Suc n)^2" by simp
qed

end


theory conditions
  imports boolean_algebra
begin

(** We define and interrelate some useful axiomatic conditions on unary operations
(operators) having a 'w-parametric type @{type "('w \<sigma> \<Rightarrow> 'w \<sigma>)"} (i.e. @{type "('w\<Rightarrow>bool)\<Rightarrow>('w\<Rightarrow>bool)"}).
Those operations are aimed at extending a Boolean algebra towards different sorts of topological Boolean algebras.*)

named_theorems cond

(**Monotonicity (MONO).*)
definition MONO::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("MONO")
  where "MONO \<phi> \<equiv> \<forall>A B. A \<preceq> B \<longrightarrow> \<phi> A \<preceq> \<phi> B"

declare MONO_def[cond]

lemma MONO_dual: "MONO \<phi> = MONO \<phi>\<^sup>d" by (smt (verit, best) BA_cp MONO_def dual_invol op_dual_def op_equal_equ)
lemma MONO_ant: "MONO \<phi> \<Longrightarrow> \<forall>A B C. A \<preceq> B \<longrightarrow> \<phi>(B \<^bold>\<rightarrow> C) \<preceq> \<phi>(A \<^bold>\<rightarrow> C)" by (metis (full_types) MONO_def impl_def subset_def)
lemma MONO_cons: "MONO \<phi> \<Longrightarrow> \<forall>A B C. A \<preceq> B \<longrightarrow> \<phi>(C \<^bold>\<rightarrow> A) \<preceq> \<phi>(C \<^bold>\<rightarrow> B)" by (metis (full_types) MONO_def impl_def subset_def)

(**Expansive/extensive (EXPN) and its dual contractive (CNTR).*)
definition EXPN::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("EXPN")
  where "EXPN \<phi>  \<equiv> \<forall>A. A \<preceq> \<phi> A"
definition CNTR::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("CNTR")
  where "CNTR \<phi> \<equiv> \<forall>A. \<phi> A \<preceq> A"

declare EXPN_def[cond] CNTR_def[cond]

lemma EXPN_CNTR_dual1: "EXPN \<phi> = CNTR \<phi>\<^sup>d" by (metis BA_cp BA_dn CNTR_def EXPN_def op_dual_def)
lemma EXPN_CNTR_dual2: "EXPN \<phi> = CNTR \<phi>\<^sup>d" by (simp add: EXPN_CNTR_dual1)

(**Normality (NORM) and its dual (DNRM).*)
definition NORM::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("NORM")
  where "NORM \<phi>  \<equiv> (\<phi> \<^bold>\<bottom>) \<approx> \<^bold>\<bottom>"
definition DNRM::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("DNRM")
  where "DNRM \<phi> \<equiv> (\<phi> \<^bold>\<top>) \<approx> \<^bold>\<top>"

declare NORM_def[cond] DNRM_def[cond]

lemma NOR_dual1: "NORM \<phi> = DNRM \<phi>\<^sup>d" unfolding NORM_def DNRM_def op_dual_def order conn by simp
lemma NOR_dual2: "DNRM \<phi> = NORM \<phi>\<^sup>d" by (metis NOR_dual1 dual_invol op_equal_equ)

(**EXPN (resp. CNTR) entail DNRM (resp. NORM).*)
lemma EXPN_impl_DNRM: "EXPN \<phi> \<Longrightarrow> DNRM \<phi>" by (simp add: EXPN_def DNRM_def setequ_def subset_def top_def)
lemma CNTR_impl_NORM: "CNTR \<phi> \<Longrightarrow> NORM \<phi>" by (metis NORM_def bottom_def CNTR_def setequ_def subset_def)

(**Idempotence (IDEM).*)
definition IDEM::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("IDEM")
  where "IDEM \<phi>  \<equiv> \<forall>A. (\<phi> A) \<approx> \<phi>(\<phi> A)"
definition IDEM_a::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("IDEM\<^sup>a")
  where "IDEM_a \<phi> \<equiv> \<forall>A. (\<phi> A) \<preceq> \<phi>(\<phi> A)"
definition IDEM_b::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("IDEM\<^sup>b")
  where "IDEM_b \<phi> \<equiv> \<forall>A. (\<phi> A) \<succeq> \<phi>(\<phi> A)"
lemma IDEM_char: "IDEM \<phi> = (IDEM_a \<phi> \<and> IDEM_b \<phi>)" using IDEM_def IDEM_a_def IDEM_b_def by (metis setequ_def)

declare IDEM_def[cond] IDEM_a_def[cond] IDEM_b_def[cond]

lemma IDEM_dual1: "IDEM\<^sup>a \<phi> = IDEM\<^sup>b \<phi>\<^sup>d" unfolding IDEM_a_def IDEM_b_def by (smt (verit, best) BA_cp dual_invol ofp_c ofp_d ofp_invol op_compl_def op_dual_def op_equal_equ)
lemma IDEM_dual2: "IDEM\<^sup>b \<phi> = IDEM\<^sup>a \<phi>\<^sup>d" by (metis IDEM_dual1 dual_invol op_equal_equ)
lemma IDEM_dual: "IDEM \<phi> = IDEM \<phi>\<^sup>d" unfolding IDEM_def by (metis IDEM_a_def IDEM_b_def IDEM_dual1 IDEM_dual2 setequ_def)

(**EXPN (resp. CNTR) entail IDEM-a (resp. IDEM-b).*)
lemma EXPN_impl_IDEM_a: "EXPN \<phi> \<Longrightarrow> IDEM\<^sup>a \<phi>" by (simp add: EXPN_def IDEM_a_def)
lemma CNTR_impl_IDEM_b: "CNTR \<phi> \<Longrightarrow> IDEM\<^sup>b \<phi>" by (simp add: CNTR_def IDEM_b_def)

(**IDEM has the property of collapsing the range and the set of fixed-points of an operator*)
lemma IDEM_Ra_fp: "IDEM \<phi> \<Longrightarrow> \<lbrakk>\<phi> -\<rbrakk> = fp \<phi>" unfolding IDEM_def fixpoint_pred_def setequ_equ range_def by fastforce

(**Distribution over joins or additivity (ADDI).*)
definition ADDI::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("ADDI")
  where "ADDI \<phi>   \<equiv> \<forall>A B. \<phi>(A \<^bold>\<or> B) \<approx> (\<phi> A) \<^bold>\<or> (\<phi> B)"
definition ADDI_a::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("ADDI\<^sup>a")
  where "ADDI\<^sup>a \<phi> \<equiv> \<forall>A B. \<phi>(A \<^bold>\<or> B) \<preceq> (\<phi> A) \<^bold>\<or> (\<phi> B)"
definition ADDI_b::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("ADDI\<^sup>b")
  where "ADDI\<^sup>b \<phi> \<equiv> \<forall>A B. \<phi>(A \<^bold>\<or> B) \<succeq> (\<phi> A) \<^bold>\<or> (\<phi> B)"

declare ADDI_def[cond] ADDI_a_def[cond] ADDI_b_def[cond]

(**Distribution over meets or multiplicativity (MULT).*)
definition MULT::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("MULT")
  where "MULT \<phi>   \<equiv> \<forall>A B. \<phi>(A \<^bold>\<and> B) \<approx> (\<phi> A) \<^bold>\<and> (\<phi> B)"
definition MULT_a::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("MULT\<^sup>a")
  where "MULT\<^sup>a \<phi> \<equiv> \<forall>A B. \<phi>(A \<^bold>\<and> B) \<preceq> (\<phi> A) \<^bold>\<and> (\<phi> B)"
definition MULT_b::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("MULT\<^sup>b")
  where "MULT_b \<phi> \<equiv> \<forall>A B. \<phi>(A \<^bold>\<and> B) \<succeq> (\<phi> A) \<^bold>\<and> (\<phi> B)"

declare MULT_def[cond] MULT_a_def[cond] MULT_b_def[cond]

lemma ADDI_char: "ADDI \<phi> = (ADDI\<^sup>a \<phi> \<and> ADDI\<^sup>b \<phi>)" using ADDI_a_def ADDI_b_def ADDI_def by (metis setequ_def)
lemma MULT_char: "MULT \<phi> = (MULT\<^sup>a \<phi> \<and> MULT\<^sup>b \<phi>)" using MULT_a_def MULT_b_def MULT_def by (metis setequ_def)

(**MONO, MULT-a and ADDI-b are equivalent.*)
lemma MONO_MULTa: "MULT\<^sup>a \<phi> = MONO \<phi>" by (smt (verit, ccfv_threshold) L10 L3 L4 L5 L8 MONO_def MULT_a_def setequ_equ subset_transitive transitive_def)
lemma MONO_ADDIb: "ADDI\<^sup>b \<phi> = MONO \<phi>" unfolding MONO_def ADDI_b_def by (smt (verit, del_insts) L9 join_def setequ_equ subset_def)

(**Below we prove several duality relationships between ADDI(a/b) and MULT(a/b).*)

(**The first duality is an easy corollary of the previous equivalence.*)
lemma MULTa_ADDIb_dual1: "MULT\<^sup>a \<phi> = ADDI\<^sup>b \<phi>\<^sup>d" using MONO_ADDIb MONO_MULTa MONO_dual by auto
lemma MULTa_ADDIb_dual2: "ADDI\<^sup>b \<phi> = MULT\<^sup>a \<phi>\<^sup>d" using MONO_ADDIb MONO_MULTa MONO_dual by auto

(*these two lemmas below are introduced for technical reasons (as stepping stones)*)
lemma MULTb_impl_ADDIa: "\<forall>\<phi>. MULT\<^sup>b \<phi> \<longrightarrow> ADDI\<^sup>a \<phi>\<^sup>d" unfolding MULT_b_def ADDI_a_def op_dual_def order conn by auto
lemma ADDIa_impl_MULTb: "\<forall>\<phi>. ADDI\<^sup>a \<phi> \<longrightarrow> MULT\<^sup>b \<phi>\<^sup>d" proof -
    { fix \<phi>::"('w \<sigma> \<Rightarrow> 'w \<sigma>)" { assume cl1a: "ADDI\<^sup>a \<phi>"
      { fix A and B
        have "\<^bold>\<midarrow>\<phi>(\<^bold>\<midarrow>(A \<^bold>\<and> B)) \<approx> \<^bold>\<midarrow>\<phi>(\<^bold>\<midarrow>A \<^bold>\<or> \<^bold>\<midarrow>B)" unfolding conn order by simp
        moreover from cl1a have "\<^bold>\<midarrow>(\<phi>(\<^bold>\<midarrow>A) \<^bold>\<or> \<phi>(\<^bold>\<midarrow>B)) \<preceq> \<^bold>\<midarrow>\<phi>(\<^bold>\<midarrow>A \<^bold>\<or> \<^bold>\<midarrow>B)" using ADDI_a_def BA_cp by blast
        ultimately have "\<^bold>\<midarrow>(\<phi>(\<^bold>\<midarrow>A)) \<^bold>\<and> \<^bold>\<midarrow>(\<phi>(\<^bold>\<midarrow>B)) \<preceq> \<^bold>\<midarrow>\<phi>(\<^bold>\<midarrow>(A \<^bold>\<and> B))" unfolding conn by simp
        hence "(\<phi>\<^sup>d A) \<^bold>\<and> (\<phi>\<^sup>d B) \<preceq> (\<phi>\<^sup>d (A \<^bold>\<and> B))" unfolding op_dual_def by simp
      } hence "MULT\<^sup>b \<phi>\<^sup>d" using MULT_b_def by blast
    } hence "ADDI\<^sup>a \<phi> \<longrightarrow> MULT\<^sup>b \<phi>\<^sup>d" by simp
} thus "\<forall>\<phi>. ADDI\<^sup>a \<phi> \<longrightarrow> MULT\<^sup>b \<phi>\<^sup>d" by blast qed

(**Duality between ADDI-a and MULT-b.*)
lemma ADDIa_MULTb_dual1: "ADDI\<^sup>a \<phi> = MULT\<^sup>b \<phi>\<^sup>d" by (metis dual_invol op_equal_equ MULTb_impl_ADDIa ADDIa_impl_MULTb)
lemma ADDIa_MULTb_dual2: "MULT\<^sup>b \<phi> = ADDI\<^sup>a \<phi>\<^sup>d" by (metis ADDIa_MULTb_dual1 dual_invol op_equal_equ)

(**Duality between ADDI and MULT.*)
lemma ADDI_MULT_dual1: "ADDI \<phi> = MULT \<phi>\<^sup>d" using ADDI_char ADDIa_MULTb_dual1 MULT_char MULTa_ADDIb_dual2 by blast
lemma ADDI_MULT_dual2: "MULT \<phi> = ADDI \<phi>\<^sup>d" using ADDI_char ADDIa_MULTb_dual2 MULT_char MULTa_ADDIb_dual1 by blast

(**We verify properties regarding closure over meets/joins for fixed-points.*)

(**MULT and ADDI imply meet-closed and join-closed respectively (the converse requires additional assumptions)*)
lemma MULT_meetclosed: "MULT \<phi> \<Longrightarrow> meet_closed (fp \<phi>)" by (simp add: MULT_def fixpoint_pred_def meet_closed_def setequ_equ)
lemma "meet_closed (fp \<phi>) \<Longrightarrow> MULT \<phi>" nitpick oops (*countermodel*)
lemma meetclosed_MULT: "MONO \<phi> \<Longrightarrow> CNTR \<phi> \<Longrightarrow> IDEM\<^sup>a \<phi> \<Longrightarrow> meet_closed (fp \<phi>) \<Longrightarrow> MULT \<phi>"
  unfolding MONO_def CNTR_def IDEM_a_def meet_closed_def by (smt (z3) L12 L8 MULT_def fixpoint_pred_def meet_def setequ_def setequ_equ subset_def)

lemma ADDI_joinclosed: "ADDI \<phi> \<Longrightarrow> join_closed (fp \<phi>)" by (simp add: ADDI_def fixpoint_pred_def join_closed_def setequ_equ)
lemma "join_closed (fp \<phi>) \<Longrightarrow> ADDI \<phi>" nitpick oops (*countermodel*)
lemma joinclosed_ADDI: "MONO \<phi> \<Longrightarrow> EXPN \<phi> \<Longrightarrow> IDEM\<^sup>b \<phi> \<Longrightarrow> join_closed (fp \<phi>) \<Longrightarrow> ADDI \<phi>"
  by (smt (verit) ADDI_def BA_cp BA_deMorgan1 BA_dn EXPN_CNTR_dual2 IDEM_dual2 MONO_dual MULT_a_def MULT_b_def MULT_char dual_invol fp_join_meet_closed_dual meetclosed_MULT op_dual_def op_equal_equ setequ_def)

(**Assuming MONO, we have that EXPN (resp. CNTR) implies meet-closed (resp. join-closed) for @{text "\<phi>"}'s fixed-points.*)
lemma EXPN_meetclosed: "MONO \<phi> \<Longrightarrow> EXPN \<phi> \<Longrightarrow> meet_closed (fp \<phi>)"
  by (smt (verit) EXPN_def MONO_MULTa MULT_a_def fixpoint_pred_def meet_closed_def setequ_def setequ_equ)
lemma CNTR_meetclosed: "MONO \<phi> \<Longrightarrow> CNTR \<phi> \<Longrightarrow> join_closed (fp \<phi>)"
  by (smt (verit, ccfv_threshold) ADDI_b_def CNTR_def MONO_ADDIb fixpoint_pred_def join_closed_def setequ_def setequ_equ)
(**Further assuming IDEM the above results can be stated to the whole range of @{text "\<phi>"}.*)
lemma "MONO \<phi> \<Longrightarrow> EXPN \<phi> \<Longrightarrow> IDEM \<phi> \<Longrightarrow> meet_closed (\<lbrakk>\<phi> -\<rbrakk>)"
  by (smt (verit, ccfv_threshold) EXPN_def IDEM_Ra_fp L3 L4 L5 L8 MONO_def fixpoint_pred_def meet_closed_def setequ_def setequ_equ)
lemma "MONO \<phi> \<Longrightarrow> CNTR \<phi> \<Longrightarrow> IDEM \<phi> \<Longrightarrow> join_closed (\<lbrakk>\<phi> -\<rbrakk>)"
  by (smt (verit, del_insts) BA_deMorgan1 BA_dn CNTR_def IDEM_Ra_fp L3 L4 L5 L7 MONO_def fixpoint_pred_def join_closed_def setequ_def setequ_equ)

(**Properties regarding distribution over implication/difference.*)
definition DISTR_impl_inc::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("DISTR\<^sub>\<rightarrow>\<^sup>i")
  where "DISTR\<^sub>\<rightarrow>\<^sup>i \<phi> \<equiv> \<forall>A B. \<phi> (A \<^bold>\<rightarrow> B) \<preceq> (\<phi> A) \<^bold>\<rightarrow> (\<phi> B)"
definition DISTR_impl_dec::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("DISTR\<^sub>\<rightarrow>\<^sup>d")
  where "DISTR\<^sub>\<rightarrow>\<^sup>d \<phi> \<equiv> \<forall>A B. \<phi> (A \<^bold>\<rightarrow> B) \<succeq> (\<phi> A) \<^bold>\<rightarrow> (\<phi> B)"

definition DISTR_diff_inc::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("DISTR\<^sub>\<leftharpoonup>\<^sup>i")
  where "DISTR\<^sub>\<leftharpoonup>\<^sup>i \<phi> \<equiv> \<forall>A B. \<phi> (A \<^bold>\<leftharpoonup> B) \<preceq> (\<phi> A) \<^bold>\<leftharpoonup> (\<phi> B)"
definition DISTR_diff_dec::"('w \<sigma> \<Rightarrow> 'w \<sigma>) \<Rightarrow> bool" ("DISTR\<^sub>\<leftharpoonup>\<^sup>d")
  where "DISTR\<^sub>\<leftharpoonup>\<^sup>d \<phi> \<equiv> \<forall>A B. \<phi> (A \<^bold>\<leftharpoonup> B) \<succeq> (\<phi> A) \<^bold>\<leftharpoonup> (\<phi> B)"

lemma DISTR_diff_inc_prop: "MONO \<phi> \<Longrightarrow> CNTR \<phi> \<Longrightarrow> DISTR\<^sub>\<leftharpoonup>\<^sup>i \<phi>" unfolding DISTR_diff_inc_def CNTR_def by (smt (verit) MONO_def diff_def subset_def)
lemma DISTR_impl_inc_prop: "MULT \<phi> \<Longrightarrow> DISTR\<^sub>\<rightarrow>\<^sup>i \<phi>" proof -
  assume mult: "MULT \<phi>"
  { fix a::"'a \<sigma>" and b::"'a \<sigma>"
    have "a \<^bold>\<and> b = a \<^bold>\<and> (a \<^bold>\<rightarrow> b)" unfolding conn by blast
    hence "\<phi>(a \<^bold>\<and> b) = \<phi>(a \<^bold>\<and> (a \<^bold>\<rightarrow> b))" by simp
    moreover from mult have "\<phi>(a \<^bold>\<and> b) \<approx> \<phi> a \<^bold>\<and> \<phi> b" by (simp add: MULT_def)
    moreover from mult have "\<phi>(a \<^bold>\<and> (a \<^bold>\<rightarrow> b)) \<approx> \<phi> a \<^bold>\<and> \<phi> (a \<^bold>\<rightarrow> b)" by (simp add: MULT_def)
    ultimately have "\<phi> a \<^bold>\<and> \<phi> (a \<^bold>\<rightarrow> b) \<approx> \<phi> a \<^bold>\<and> \<phi> b" by (simp add: setequ_equ)
    hence "\<phi> a \<^bold>\<and> \<phi> (a \<^bold>\<rightarrow> b) \<approx> \<phi> a \<^bold>\<and> (\<phi> a \<^bold>\<rightarrow> \<phi> b)" unfolding conn order by blast
    hence "\<phi>(a \<^bold>\<rightarrow> b) \<preceq> \<phi> a \<^bold>\<rightarrow> \<phi> b" unfolding conn order by blast
  } thus ?thesis by (simp add: DISTR_impl_inc_def)
qed
lemma DISTR_impl_dec_prop: "MONO \<phi> \<Longrightarrow> EXPN \<phi> \<Longrightarrow> DISTR\<^sub>\<rightarrow>\<^sup>d \<phi>" by (smt (verit, best) DISTR_impl_dec_def EXPN_def MONO_def impl_def subset_def)
lemma DISTR_diff_dec_prop: "ADDI \<phi> \<Longrightarrow> DISTR\<^sub>\<leftharpoonup>\<^sup>d \<phi>" proof -
  assume addi: "ADDI \<phi>"
  { fix a::"'a \<sigma>" and b::"'a \<sigma>"
    have "a \<^bold>\<or> b = (a \<^bold>\<leftharpoonup> b) \<^bold>\<or> b" unfolding conn by blast
    hence "\<phi>(a \<^bold>\<or> b) = \<phi>((a \<^bold>\<leftharpoonup> b) \<^bold>\<or> b)" by simp
    moreover from addi have "\<phi>(a \<^bold>\<or> b) \<approx> \<phi> a \<^bold>\<or> \<phi> b" by (simp add: ADDI_def)
    moreover from addi have "\<phi>((a \<^bold>\<leftharpoonup> b) \<^bold>\<or> b) \<approx> \<phi> (a \<^bold>\<leftharpoonup> b) \<^bold>\<or> (\<phi> b)" by (simp add: ADDI_def)
    ultimately have "\<phi> a \<^bold>\<or> \<phi> b \<approx> \<phi>(a \<^bold>\<leftharpoonup> b) \<^bold>\<or> \<phi> b" unfolding order by metis
    hence "(\<phi> a \<^bold>\<leftharpoonup> \<phi> b) \<^bold>\<or> \<phi> b \<approx> \<phi>(a \<^bold>\<leftharpoonup> b) \<^bold>\<or> \<phi> b" unfolding conn order by blast
    hence "\<phi> a \<^bold>\<leftharpoonup> \<phi> b \<preceq> \<phi> (a \<^bold>\<leftharpoonup> b)" unfolding conn order by blast
  } thus ?thesis by (simp add: DISTR_diff_dec_def)
qed

lemma ADDI_distr_impl_dual: "ADDI \<phi> \<Longrightarrow> \<forall>A B. \<phi>\<^sup>d(A \<^bold>\<rightarrow> B) \<preceq> \<phi> A \<^bold>\<rightarrow> \<phi> B" by (smt (verit) BA_cp BA_dn DISTR_diff_dec_def DISTR_diff_dec_prop impl_diff_rel op_dual_def setequ_equ)
lemma MULT_distr_diff_dual: "MULT \<phi> \<Longrightarrow> \<forall>A B. \<phi>\<^sup>d(A \<^bold>\<leftharpoonup> B) \<succeq> \<phi> A \<^bold>\<leftharpoonup> \<phi> B" by (smt (verit) BA_cp BA_dn DISTR_impl_inc_def DISTR_impl_inc_prop impl_diff_rel op_dual_def setequ_equ)
lemma ADDI_distr_diff_dual: "ADDI \<phi> \<Longrightarrow> \<forall>A B. \<phi>(A \<^bold>\<leftharpoonup> B) \<succeq> \<phi>\<^sup>d A \<^bold>\<leftharpoonup> \<phi>\<^sup>d B" by (smt (verit, ccfv_SIG) ADDI_MULT_dual1 BA_cp BA_dn DISTR_impl_inc_def DISTR_impl_inc_prop impl_diff_rel op_dual_def setequ_equ)
lemma MULT_distr_impl_dual: "MULT \<phi> \<Longrightarrow> \<forall>A B. \<phi>(A \<^bold>\<rightarrow> B) \<preceq> \<phi>\<^sup>d A \<^bold>\<rightarrow> \<phi>\<^sup>d B" by (metis ADDI_MULT_dual2 ADDI_distr_impl_dual dual_invol op_equal_equ)

end


(*  Title:      FOL/ex/Nat_Class.thy
    Author:     Markus Wenzel, TU Muenchen
*)

section \<open>Theory of the natural numbers: Peano's axioms, primitive recursion\<close>

theory Nat_Class
  imports FOL
begin

text \<open>
  This is an abstract version of \<^file>\<open>Nat.thy\<close>. Instead of axiomatizing a
  single type \<open>nat\<close>, it defines the class of all these types (up to
  isomorphism).

  Note: The \<open>rec\<close> operator has been made \<^emph>\<open>monomorphic\<close>, because class
  axioms cannot contain more than one type variable.
\<close>

class nat =
  fixes Zero :: \<open>'a\<close>  (\<open>0\<close>)
    and Suc :: \<open>'a \<Rightarrow> 'a\<close>
    and rec :: \<open>'a \<Rightarrow> 'a \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> 'a\<close>
  assumes induct: \<open>P(0) \<Longrightarrow> (\<And>x. P(x) \<Longrightarrow> P(Suc(x))) \<Longrightarrow> P(n)\<close>
    and Suc_inject: \<open>Suc(m) = Suc(n) \<Longrightarrow> m = n\<close>
    and Suc_neq_Zero: \<open>Suc(m) = 0 \<Longrightarrow> R\<close>
    and rec_Zero: \<open>rec(0, a, f) = a\<close>
    and rec_Suc: \<open>rec(Suc(m), a, f) = f(m, rec(m, a, f))\<close>
begin

definition add :: \<open>'a \<Rightarrow> 'a \<Rightarrow> 'a\<close>  (infixl \<open>+\<close> 60)
  where \<open>m + n = rec(m, n, \<lambda>x y. Suc(y))\<close>

lemma Suc_n_not_n: \<open>Suc(k) \<noteq> (k::'a)\<close>
  apply (rule_tac n = \<open>k\<close> in induct)
   apply (rule notI)
   apply (erule Suc_neq_Zero)
  apply (rule notI)
  apply (erule notE)
  apply (erule Suc_inject)
  done

lemma \<open>(k + m) + n = k + (m + n)\<close>
  apply (rule induct)
  back
  back
  back
  back
  back
  oops

lemma add_Zero [simp]: \<open>0 + n = n\<close>
  apply (unfold add_def)
  apply (rule rec_Zero)
  done

lemma add_Suc [simp]: \<open>Suc(m) + n = Suc(m + n)\<close>
  apply (unfold add_def)
  apply (rule rec_Suc)
  done

lemma add_Zero_right: \<open>m + 0 = m\<close>
  apply (rule_tac n = \<open>m\<close> in induct)
   apply simp
  apply simp
  done

lemma add_Suc_right: \<open>m + Suc(n) = Suc(m + n)\<close>
  apply (rule_tac n = \<open>m\<close> in induct)
   apply simp_all
  done

lemma
  assumes prem: \<open>\<And>n. f(Suc(n)) = Suc(f(n))\<close>
  shows \<open>f(i + j) = i + f(j)\<close>
  apply (rule_tac n = \<open>i\<close> in induct)
   apply simp
  apply (simp add: prem)
  done

end

end


(* Author: Gerwin Klein, 2012
   Maintainers: Gerwin Klein <kleing at cse.unsw.edu.au>
                Rafal Kolanski <rafal.kolanski at nicta.com.au>
*)

section "Equivalence between Separation Algebra Formulations"

theory Sep_Eq
imports Separation_Algebra Separation_Algebra_Alt
begin

text \<open>
  In this theory we show that our total formulation of separation algebra is
  equivalent in strength to Calcagno et al's original partial one.

  This theory is not intended to be included in own developments.
\<close>

no_notation map_add (infixl "++" 100)

section "Total implies Partial"

definition add2 :: "'a::sep_algebra => 'a => 'a option" where
  "add2 x y \<equiv> if x ## y then Some (x + y) else None"

lemma add2_zero: "add2 x 0 = Some x"
  by (simp add: add2_def)

lemma add2_assoc:
  "lift2 add2 a (lift2 add2 b c) = lift2 add2 (lift2 add2 a b) c"
  by (auto simp: add2_def lift2_def sep_add_assoc
              dest: sep_disj_addD sep_disj_addI3
                    sep_add_disjD sep_disj_addI2 sep_disj_commuteI
              split: option.splits)

interpretation total_partial: sep_algebra_alt 0 add2
  by (unfold_locales) (auto intro: add2_zero add2_comm add2_assoc)

section "Partial implies Total"

definition
  sep_add' :: "'a \<Rightarrow> 'a \<Rightarrow> 'a :: sep_algebra_alt" where
  "sep_add' x y \<equiv> if disjoint x y then the (add x y) else undefined"

lemma sep_disj_zero':
  "disjoint x 0"
  by simp

lemma sep_disj_commuteI':
  "disjoint x y \<Longrightarrow> disjoint y x"
  by (clarsimp simp: disjoint_def add_comm)

lemma sep_add_zero':
  "sep_add' x 0 = x"
  by (simp add: sep_add'_def)

lemma sep_add_commute':
  "disjoint x y \<Longrightarrow> sep_add' x y = sep_add' y x"
  by (clarsimp simp: sep_add'_def disjoint_def add_comm)

lemma sep_add_assoc':
  "\<lbrakk> disjoint x y; disjoint y z; disjoint x z \<rbrakk> \<Longrightarrow>
  sep_add' (sep_add' x y) z = sep_add' x (sep_add' y z)"
  using add_assoc [of "Some x" "Some y" "Some z"]
  by (clarsimp simp: disjoint_def sep_add'_def lift2_def
               split: option.splits)

lemma sep_disj_addD1':
  "disjoint x (sep_add' y z) \<Longrightarrow> disjoint y z \<Longrightarrow> disjoint x y"
proof (clarsimp simp: disjoint_def sep_add'_def)
  fix a assume a: "y \<oplus> z = Some a"
  fix b assume b: "x \<oplus> a = Some b"
  with a have "Some x ++ (Some y ++ Some z) = Some b" by (simp add: lift2_def)
  hence "(Some x ++ Some y) ++ Some z = Some b" by (simp add: add_assoc)
  thus "\<exists>b. x \<oplus> y = Some b" by (simp add: lift2_def split: option.splits)
qed

lemma sep_disj_addI1':
  "disjoint x (sep_add' y z) \<Longrightarrow> disjoint y z \<Longrightarrow> disjoint (sep_add' x y) z"
  apply (clarsimp simp: disjoint_def sep_add'_def)
  apply (rule conjI)
   apply clarsimp
   apply (frule lift_to_add2, assumption)
   apply (simp add: add_assoc)
   apply (clarsimp simp: lift2_def add_comm)
  apply clarsimp
  apply (frule lift_to_add2, assumption)
  apply (simp add: add_assoc)
  apply (clarsimp simp: lift2_def)
  done

interpretation partial_total: sep_algebra sep_add' 0 disjoint
  apply (unfold_locales)
        apply (rule sep_disj_zero')
       apply (erule sep_disj_commuteI')
      apply (rule sep_add_zero')
     apply (erule sep_add_commute')
    apply (erule (2) sep_add_assoc')
   apply (erule (1) sep_disj_addD1')
  apply (erule (1) sep_disj_addI1')
  done

end


theory Ordered_Euclidean_Space
imports
  Cartesian_Euclidean_Space
  "~~/src/HOL/Library/Product_Order"
begin

subsection {* An ordering on euclidean spaces that will allow us to talk about intervals *}

class ordered_euclidean_space = ord + inf + sup + abs + Inf + Sup + euclidean_space +
  assumes eucl_le: "x \<le> y \<longleftrightarrow> (\<forall>i\<in>Basis. x \<bullet> i \<le> y \<bullet> i)"
  assumes eucl_less_le_not_le: "x < y \<longleftrightarrow> x \<le> y \<and> \<not> y \<le> x"
  assumes eucl_inf: "inf x y = (\<Sum>i\<in>Basis. inf (x \<bullet> i) (y \<bullet> i) *\<^sub>R i)"
  assumes eucl_sup: "sup x y = (\<Sum>i\<in>Basis. sup (x \<bullet> i) (y \<bullet> i) *\<^sub>R i)"
  assumes eucl_Inf: "Inf X = (\<Sum>i\<in>Basis. (INF x:X. x \<bullet> i) *\<^sub>R i)"
  assumes eucl_Sup: "Sup X = (\<Sum>i\<in>Basis. (SUP x:X. x \<bullet> i) *\<^sub>R i)"
  assumes eucl_abs: "abs x = (\<Sum>i\<in>Basis. abs (x \<bullet> i) *\<^sub>R i)"
begin

subclass order
  by default
    (auto simp: eucl_le eucl_less_le_not_le intro!: euclidean_eqI antisym intro: order.trans)

subclass ordered_ab_group_add_abs
  by default (auto simp: eucl_le inner_add_left eucl_abs abs_leI)

subclass ordered_real_vector
  by default (auto simp: eucl_le intro!: mult_left_mono mult_right_mono)

subclass lattice
  by default (auto simp: eucl_inf eucl_sup eucl_le)

subclass distrib_lattice
  by default (auto simp: eucl_inf eucl_sup sup_inf_distrib1 intro!: euclidean_eqI)

subclass conditionally_complete_lattice
proof
  fix z::'a and X::"'a set"
  assume "X \<noteq> {}"
  hence "\<And>i. (\<lambda>x. x \<bullet> i) ` X \<noteq> {}" by simp
  thus "(\<And>x. x \<in> X \<Longrightarrow> z \<le> x) \<Longrightarrow> z \<le> Inf X" "(\<And>x. x \<in> X \<Longrightarrow> x \<le> z) \<Longrightarrow> Sup X \<le> z"
    by (auto simp: eucl_Inf eucl_Sup eucl_le Inf_class.INF_def Sup_class.SUP_def
      simp del: Inf_class.Inf_image_eq Sup_class.Sup_image_eq
      intro!: cInf_greatest cSup_least)
qed (force intro!: cInf_lower cSup_upper
      simp: bdd_below_def bdd_above_def preorder_class.bdd_below_def preorder_class.bdd_above_def
        eucl_Inf eucl_Sup eucl_le Inf_class.INF_def Sup_class.SUP_def
      simp del: Inf_class.Inf_image_eq Sup_class.Sup_image_eq)+

lemma inner_Basis_inf_left: "i \<in> Basis \<Longrightarrow> inf x y \<bullet> i = inf (x \<bullet> i) (y \<bullet> i)"
  and inner_Basis_sup_left: "i \<in> Basis \<Longrightarrow> sup x y \<bullet> i = sup (x \<bullet> i) (y \<bullet> i)"
  by (simp_all add: eucl_inf eucl_sup inner_setsum_left inner_Basis if_distrib comm_monoid_add_class.setsum.delta
      cong: if_cong)

lemma inner_Basis_INF_left: "i \<in> Basis \<Longrightarrow> (INF x:X. f x) \<bullet> i = (INF x:X. f x \<bullet> i)"
  and inner_Basis_SUP_left: "i \<in> Basis \<Longrightarrow> (SUP x:X. f x) \<bullet> i = (SUP x:X. f x \<bullet> i)"
  using eucl_Sup [of "f ` X"] eucl_Inf [of "f ` X"] by (simp_all add: comp_def)

lemma abs_inner: "i \<in> Basis \<Longrightarrow> abs x \<bullet> i = abs (x \<bullet> i)"
  by (auto simp: eucl_abs)

lemma
  abs_scaleR: "\<bar>a *\<^sub>R b\<bar> = \<bar>a\<bar> *\<^sub>R \<bar>b\<bar>"
  by (auto simp: eucl_abs abs_mult intro!: euclidean_eqI)

lemma interval_inner_leI:
  assumes "x \<in> {a .. b}" "0 \<le> i"
  shows "a\<bullet>i \<le> x\<bullet>i" "x\<bullet>i \<le> b\<bullet>i"
  using assms
  unfolding euclidean_inner[of a i] euclidean_inner[of x i] euclidean_inner[of b i]
  by (auto intro!: setsum_mono mult_right_mono simp: eucl_le)

lemma inner_nonneg_nonneg:
  shows "0 \<le> a \<Longrightarrow> 0 \<le> b \<Longrightarrow> 0 \<le> a \<bullet> b"
  using interval_inner_leI[of a 0 a b]
  by auto

lemma inner_Basis_mono:
  shows "a \<le> b \<Longrightarrow> c \<in> Basis  \<Longrightarrow> a \<bullet> c \<le> b \<bullet> c"
  by (simp add: eucl_le)

lemma Basis_nonneg[intro, simp]: "i \<in> Basis \<Longrightarrow> 0 \<le> i"
  by (auto simp: eucl_le inner_Basis)

lemma Sup_eq_maximum_componentwise:
  fixes s::"'a set"
  assumes i: "\<And>b. b \<in> Basis \<Longrightarrow> X \<bullet> b = i b \<bullet> b"
  assumes sup: "\<And>b x. b \<in> Basis \<Longrightarrow> x \<in> s \<Longrightarrow> x \<bullet> b \<le> X \<bullet> b"
  assumes i_s: "\<And>b. b \<in> Basis \<Longrightarrow> (i b \<bullet> b) \<in> (\<lambda>x. x \<bullet> b) ` s"
  shows "Sup s = X"
  using assms
  unfolding eucl_Sup euclidean_representation_setsum
  by (auto simp: Sup_class.SUP_def simp del: Sup_class.Sup_image_eq intro!: conditionally_complete_lattice_class.cSup_eq_maximum)

lemma Inf_eq_minimum_componentwise:
  assumes i: "\<And>b. b \<in> Basis \<Longrightarrow> X \<bullet> b = i b \<bullet> b"
  assumes sup: "\<And>b x. b \<in> Basis \<Longrightarrow> x \<in> s \<Longrightarrow> X \<bullet> b \<le> x \<bullet> b"
  assumes i_s: "\<And>b. b \<in> Basis \<Longrightarrow> (i b \<bullet> b) \<in> (\<lambda>x. x \<bullet> b) ` s"
  shows "Inf s = X"
  using assms
  unfolding eucl_Inf euclidean_representation_setsum
  by (auto simp: Inf_class.INF_def simp del: Inf_class.Inf_image_eq intro!: conditionally_complete_lattice_class.cInf_eq_minimum)

end

lemma
  compact_attains_Inf_componentwise:
  fixes b::"'a::ordered_euclidean_space"
  assumes "b \<in> Basis" assumes "X \<noteq> {}" "compact X"
  obtains x where "x \<in> X" "x \<bullet> b = Inf X \<bullet> b" "\<And>y. y \<in> X \<Longrightarrow> x \<bullet> b \<le> y \<bullet> b"
proof atomize_elim
  let ?proj = "(\<lambda>x. x \<bullet> b) ` X"
  from assms have "compact ?proj" "?proj \<noteq> {}"
    by (auto intro!: compact_continuous_image continuous_intros)
  from compact_attains_inf[OF this]
  obtain s x
    where s: "s\<in>(\<lambda>x. x \<bullet> b) ` X" "\<And>t. t\<in>(\<lambda>x. x \<bullet> b) ` X \<Longrightarrow> s \<le> t"
      and x: "x \<in> X" "s = x \<bullet> b" "\<And>y. y \<in> X \<Longrightarrow> x \<bullet> b \<le> y \<bullet> b"
    by auto
  hence "Inf ?proj = x \<bullet> b"
    by (auto intro!: conditionally_complete_lattice_class.cInf_eq_minimum simp del: Inf_class.Inf_image_eq)
  hence "x \<bullet> b = Inf X \<bullet> b"
    by (auto simp: eucl_Inf Inf_class.INF_def inner_setsum_left inner_Basis if_distrib `b \<in> Basis` setsum.delta
      simp del: Inf_class.Inf_image_eq
      cong: if_cong)
  with x show "\<exists>x. x \<in> X \<and> x \<bullet> b = Inf X \<bullet> b \<and> (\<forall>y. y \<in> X \<longrightarrow> x \<bullet> b \<le> y \<bullet> b)" by blast
qed

lemma
  compact_attains_Sup_componentwise:
  fixes b::"'a::ordered_euclidean_space"
  assumes "b \<in> Basis" assumes "X \<noteq> {}" "compact X"
  obtains x where "x \<in> X" "x \<bullet> b = Sup X \<bullet> b" "\<And>y. y \<in> X \<Longrightarrow> y \<bullet> b \<le> x \<bullet> b"
proof atomize_elim
  let ?proj = "(\<lambda>x. x \<bullet> b) ` X"
  from assms have "compact ?proj" "?proj \<noteq> {}"
    by (auto intro!: compact_continuous_image continuous_intros)
  from compact_attains_sup[OF this]
  obtain s x
    where s: "s\<in>(\<lambda>x. x \<bullet> b) ` X" "\<And>t. t\<in>(\<lambda>x. x \<bullet> b) ` X \<Longrightarrow> t \<le> s"
      and x: "x \<in> X" "s = x \<bullet> b" "\<And>y. y \<in> X \<Longrightarrow> y \<bullet> b \<le> x \<bullet> b"
    by auto
  hence "Sup ?proj = x \<bullet> b"
    by (auto intro!: cSup_eq_maximum simp del: Sup_image_eq)
  hence "x \<bullet> b = Sup X \<bullet> b"
    by (auto simp: eucl_Sup[where 'a='a] SUP_def inner_setsum_left inner_Basis if_distrib `b \<in> Basis` setsum.delta
      simp del: Sup_image_eq cong: if_cong)
  with x show "\<exists>x. x \<in> X \<and> x \<bullet> b = Sup X \<bullet> b \<and> (\<forall>y. y \<in> X \<longrightarrow> y \<bullet> b \<le> x \<bullet> b)" by blast
qed

lemma (in order) atLeastatMost_empty'[simp]:
  "(~ a <= b) \<Longrightarrow> {a..b} = {}"
  by (auto)

instance real :: ordered_euclidean_space
  by default (auto simp: INF_def SUP_def)

lemma in_Basis_prod_iff:
  fixes i::"'a::euclidean_space*'b::euclidean_space"
  shows "i \<in> Basis \<longleftrightarrow> fst i = 0 \<and> snd i \<in> Basis \<or> snd i = 0 \<and> fst i \<in> Basis"
  by (cases i) (auto simp: Basis_prod_def)

instantiation prod::(abs, abs) abs
begin

definition "abs x = (abs (fst x), abs (snd x))"

instance proof qed
end

instance prod :: (ordered_euclidean_space, ordered_euclidean_space) ordered_euclidean_space
  by default
    (auto intro!: add_mono simp add: euclidean_representation_setsum'  Ball_def inner_prod_def
      in_Basis_prod_iff inner_Basis_inf_left inner_Basis_sup_left inner_Basis_INF_left Inf_prod_def
      inner_Basis_SUP_left Sup_prod_def less_prod_def less_eq_prod_def eucl_le[where 'a='a]
      eucl_le[where 'a='b] abs_prod_def abs_inner)

text{* Instantiation for intervals on @{text ordered_euclidean_space} *}

lemma
  fixes a :: "'a\<Colon>ordered_euclidean_space"
  shows cbox_interval: "cbox a b = {a..b}"
    and interval_cbox: "{a..b} = cbox a b"
    and eucl_le_atMost: "{x. \<forall>i\<in>Basis. x \<bullet> i <= a \<bullet> i} = {..a}"
    and eucl_le_atLeast: "{x. \<forall>i\<in>Basis. a \<bullet> i <= x \<bullet> i} = {a..}"
    by (auto simp: eucl_le[where 'a='a] eucl_less_def box_def cbox_def)

lemma closed_eucl_atLeastAtMost[simp, intro]:
  fixes a :: "'a\<Colon>ordered_euclidean_space"
  shows "closed {a..b}"
  by (simp add: cbox_interval[symmetric] closed_cbox)

lemma closed_eucl_atMost[simp, intro]:
  fixes a :: "'a\<Colon>ordered_euclidean_space"
  shows "closed {..a}"
  by (simp add: eucl_le_atMost[symmetric])

lemma closed_eucl_atLeast[simp, intro]:
  fixes a :: "'a\<Colon>ordered_euclidean_space"
  shows "closed {a..}"
  by (simp add: eucl_le_atLeast[symmetric])

lemma bounded_closed_interval:
  fixes a :: "'a::ordered_euclidean_space"
  shows "bounded {a .. b}"
  using bounded_cbox[of a b]
  by (metis interval_cbox)

lemma convex_closed_interval:
  fixes a :: "'a::ordered_euclidean_space"
  shows "convex {a .. b}"
  using convex_box[of a b]
  by (metis interval_cbox)

lemma image_affinity_interval: fixes m::real
  fixes a b c :: "'a::ordered_euclidean_space"
  shows "(\<lambda>x. m *\<^sub>R x + c) ` {a..b} =
    (if {a..b} = {} then {}
     else (if 0 \<le> m then {m *\<^sub>R a + c .. m *\<^sub>R b + c}
     else {m *\<^sub>R b + c .. m *\<^sub>R a + c}))"
  using image_affinity_cbox[of m c a b]
  by (simp add: cbox_interval)

lemma image_smult_interval:"(\<lambda>x. m *\<^sub>R (x::_::ordered_euclidean_space)) ` {a .. b} =
  (if {a .. b} = {} then {} else if 0 \<le> m then {m *\<^sub>R a .. m *\<^sub>R b} else {m *\<^sub>R b .. m *\<^sub>R a})"
  using image_smult_cbox[of m a b]
  by (simp add: cbox_interval)

lemma is_interval_closed_interval:
  "is_interval {a .. (b::'a::ordered_euclidean_space)}"
  by (metis cbox_interval is_interval_cbox)

lemma compact_interval:
  fixes a b::"'a::ordered_euclidean_space"
  shows "compact {a .. b}"
  by (metis compact_cbox interval_cbox)

no_notation
  eucl_less (infix "<e" 50)

lemma One_nonneg: "0 \<le> (\<Sum>Basis::'a::ordered_euclidean_space)"
  by (auto intro: setsum_nonneg)

lemma content_closed_interval:
  fixes a :: "'a::ordered_euclidean_space"
  assumes "a \<le> b"
  shows "content {a .. b} = (\<Prod>i\<in>Basis. b\<bullet>i - a\<bullet>i)"
  using content_cbox[of a b] assms
  by (simp add: cbox_interval eucl_le[where 'a='a])

lemma integrable_const_ivl[intro]:
  fixes a::"'a::ordered_euclidean_space"
  shows "(\<lambda>x. c) integrable_on {a .. b}"
  unfolding cbox_interval[symmetric]
  by (rule integrable_const)

lemma integrable_on_subinterval:
  fixes f :: "'n::ordered_euclidean_space \<Rightarrow> 'a::banach"
  assumes "f integrable_on s"
    and "{a .. b} \<subseteq> s"
  shows "f integrable_on {a .. b}"
  using integrable_on_subcbox[of f s a b] assms
  by (simp add: cbox_interval)

lemma
  fixes a b::"'a::ordered_euclidean_space"
  shows bdd_above_cbox[intro, simp]: "bdd_above (cbox a b)"
    and bdd_below_cbox[intro, simp]: "bdd_below (cbox a b)"
    and bdd_above_box[intro, simp]: "bdd_above (box a b)"
    and bdd_below_box[intro, simp]: "bdd_below (box a b)"
  unfolding atomize_conj
  by (metis bdd_above_Icc bdd_above_mono bdd_below_Icc bdd_below_mono bounded_box
    bounded_subset_cbox interval_cbox)

instantiation vec :: (ordered_euclidean_space, finite) ordered_euclidean_space
begin

definition "inf x y = (\<chi> i. inf (x $ i) (y $ i))"
definition "sup x y = (\<chi> i. sup (x $ i) (y $ i))"
definition "Inf X = (\<chi> i. (INF x:X. x $ i))"
definition "Sup X = (\<chi> i. (SUP x:X. x $ i))"
definition "abs x = (\<chi> i. abs (x $ i))"

instance
  apply default
  unfolding euclidean_representation_setsum'
  apply (auto simp: less_eq_vec_def inf_vec_def sup_vec_def Inf_vec_def Sup_vec_def inner_axis
    Basis_vec_def inner_Basis_inf_left inner_Basis_sup_left inner_Basis_INF_left
    inner_Basis_SUP_left eucl_le[where 'a='a] less_le_not_le abs_vec_def abs_inner)
  done

end

end