Theory VS_Vector_Spaces

(* Title: Examples/Vector_Spaces/VS_Vector_Spaces.thy
   Author: Mihails Milehins
   Copyright 2021 (C) Mihails Milehins
*)
section‹Vector spaces›
theory VS_Vector_Spaces
  imports VS_Modules
begin



subsectionvector_space_with›

locale vector_space_with = ab_group_add plusVS zeroVS minusVS uminusVS
  for plusVS :: "['vs, 'vs]  'vs" (infixl +VS 65)
    and zeroVS (0VS)
    and minusVS (infixl -VS 65)
    and uminusVS (-VS _› [81] 80) +
  fixes scale :: "['f::field, 'vs]  'vs" (infixr "*swith" 75)
  assumes scale_right_distrib[algebra_simps]: 
    "a *swith (x +VS y) = a *swith x +VS a *swith y"
    and scale_left_distrib[algebra_simps]:
      "(a + b) *swith x = a *swith x +VS b *swith x"
    and scale_scale[simp]: "a *swith (b *swith x) = (a * b) *swith x"
    and scale_one[simp]: "1 *swith x = x"
begin

notation plusVS (infixl +VS 65)
  and zeroVS (0VS)
  and minusVS (infixl -VS 65)
  and uminusVS (-VS _› [81] 80)
  and scale (infixr "*swith" 75)
  
end

lemma vector_space_with_overloaded[ud_with]: 
  "vector_space = vector_space_with (+) 0 (-) uminus"
  unfolding vector_space_def vector_space_with_def vector_space_with_axioms_def
  by (simp add: field_axioms ab_group_add_axioms)

locale vector_space_pair_with =
  VS1: vector_space_with plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1 +
  VS2: vector_space_with plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
  for plusVS_1 :: "['vs_1, 'vs_1]  'vs_1" (infixl +VS'_1 65)
    and zeroVS_1 (0VS'_1)
    and minusVS_1 (infixl -VS'_1 65)
    and uminusVS_1 (-VS'_1 _› [81] 80)
    and scale1 :: "['f::field, 'vs_1]  'vs_1"  (infixr *swith'_1 75)
    and plusVS_2 :: "['vs_2, 'vs_2]  'vs_2" (infixl +VS'_2 65)
    and zeroVS_2 (0VS'_2)
    and minusVS_2 (infixl -VS'_2 65)
    and uminusVS_2 (-VS'_2 _› [81] 80)
    and scale2 :: "['f::field, 'vs_2]  'vs_2" (infixr *swith'_2 75)

lemma vector_space_pair_with_overloaded[ud_with]: 
  "vector_space_pair = 
    (
      λscale1 scale2. 
        vector_space_pair_with (+) 0 (-) uminus scale1 (+) 0 (-) uminus scale2
    )"
  unfolding vector_space_pair_def vector_space_pair_with_def 
  unfolding vector_space_with_overloaded
  ..

locale linear_with =
  VS1: vector_space_with plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1 +
  VS2: vector_space_with plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2 +
  module_hom_with 
    plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1
    plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
    f 
  for plusVS_1 :: "['vs_1, 'vs_1]  'vs_1" (infixl +VS'_1 65)
    and zeroVS_1 (0VS'_1)
    and minusVS_1 (infixl -VS'_1 65)
    and uminusVS_1 (-VS'_1 _› [81] 80)
    and scale1 :: "['f::field, 'vs_1]  'vs_1"  (infixr *swith'_1 75)
    and plusVS_2 :: "['vs_2, 'vs_2]  'vs_2" (infixl +VS'_2 65)
    and zeroVS_2 (0VS'_2)
    and minusVS_2 (infixl -VS'_2 65)
    and uminusVS_2 (-VS'_2 _› [81] 80)
    and scale2 :: "['f::field, 'vs_2]  'vs_2" (infixr *swith'_2 75)
    and f :: "'vs_1  'vs_2"

lemma linear_with_overloaded[ud_with]: 
  "Vector_Spaces.linear = 
    (
      λscale1 scale2. 
        linear_with (+) 0 (-) uminus scale1 (+) 0 (-) uminus scale2
    )"
  unfolding 
    Vector_Spaces.linear_def linear_with_def 
    vector_space_with_overloaded module_hom_with_overloaded
  ..

locale finite_dimensional_vector_space_with = 
  vector_space_with plusVS zeroVS minusVS uminusVS scale
  for plusVS :: "['vs, 'vs]  'vs"
    and zeroVS 
    and minusVS 
    and uminusVS 
    and scale :: "['f::field, 'vs]  'vs" +
  fixes basis :: "'vs set"
  assumes finite_basis: "finite basis"
    and independent_basis: "independent_with 0 0VS (+VS) (*swith) basis"
    and span_basis: "span.with 0VS (+VS) (*swith) basis = UNIV"

lemma finite_dimensional_vector_space_with_overloaded[ud_with]: 
  "finite_dimensional_vector_space = 
    finite_dimensional_vector_space_with (+) 0 (-) uminus"
  unfolding
    finite_dimensional_vector_space_def
    finite_dimensional_vector_space_axioms_def
    finite_dimensional_vector_space_with_def
    finite_dimensional_vector_space_with_axioms_def
  by (intro ext)
    (
      auto simp: 
        vector_space_with_overloaded 
        dependent.with 
        module_iff_vector_space
        span.with 
    )

locale finite_dimensional_vector_space_pair_1_with = 
  VS1: finite_dimensional_vector_space_with 
    plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1 basis1 +
  VS2: vector_space_with 
    plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
  for plusVS_1 :: "['vs_1, 'vs_1]  'vs_1" (infixl +VS'_1 65)
    and zeroVS_1 (0VS'_1)
    and minusVS_1 (infixl -VS'_1 65)
    and uminusVS_1 (-VS'_1 _› [81] 80)
    and scale1 :: "['f::field, 'vs_1]  'vs_1" (infixr *swith'_1 75)
    and basis1
    and plusVS_2 :: "['vs_2, 'vs_2]  'vs_2" (infixl +VS'_2 65)
    and zeroVS_2 (0VS'_2)
    and minusVS_2 (infixl -VS'_2 65)
    and uminusVS_2 (-VS'_2 _› [81] 80)
    and scale2 :: "['f::field, 'vs_2]  'vs_2" (infixr *swith'_2 75)

lemma finite_dimensional_vector_space_pair_1_with_overloaded[ud_with]: 
  "finite_dimensional_vector_space_pair_1 = 
    (
      λscale1 basis1 scale2. 
        finite_dimensional_vector_space_pair_1_with 
          (+) 0 (-) uminus scale1 basis1 (+) 0 (-) uminus scale2
    )"
  unfolding
    finite_dimensional_vector_space_pair_1_def
    finite_dimensional_vector_space_pair_1_with_def    
    vector_space_with_overloaded
  by (simp add: finite_dimensional_vector_space_with_overloaded)

locale finite_dimensional_vector_space_pair_with = 
  VS1: finite_dimensional_vector_space_with 
    plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1 basis1 +
  VS2: finite_dimensional_vector_space_with 
    plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2 basis2
  for plusVS_1 :: "['vs_1, 'vs_1]  'vs_1" (infixl +VS'_1 65)
    and zeroVS_1 (0VS'_1)
    and minusVS_1 (infixl -VS'_1 65)
    and uminusVS_1 (-VS'_1 _› [81] 80)
    and scale1 :: "['f::field, 'vs_1]  'vs_1" (infixr *swith'_1 75)
    and basis1
    and plusVS_2 :: "['vs_2, 'vs_2]  'vs_2" (infixl +VS'_2 65)
    and zeroVS_2 (0VS'_2)
    and minusVS_2 (infixl -VS'_2 65)
    and uminusVS_2 (-VS'_2 _› [81] 80)
    and scale2 :: "['f::field, 'vs_2]  'vs_2" (infixr *swith'_2 75)
    and basis2

lemma finite_dimensional_vector_space_pair_with_overloaded[ud_with]: 
  "finite_dimensional_vector_space_pair = 
    (
      λscale1 basis1 scale2 basis2. 
        finite_dimensional_vector_space_pair_with 
          (+) 0 (-) uminus scale1 basis1 (+) 0 (-) uminus scale2 basis2
    )"
  unfolding
    finite_dimensional_vector_space_pair_def
    finite_dimensional_vector_space_pair_with_def
    finite_dimensional_vector_space_with_overloaded
  ..



subsectionvector_space_ow›


subsubsection‹Definitions and common properties›


text‹Single vector space.›

locale vector_space_ow = ab_group_add_ow UVS plusVS zeroVS minusVS uminusVS
  for UVS :: "'vs set" 
    and plusVS (infixl +VS 65)
    and zeroVS (0VS)
    and minusVS (infixl -VS 65)
    and uminusVS (-VS _› [81] 80) +
  fixes scale :: "['f::field, 'vs]  'vs" (infixr "*sow" 75)
  assumes scale_closed[simp, intro]: "x  UVS  a *sow x  UVS"
    and scale_right_distrib[algebra_simps]: 
    " x  UVS; y  UVS   a *sow (x +VS y) = a *sow x +VS a *sow y"
    and scale_left_distrib[algebra_simps]: 
      "x  UVS  (a + b) *sow x = a *sow x +VS b *sow x"
    and scale_scale[simp]: 
      "x  UVS  a *sow (b *sow x) = (a * b) *sow x"
    and scale_one[simp]: "x  UVS  1 *sow x = x"
begin

lemma scale_closed'[simp]: "a. xUVS. a *sow x  UVS" by simp

lemma minus_closed'[simp]: "xUVS. yUVS. x -VS y  UVS"
  by (simp add: ab_diff_conv_add_uminus add_closed' uminus_closed)

lemma uminus_closed'[simp]: "xUVS. -VS x  UVS" by (simp add: uminus_closed)

tts_register_sbts (*sow) | UVS
  by (rule tts_AB_C_transfer[OF scale_closed]) 
    (auto simp: bi_unique_eq right_total_eq)

sublocale implicitVS: module_ow UVS plusVS zeroVS minusVS uminusVS scale
  by unfold_locales (simp_all add: scale_right_distrib scale_left_distrib)

end

ud vector_space.dim
ud dim' dim


text‹Pair of vector spaces.›

locale vector_space_pair_ow = 
  VS1: vector_space_ow UVS_1 plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1 +
  VS2: vector_space_ow UVS_2 plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
  for UVS_1 :: "'vs_1 set"
    and plusVS_1 (infixl +VS'_1 65)
    and zeroVS_1 (0VS'_1)
    and minusVS_1 (infixl -VS'_1 65)
    and uminusVS_1 (-VS'_1 _› [81] 80)
    and scale1 :: "['f::field, 'vs_1]  'vs_1" (infixr *sow'_1 75)
    and UVS_2 :: "'vs_2 set"
    and plusVS_2 (infixl +VS'_2 65)
    and zeroVS_2 (0VS'_2)
    and minusVS_2 (infixl -VS'_2 65)
    and uminusVS_2 (-VS'_2 _› [81] 80)
    and scale2 :: "['f::field, 'vs_2]  'vs_2" (infixr *sow'_2 75)
begin

sublocale implicitVS: module_pair_ow 
  UVS_1 plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1
  UVS_2 plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
  by unfold_locales

end


text‹Linear map.›

locale linear_ow =
  VS1: vector_space_ow UVS_1 plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1 +
  VS2: vector_space_ow UVS_2 plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2 +
  module_hom_ow 
    UVS_1 plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1
    UVS_2 plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
    f 
  for UVS_1 :: "'vs_1 set"
    and plusVS_1 (infixl +VS'_1 65)
    and zeroVS_1 (0VS'_1)
    and minusVS_1 (infixl -VS'_1 65)
    and uminusVS_1 (-VS'_1 _› [81] 80)
    and scale1 :: "['f::field, 'vs_1]  'vs_1" (infixr *sow'_1 75)
    and UVS_2 :: "'vs_2 set"
    and plusVS_2 (infixl +VS'_2 65)
    and zeroVS_2 (0VS'_2)
    and minusVS_2 (infixl -VS'_2 65)
    and uminusVS_2 (-VS'_2 _› [81] 80)
    and scale2 :: "['f::field, 'vs_2]  'vs_2" (infixr *sow'_2 75)
    and f :: "'vs_1  'vs_2"
begin

sublocale implicitVS: vector_space_pair_ow
  UVS_1 plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1
  UVS_2 plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
  by unfold_locales

end


text‹Single finite dimensional vector space.›

locale finite_dimensional_vector_space_ow = 
  vector_space_ow UVS plusVS zeroVS minusVS uminusVS scale
  for UVS :: "'vs set"
    and plusVS (infixl +VS 65)
    and zeroVS (0VS)
    and minusVS (infixl -VS 65)
    and uminusVS (-VS _› [81] 80) 
    and scale :: "['f::field, 'vs]  'vs" (infixr "*sow" 75) +
  fixes basis :: "'vs set"
  assumes basis_closed: "basis  UVS"
    and finite_basis: "finite basis"
    and independent_basis: "independent_with 0 zeroVS plusVS scale basis"
    and span_basis: "span.with zeroVS plusVS scale basis = UVS"


text‹Pair of finite dimensional vector spaces.›

locale finite_dimensional_vector_space_pair_1_ow =
  VS1: finite_dimensional_vector_space_ow
    UVS_1 plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1 basis1 +
  VS2: vector_space_ow 
    UVS_2 plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
  for UVS_1 :: "'vs_1 set"
    and plusVS_1 (infixl +VS'_1 65)
    and zeroVS_1 (0VS'_1)
    and minusVS_1 (infixl -VS'_1 65)
    and uminusVS_1 (-VS'_1 _› [81] 80)
    and scale1 :: "['f::field, 'vs_1]  'vs_1" (infixr *sow'_1 75)
    and basis1
    and UVS_2 :: "'vs_2 set"
    and plusVS_2 (infixl +VS'_2 65)
    and zeroVS_2 (0VS'_2)
    and minusVS_2 (infixl -VS'_2 65)
    and uminusVS_2 (-VS'_2 _› [81] 80)
    and scale2 :: "['f::field, 'vs_2]  'vs_2" (infixr *sow'_2 75)

locale finite_dimensional_vector_space_pair_ow = 
  VS1: finite_dimensional_vector_space_ow 
    UVS_1 plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1 basis1 + 
  VS2: finite_dimensional_vector_space_ow 
    UVS_2 plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2 basis2
  for UVS_1 :: "'vs_1 set"
    and plusVS_1 (infixl +VS'_1 65)
    and zeroVS_1 (0VS'_1)
    and minusVS_1 (infixl -VS'_1 65)
    and uminusVS_1 (-VS'_1 _› [81] 80)
    and scale1 :: "['f::field, 'vs_1]  'vs_1" (infixr *sow'_1 75)
    and basis1
    and UVS_2 :: "'vs_2 set"
    and plusVS_2 (infixl +VS'_2 65)
    and zeroVS_2 (0VS'_2)
    and minusVS_2 (infixl -VS'_2 65)
    and uminusVS_2 (-VS'_2 _› [81] 80)
    and scale2 :: "['f::field, 'vs_2]  'vs_2" (infixr *sow'_2 75)
    and basis2


subsubsection‹Transfer.›

lemma vector_space_with_transfer[transfer_rule]:
  includes lifting_syntax
  assumes [transfer_rule]: "bi_unique B" "right_total B"     
  fixes PP lhs
  defines
    "PP  
      (
        (B ===> B ===> B) ===>
        B ===>
        (B ===> B ===> B) ===>
        (B ===> B) ===>
        ((=) ===> B ===> B) ===>
        (=)
      )"
    and
      "lhs  
        (
          λplusVS zeroVS minusVS uminusVS scale.
            vector_space_ow 
              (Collect (Domainp B)) plusVS zeroVS minusVS uminusVS scale
        )"
  shows "PP lhs vector_space_with"
proof-
  let ?rhs = 
    "(
      λplusVS zeroVS minusVS uminusVS scale.
        (a  UNIV. x  UNIV. scale a x  UNIV) 
         vector_space_with plusVS zeroVS minusVS uminusVS scale
    )"
  have "PP lhs ?rhs"
    unfolding 
      PP_def lhs_def
      vector_space_ow_def vector_space_with_def
      vector_space_ow_axioms_def vector_space_with_axioms_def
    apply transfer_prover_start
    apply transfer_step+
    by (intro ext) blast
  then show ?thesis by simp
qed

lemma vector_space_pair_with_transfer[transfer_rule]:
  includes lifting_syntax
  assumes [transfer_rule]: 
    "bi_unique B1" "right_total B1" "bi_unique B2" "right_total B2"     
  fixes PP lhs
  defines
    "PP  
      (
        (B1 ===> B1 ===> B1) ===>
        B1 ===>
        (B1 ===> B1 ===> B1) ===>
        (B1 ===> B1) ===>
        ((=) ===> B1 ===> B1) ===>
        (B2 ===> B2 ===> B2) ===>
        B2 ===>
        (B2 ===> B2 ===> B2) ===>
        (B2 ===> B2) ===>
        ((=) ===> B2 ===> B2) ===>
        (=)
    )"
    and
      "lhs  
        (
          λ
            plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1
            plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2.
          vector_space_pair_ow 
            (Collect (Domainp B1)) plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1
            (Collect (Domainp B2)) plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
        )"
    shows "PP lhs vector_space_pair_with"
  unfolding PP_def lhs_def
  unfolding vector_space_pair_ow_def vector_space_pair_with_def
  by transfer_prover

lemma linear_with_transfer[transfer_rule]:
  includes lifting_syntax
  assumes [transfer_rule]: 
    "bi_unique B1" "right_total B1" "bi_unique B2" "right_total B2"     
  fixes PP lhs
  defines
    "PP  
      (
        (B1 ===> B1 ===> B1) ===>
        B1 ===>
        (B1 ===> B1 ===> B1) ===>
        (B1 ===> B1) ===>
        ((=) ===> B1 ===> B1) ===>
        (B2 ===> B2 ===> B2) ===>
        B2 ===>
        (B2 ===> B2 ===> B2) ===>
        (B2 ===> B2) ===>
        ((=) ===> B2 ===> B2) ===>
        (B1 ===> B2) ===>
        (=)
    )"
    and
      "lhs  
        (
          λ
            plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1
            plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
            f.
          linear_ow 
            (Collect (Domainp B1)) plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1
            (Collect (Domainp B2)) plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
            f
        )
      "
    shows "PP lhs linear_with"
  unfolding PP_def lhs_def
  unfolding linear_ow_def linear_with_def
  by transfer_prover

lemma linear_with_transfer'[transfer_rule]:
  includes lifting_syntax
  assumes [transfer_rule]: "bi_unique B" "right_total B"
  fixes PP lhs
  defines
    "PP  
      (
        (B ===> B ===> B) ===>
        B ===>
        (B ===> B ===> B) ===>
        (B ===> B) ===>
        ((=) ===> B ===> B) ===>
        (B ===> B ===> B) ===>
        B ===>
        (B ===> B ===> B) ===>
        (B ===> B) ===>
        ((=) ===> B ===> B) ===>
        (B ===> B) ===>
        (=)
    )"
    and
      "lhs  
        (
          λ
            plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1
            plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
            f.
          linear_ow 
            (Collect (Domainp B)) plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1
            (Collect (Domainp B)) plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
            f
        )
      "
    shows "PP lhs linear_with"
  unfolding PP_def lhs_def
  using assms(1,2) by (rule linear_with_transfer[OF assms(1,2)])

lemma finite_dimensional_vector_space_with_transfer[transfer_rule]:
  includes lifting_syntax
  assumes [transfer_rule]: "bi_unique B" "right_total B"     
  fixes PP lhs
  defines
    "PP  
      (
        (B ===> B ===> B) ===>
        B ===>
        (B ===> B ===> B) ===>
        (B ===> B) ===>
        ((=) ===> B ===> B) ===>
        rel_set B ===>
        (=)
      )"
    and
      "lhs  
        (
          λplusVS zeroVS minusVS uminusVS scale basis.
            finite_dimensional_vector_space_ow 
              (Collect (Domainp B)) plusVS zeroVS minusVS uminusVS scale basis
        )"
    shows "PP lhs finite_dimensional_vector_space_with"
proof-
  let ?rhs = 
    "(
      λplusVS zeroVS minusVS uminusVS scale basis.
        basis  UNIV 
        finite_dimensional_vector_space_with 
          plusVS zeroVS minusVS uminusVS scale basis
    )"
  have "PP lhs ?rhs"
    unfolding 
      PP_def lhs_def
      finite_dimensional_vector_space_ow_def 
      finite_dimensional_vector_space_with_def
      finite_dimensional_vector_space_ow_axioms_def
      finite_dimensional_vector_space_with_axioms_def
    apply transfer_prover_start
    apply transfer_step+
    by blast
  then show ?thesis by simp
qed

lemma finite_dimensional_vector_space_pair_1_with_transfer[transfer_rule]:
  includes lifting_syntax
  assumes [transfer_rule]: 
    "bi_unique B1" "right_total B1" "bi_unique B2" "right_total B2"     
  fixes PP lhs
  defines
    "PP  
      (
        (B1 ===> B1 ===> B1) ===>
        B1 ===>
        (B1 ===> B1 ===> B1) ===>
        (B1 ===> B1) ===>
        ((=) ===> B1 ===> B1) ===>
        rel_set B1 ===>
        (B2 ===> B2 ===> B2) ===>
        B2 ===>
        (B2 ===> B2 ===> B2) ===>
        (B2 ===> B2) ===>
        ((=) ===> B2 ===> B2) ===>
        (=)
    )"
    and
      "lhs  
        (
          λ
            plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1 basis1
            plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2.
          finite_dimensional_vector_space_pair_1_ow 
            (Collect (Domainp B1)) 
              plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1 basis1
            (Collect (Domainp B2)) 
              plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2
        )"
    shows "PP lhs finite_dimensional_vector_space_pair_1_with"
  unfolding PP_def lhs_def
  unfolding 
    finite_dimensional_vector_space_pair_1_ow_def
    finite_dimensional_vector_space_pair_1_with_def
  by transfer_prover

lemma finite_dimensional_vector_space_pair_with_transfer[transfer_rule]:
  includes lifting_syntax
  assumes [transfer_rule]: 
    "bi_unique B1" "right_total B1" "bi_unique B2" "right_total B2"     
  fixes PP lhs
  defines
    "PP  
      (
        (B1 ===> B1 ===> B1) ===>
        B1 ===>
        (B1 ===> B1 ===> B1) ===>
        (B1 ===> B1) ===>
        ((=) ===> B1 ===> B1) ===>
        rel_set B1 ===>
        (B2 ===> B2 ===> B2) ===>
        B2 ===>
        (B2 ===> B2 ===> B2) ===>
        (B2 ===> B2) ===>
        ((=) ===> B2 ===> B2) ===>
        rel_set B2 ===>
        (=)
      )"
    and
      "lhs  
        (
          λ
            plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1 basis1
            plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2 basis2.
          finite_dimensional_vector_space_pair_ow 
            (Collect (Domainp B1)) 
              plusVS_1 zeroVS_1 minusVS_1 uminusVS_1 scale1 basis1
            (Collect (Domainp B2)) 
              plusVS_2 zeroVS_2 minusVS_2 uminusVS_2 scale2 basis2
        )"
    shows "PP lhs finite_dimensional_vector_space_pair_with"
  unfolding PP_def lhs_def
  unfolding 
    finite_dimensional_vector_space_pair_ow_def
    finite_dimensional_vector_space_pair_with_def
  by transfer_prover



subsectionvector_space_on›

locale vector_space_on = module_on UVS scale
  for UVS and scale :: "'a::field  'b::ab_group_add  'b" (infixr "*s" 75)
begin

notation scale (infixr "*s" 75)

sublocale implicitVS: vector_space_ow UVS (+) 0 (-) uminus scale
  by unfold_locales 
    (simp_all add: scale_right_distrib_on scale_left_distrib_on)

lemmas ab_group_add_ow_axioms = implicitM.ab_group_add_ow_axioms
lemmas vector_space_ow_axioms = implicitVS.vector_space_ow_axioms

definition dim :: "'b set  nat"
  where "dim V = (if bUVS. ¬ dependent b  span b = span V
    then card (SOME b. b  UVS  ¬ dependent b  span b = span V)
    else 0)"

end

lemma vector_space_on_alt_def: "vector_space_on UVS = module_on UVS"
  unfolding vector_space_on_def module_on_def
  by auto

lemma implicit_vector_space_ow[tts_implicit]:
  "vector_space_ow UVS (+) 0 (-) uminus = vector_space_on UVS"
proof(intro ext, rule iffI)
  fix s :: "'a  'b  'b" 
  assume "vector_space_ow UVS (+) 0 (-) uminus s"
  then interpret vector_space_ow UVS (+) 0 (-) uminus s .
  show "vector_space_on UVS s"
    by 
      (
        simp add: 
          scale_left_distrib 
          scale_right_distrib
          module_on_def 
          vector_space_on_def
      )
qed (rule vector_space_on.vector_space_ow_axioms)

locale linear_on = 
  VS1: vector_space_on UM_1 scale1 +
  VS2: vector_space_on UM_2 scale2 +
  module_hom_on UM_1 UM_2 scale1 scale2 f
  for UM_1 UM_2 and scale1::"'a::field  'b  'b::ab_group_add"
    and scale2::"'a::field  'c  'c::ab_group_add"
    and f

lemma implicit_linear_on[tts_implicit]:
  "linear_ow UM_1 (+) 0 minus uminus scale1 UM_2 (+) 0 (-) uminus scale2 = 
    linear_on UM_1 UM_2 scale1 scale2"
  unfolding linear_ow_def linear_on_def tts_implicit ..

locale finite_dimensional_vector_space_on =
  vector_space_on UVS scale 
  for UVS :: "'b::ab_group_add set" 
    and scale :: "'a::field  'b  'b" +
  fixes basis :: "'b set"
  assumes finite_basis: "finite basis"
    and independent_basis: "¬ dependent basis"
    and span_basis: "span basis = UVS" 
    and basis_subset: "basis  UVS"
begin

sublocale implicitVS: 
  finite_dimensional_vector_space_ow UVS (+) 0 (-) uminus scale basis
  by unfold_locales 
    (
      simp_all add: 
        finite_basis 
        implicit_dependent_with 
        independent_basis  
        implicit_span_with
        span_basis
        basis_subset
    )

end

lemma implicit_finite_dimensional_vector_space_on[tts_implicit]:
  "finite_dimensional_vector_space_ow UVS (+) 0 minus uminus scale basis = 
    finite_dimensional_vector_space_on UVS scale basis"
  unfolding 
    finite_dimensional_vector_space_ow_def 
    finite_dimensional_vector_space_on_def  
    finite_dimensional_vector_space_ow_axioms_def
    finite_dimensional_vector_space_on_axioms_def  
    vector_space_on_alt_def
    tts_implicit
  by (metis module_on.implicit_dependent_with module_on.implicit_span_with)  

locale vector_space_pair_on = 
  VS1: vector_space_on UM_1 scale1 +
  VS2: vector_space_on UM_2 scale2
  for UM_1:: "'b::ab_group_add set" and UM_2::"'c::ab_group_add set"
    and scale1::"'a::field  _  _" (infixr *s1 75) 
    and scale2::"'a  _  _" (infixr *s2 75)
begin

notation scale1 (infixr *s1 75)
notation scale2 (infixr *s2 75)

sublocale module_pair_on UM_1 UM_2 scale1 scale2 by unfold_locales

sublocale implicitVS: 
  vector_space_pair_ow 
    UM_1 (+) 0 (-) uminus scale1 
    UM_2 (+) 0 (-) uminus scale2
  by unfold_locales

end

lemma implicit_vector_space_pair_on[tts_implicit]:
  "vector_space_pair_ow 
    UM_1 (+) 0 (-) uminus scale1 
    UM_2 (+) 0 (-) uminus scale2 = 
    vector_space_pair_on UM_1 UM_2 scale1 scale2"
  unfolding vector_space_pair_ow_def vector_space_pair_on_def tts_implicit ..

locale finite_dimensional_vector_space_pair_1_on =
  VS1: finite_dimensional_vector_space_on UM_1 scale1 basis1 +
  VS2: vector_space_on UM_2 scale2
  for UM_1 UM_2
    and scale1::"'a::field  'b::ab_group_add  'b"
    and scale2::"'a::field  'c::ab_group_add  'c"
    and basis1
begin

sublocale vector_space_pair_on UM_1 UM_2 scale1 scale2 by unfold_locales

sublocale implicitVS:
  finite_dimensional_vector_space_pair_1_ow 
    UM_1 (+) 0 (-) uminus scale1 basis1 UM_2 (+) 0 (-) uminus scale2
  by unfold_locales

end

lemma implicit_finite_dimensional_vector_space_pair_1_on[tts_implicit]:
  "finite_dimensional_vector_space_pair_1_ow 
    UM_1 (+) 0 minus uminus scale1 basis1 UM_2 (+) 0 (-) uminus scale2 = 
    finite_dimensional_vector_space_pair_1_on UM_1 UM_2 scale1 scale2 basis1"
  unfolding 
    finite_dimensional_vector_space_pair_1_ow_def 
    finite_dimensional_vector_space_pair_1_on_def 
    tts_implicit 
    ..

locale finite_dimensional_vector_space_pair_on =
  VS1: finite_dimensional_vector_space_on UM_1 scale1 basis1 +
  VS2: finite_dimensional_vector_space_on UM_2 scale2 basis2
  for UM_1 UM_2
    and scale1::"'a::field  'b::ab_group_add  'b"
    and scale2::"'a::field  'c::ab_group_add  'c"
    and basis1 basis2
begin

sublocale finite_dimensional_vector_space_pair_1_on UM_1 UM_2 scale1 scale2 
  by unfold_locales

sublocale implicitVS: 
  finite_dimensional_vector_space_pair_ow 
    UM_1 (+) 0 (-) uminus scale1 basis1 
    UM_2 (+) 0 (-) uminus scale2 basis2
  by unfold_locales

end

lemma implicit_finite_dimensional_vector_space_pair_on[tts_implicit]:
  "finite_dimensional_vector_space_pair_ow 
      UM_1 (+) 0 minus uminus scale1 basis1 
      UM_2 (+) 0 (-) uminus scale2 basis2 = 
    finite_dimensional_vector_space_pair_on 
      UM_1 UM_2 scale1 scale2 basis1 basis2"
  unfolding 
    finite_dimensional_vector_space_pair_ow_def 
    finite_dimensional_vector_space_pair_on_def 
    tts_implicit 
    ..



subsection‹Relativization : part I›

context vector_space_on
begin

tts_context
  tts: (?'b to UVS::'b set)
  rewriting ctr_simps
  substituting ab_group_add_ow_axioms
    and vector_space_ow_axioms
    and implicitM.module_ow_axioms
  applying 
    [
      OF 
        implicitM.carrier_ne 
        implicitM.add_closed' 
        implicitM.zero_closed 
        implicitVS.minus_closed' 
        implicitVS.uminus_closed' 
        implicitVS.scale_closed',
      unfolded tts_implicit
    ]
begin

tts_lemma linear_id: "linear_on UVS UVS (*s) (*s) id"
  is vector_space.linear_id.

tts_lemma linear_ident: "linear_on UVS UVS (*s) (*s) (λx. x)"
  is vector_space.linear_ident.
    
tts_lemma linear_scale_self: "linear_on UVS UVS (*s) (*s) ((*s) c)"
  is vector_space.linear_scale_self.
    
tts_lemma linear_scale_left:
  assumes "x  UVS"
  shows "linear_on UNIV UVS (*) (*s) (λr. r *s x)"
    is vector_space.linear_scale_left.
    
tts_lemma linear_uminus: "linear_on UVS UVS (*s) (*s) uminus"
    is vector_space.linear_uminus.
    
tts_lemma linear_imp_scale["consumes" - 1, "case_names" "1"]:
  assumes "range D  UVS"
    and "linear_on UNIV UVS (*) (*s) D"
    and "d. d  UVS; D = (λx. x *s d)  thesis"
  shows thesis
    is vector_space.linear_imp_scale.

tts_lemma scale_eq_0_iff:
  assumes "x  UVS"
  shows "(a *s x = 0) = (a = 0  x = 0)"
    is vector_space.scale_eq_0_iff.

tts_lemma scale_left_imp_eq:
  assumes "x  UVS" and "y  UVS" and "a  0" and "a *s x = a *s y"
  shows "x = y"
    is vector_space.scale_left_imp_eq.

tts_lemma scale_right_imp_eq:
  assumes "x  UVS" and "x  0" and "a *s x = b *s x"
  shows "a = b"
    is vector_space.scale_right_imp_eq.

tts_lemma scale_cancel_left:
  assumes "x  UVS" and "y  UVS"
  shows "(a *s x = a *s y) = (x = y  a = 0)"
    is vector_space.scale_cancel_left.

tts_lemma scale_cancel_right:
  assumes "x  UVS"
  shows "(a *s x = b *s x) = (a = b  x = 0)"
    is vector_space.scale_cancel_right.

tts_lemma injective_scale:
  assumes "c  0"
  shows "inj_on ((*s) c) UVS"
    is vector_space.injective_scale.

tts_lemma dependent_def:
  assumes "P  UVS"
  shows "dependent P = (xP. x  span (P - {x}))"
    is vector_space.dependent_def.

tts_lemma dependent_single:
  assumes "x  UVS"
  shows "dependent {x} = (x = 0)"
    is vector_space.dependent_single.

tts_lemma in_span_insert:
  assumes "a  UVS"
    and "b  UVS"
    and "S  UVS"
    and "a  span (insert b S)"
    and "a  span S"
  shows "b  span (insert a S)"
    is vector_space.in_span_insert.

tts_lemma dependent_insertD:
  assumes "a  UVS" and "S  UVS" and "a  span S" and "dependent (insert a S)"
  shows "dependent S"
    is vector_space.dependent_insertD.

tts_lemma independent_insertI:
  assumes "a  UVS" and "S  UVS" and "a  span S" and "¬ dependent S"
  shows "¬ dependent (insert a S)"
    is vector_space.independent_insertI.

tts_lemma independent_insert:
  assumes "a  UVS" and "S  UVS"
  shows "(¬ dependent (insert a S)) = 
    (if a  S then ¬ dependent S else ¬ dependent S  a  span S)"
    is vector_space.independent_insert.

tts_lemma maximal_independent_subset_extend["consumes" - 1, "case_names" "1"]:
  assumes "S  UVS"
    and "V  UVS"
    and "S  V"
    and "¬ dependent S"
    and "B. B  UVS; S  B; B  V; ¬ dependent B; V  span B  thesis"
  shows thesis
    is vector_space.maximal_independent_subset_extend.

tts_lemma maximal_independent_subset["consumes" - 1, "case_names" "1"]:
  assumes "V  UVS"
    and "B. B  UVS; B  V; ¬ dependent B; V  span B  thesis"
  shows thesis
    is vector_space.maximal_independent_subset.

tts_lemma in_span_delete:
  assumes "a  UVS"
    and "S  UVS"
    and "b  UVS"
    and "a  span S"
    and "a  span (S - {b})"
  shows "b  span (insert a (S - {b}))"
    is vector_space.in_span_delete.

tts_lemma span_redundant:
  assumes "x  UVS" and "S  UVS" and "x  span S"
  shows "span (insert x S) = span S"
    is vector_space.span_redundant.

tts_lemma span_trans:
  assumes "x  UVS"
    and "S  UVS"
    and "y  UVS"
    and "x  span S"
    and "y  span (insert x S)"
  shows "y  span S"
    is vector_space.span_trans.

tts_lemma span_insert_0:
  assumes "S  UVS"
  shows "span (insert 0 S) = span S"
    is vector_space.span_insert_0.

tts_lemma span_delete_0:
  assumes "S  UVS"
  shows "span (S - {0}) = span S"
    is vector_space.span_delete_0.

tts_lemma span_image_scale:
  assumes "S  UVS" and "finite S" and "x. x  UVS; x  S  c x  0"
  shows "span ((λx. c x *s x) ` S) = span S"
    is vector_space.span_image_scale.

tts_lemma exchange_lemma:
  assumes "T  UVS"
    and "S  UVS"
    and "finite T"
    and "¬dependent S"
    and "S  span T"
  shows "t'Pow UVS. 
    card t' = card T  finite t'  S  t'  t'  S  T  S  span t'"
    is vector_space.exchange_lemma.

tts_lemma independent_span_bound:
  assumes "T  UVS"
    and "S  UVS"
    and "finite T"
    and "¬ dependent S"
    and "S  span T"
  shows "finite S  card S  card T"
    is vector_space.independent_span_bound.

tts_lemma independent_explicit_finite_subsets:
  assumes "A  UVS"
  shows "(¬ dependent A) = 
    (
      xUVS. 
        x  A  
        finite x  
        (f. (vx. f v *s v) = 0  (xx. f x = 0))
    )"
    given vector_space.independent_explicit_finite_subsets by auto

tts_lemma independent_if_scalars_zero:
  assumes "A  UVS"
    and "finite A"
    and "f x. x  UVS; (xA. f x *s x) = 0; x  A  f x = 0"
  shows "¬ dependent A"
    is vector_space.independent_if_scalars_zero.

tts_lemma subspace_sums:
  assumes "S  UVS" and "T  UVS" and "subspace S" and "subspace T"
  shows "subspace {x  UVS. aUVS. bUVS. x = a + b  a  S  b  T}"
    is vector_space.subspace_sums.

tts_lemma bij_if_span_eq_span_bases:
  assumes "B  UVS"
    and "C  UVS"
    and "¬dependent B"
    and "¬dependent C"
    and "span B = span C"
  shows "x. bij_betw x B C  (aUVS. x a  UVS)"
    given vector_space.bij_if_span_eq_span_bases by blast

end

end



subsection‹Transfer: dim›

context vector_space_on
begin

lemma dim_eq_card:
  assumes "B  UVS"
    and "V  UVS"
    and BV: "span B = span V" 
    and B: "¬dependent B"
  shows "dim V = card B"
proof-
  define p where "p b  b  UVS  ¬dependent b  span b = span V" for b
  from assms have "p (SOME B. p B)"
    by (intro someI[of p B], unfold p_def) simp
  then have "f. bij_betw f B (SOME B. p B)  (xUVS. f x  UVS)"
    by (subst (asm) p_def, intro bij_if_span_eq_span_bases) (simp_all add: assms)
  then have "card B = card (SOME B. p B)" by (auto intro: bij_betw_same_card)
  then show ?thesis using assms(1,3,4) unfolding dim_def p_def by auto
qed

lemma dim_transfer[transfer_rule]: 
  includes lifting_syntax                               
  assumes [transfer_domain_rule]: "Domainp A = (λx. x  UVS)"
    and [transfer_rule]: "right_total A" "bi_unique A"
    and [transfer_rule]: "(A ===> A ===> A) plus plus'"
    and [transfer_rule]: "((=) ===> A ===> A) scale scale'"
    and [transfer_rule]: "A 0 zero'"
  shows "(rel_set A ===> (=)) dim (dim.with plus' zero' 0 scale')"
proof(rule rel_funI)
  
  (* preliminaries *)
  have rt_rlA: "right_total (rel_set A)"
    using assms using right_total_rel_set by auto
  have Dom_rsA: "Domainp (rel_set A) x = (x  UVS)" for x
    by (meson Domainp_set assms(1) in_mono subsetI)

  (* hypothesis and preliminary derived results *)
  fix V V' assume [transfer_rule]: "rel_set A V V'"
  with assms have subset: "V  UVS" 
    by (metis Domainp.DomainI rel_setD1 subsetI)
  then have "span V  UVS" by (simp add: span_minimal subspace_UNIV)

  (* convenience definitions *)
  define P' where "P' =
    (
      b. 
        (with 0 zero' plus' scale' : «independent» b)  
        (with zero' plus' scale' : «span» b) = 
          (with zero' plus' scale' : «span» V')
    )"
  define P where "P = 
    (bUVS. ¬ dependent b  span b = span V)"
  have "P = P'" 
    unfolding P_def P'_def by (transfer, unfold tts_implicit) blast
  define f where "f b = (b  UVS  ¬ dependent b  span b = span V)" for b
  define f' where "f' b = (b  UVS  f b)" for b
  have "f = f'" unfolding f'_def f_def by simp
  define g where "g b = 
    (
      (with 0 zero' plus' scale' : «independent» b)  
      (with zero' plus' scale': «span» b) = 
      (with zero' plus' scale' : «span» V')
    )"
    for b
  define g' where "g' b = (b  UNIV  g b)" for b
  have "g = g'" unfolding g_def g'_def by simp

  (* towards Eps_unique_transfer_lemma *)
  have fg[transfer_rule]: "(rel_set A ===> (=)) f g"
    unfolding g = g' 
    unfolding f_def g'_def g_def tts_implicit[symmetric]
    apply transfer_prover_start
    apply transfer_step+
    by simp
  have ex_Dom_rsA: "x. Domainp (rel_set A) x  f x"
    unfolding Dom_rsA f_def 
    by 
      (
        meson   
          span V  UVS 
          maximal_independent_subset 
          span_subspace 
          subspace_span 
          subset
      )
  have card_xy: "x y. g x; g y  card x = card y"
    by (transfer, unfold f_def) (metis dim_eq_card)

  (* main *)
  show "dim V = dim.with plus' zero' 0 scale' V'"
  proof(cases P')
    case True
    then have P unfolding P = P' .
    then have dim: "dim V = card (SOME b. f b)"
      unfolding dim_def P_def f_def by simp
    from True have dw: "dim.with plus' zero' 0 scale' V' = card (SOME b. g b)"
      unfolding dim.with_def P'_def g_def by simp
    from Eps_unique_transfer_lemma[
        OF rt_rlA fg card_transfer[OF bi_unique A] ex_Dom_rsA card_xy, 
        simplified,
        unfolded Dom_rsA,
        folded f'_def f = f'
        ]
    show "dim V = dim.with plus' zero' 0 scale' V'" 
      unfolding dim dw by simp
  next
    case False
    then have "¬P" unfolding P = P' .
    then have dim: "dim V = 0" unfolding dim_def P_def by auto 
    moreover from False have dw: "dim.with plus' zero'  0 scale' V' = 0"
      unfolding dim.with_def P'_def g_def by auto
    ultimately show ?thesis by simp
  qed

qed

end



subsection‹Relativization: part II›

context vector_space_on
begin

tts_context
  tts: (?'b to UVS::'b set)
  sbterms: ((+)::?'b::ab_group_add?'b?'b to (+)::'b'b'b)
    and 
      (
        ?scale::?'a::field ?'b::ab_group_add?'b::ab_group_add to 
        (*s)::'a'b'b
      )
    and (0::?'b::ab_group_add to 0::'b)
  rewriting ctr_simps
  substituting ab_group_add_ow_axioms 
    and vector_space_ow_axioms
    and implicitM.module_ow_axioms
  eliminating ?a  ?A and ?B  ?C through auto
  applying 
    [
      OF 
        implicitM.carrier_ne 
        implicitVS.minus_closed' 
        implicitVS.uminus_closed', 
      unfolded tts_implicit
     ]
begin

tts_lemma dim_unique:
  assumes "V  UVS"
    and "B  V"
    and "V  span B"
    and "¬ dependent B"
    and "card B = n"
  shows "dim V = n"
    is vector_space.dim_unique.
    
tts_lemma basis_card_eq_dim:
  assumes "V  UVS" and "B  V" and "V  span B" and "¬ dependent B"
  shows "card B = dim V"
    is vector_space.basis_card_eq_dim.
    
tts_lemma dim_eq_card_independent:
  assumes "B  UVS" and "¬ dependent B"
  shows "dim B = card B"
    is vector_space.dim_eq_card_independent.

tts_lemma dim_span:
  assumes "S  UVS"
  shows "dim (span S) = dim S"
    is vector_space.dim_span.

tts_lemma dim_span_eq_card_independent:
  assumes "B  UVS" and "¬ dependent B"
  shows "dim (span B) = card B"
    is vector_space.dim_span_eq_card_independent.

tts_lemma dim_le_card:
  assumes "V  UVS" and "W  UVS" and "V  span W" and "finite W"
  shows "dim V  card W"
    is vector_space.dim_le_card.

tts_lemma span_eq_dim:
  assumes "S  UVS" and "T  UVS" and "span S = span T"
  shows "dim S = dim T"
    is vector_space.span_eq_dim.

tts_lemma dim_le_card':
  assumes "s  UVS" and "finite s"
  shows "dim s  card s"
    is vector_space.dim_le_card'.

tts_lemma span_card_ge_dim:
  assumes "V  UVS" and "B  V" and "V  span B" and "finite B"
  shows "dim V  card B"
    is vector_space.span_card_ge_dim.

end

tts_context
  tts: (?'b to UVS::'b set) 
  sbterms: ((+)::?'b::ab_group_add?'b?'b to (+)::'b'b'b)
    and (?scale::?'a::field ?'b::ab_group_add?'b to (*s)::'a'b'b)
    and (0::?'b::ab_group_add to 0::'b)
  rewriting ctr_simps
  substituting ab_group_add_ow_axioms 
    and vector_space_ow_axioms
    and implicitM.module_ow_axioms
  applying 
    [
      OF 
        implicitM.carrier_ne 
        implicitVS.minus_closed' 
        implicitVS.uminus_closed', 
        unfolded tts_implicit
     ]
begin
  
tts_lemma basis_exists:
  assumes "V  UVS"
    and "B. 
      
        B  UVS; 
        B  V; 
        ¬ dependent B; 
        V  span B; 
        card B = dim V
        thesis"
  shows thesis
    is vector_space.basis_exists.

end

end

context finite_dimensional_vector_space_on 
begin

tts_context
  tts: (?'b to UVS::'b set)
  sbterms: ((+)::?'b::ab_group_add?'b?'b to (+)::'b'b'b)
    and (?scale::?'a::field ?'b::ab_group_add?'b to (*s)::'a'b'b)
    and (0::?'b::ab_group_add to 0::'b)
  rewriting ctr_simps
  substituting ab_group_add_ow_axioms
    and vector_space_ow_axioms
    and implicitVS.finite_dimensional_vector_space_ow_axioms
    and implicitM.module_ow_axioms
  eliminating ?a  ?A and ?B  ?C through auto
  applying 
    [
      OF 
        implicitM.carrier_ne 
        implicitVS.minus_closed' 
        implicitVS.uminus_closed' 
        basis_subset, 
      unfolded tts_implicit
    ]
begin

tts_lemma finiteI_independent:
  assumes "B  UVS" and "¬ dependent B"
  shows "finite B"
  is finite_dimensional_vector_space.finiteI_independent.

tts_lemma dim_empty: "dim {} = 0"
  is finite_dimensional_vector_space.dim_empty.
    
tts_lemma dim_insert:
  assumes "x  UVS" and "S  UVS"
  shows "dim (insert x S) = (if x  span S then dim S else dim S + 1)"
    is finite_dimensional_vector_space.dim_insert.
    
tts_lemma dim_singleton:
  assumes "x  UVS"
  shows "dim {x} = (if x = 0 then 0 else 1)"
    is finite_dimensional_vector_space.dim_singleton.

tts_lemma choose_subspace_of_subspace["consumes" - 1, "case_names" "1"]:
  assumes "S  UVS"
    and "n  dim S"
    and "T. T  UVS; subspace T; T  span S; dim T = n  thesis"
  shows thesis
    is finite_dimensional_vector_space.choose_subspace_of_subspace.

tts_lemma basis_subspace_exists["consumes" - 1, "case_names" "1"]:
  assumes "S  UVS"
    and "subspace S"
    and "B. 
      
        B  UVS; 
        finite B; 
        B  S; 
        ¬ dependent B; 
        span B = S; 
        card B = dim S
        thesis"
  shows thesis
    is finite_dimensional_vector_space.basis_subspace_exists.

tts_lemma dim_mono:
  assumes "V  UVS" and "W  UVS" and "V  span W"
  shows "dim V  dim W"
    is finite_dimensional_vector_space.dim_mono.

tts_lemma dim_subset:
  assumes "T  UVS" and "S  T"
  shows "dim S  dim T"
    is finite_dimensional_vector_space.dim_subset.

tts_lemma dim_eq_0:
  assumes "S  UVS"
  shows "(dim S = 0) = (S  {0})"
    is finite_dimensional_vector_space.dim_eq_0.

tts_lemma dim_UNIV: "dim UVS = card basis"
    is finite_dimensional_vector_space.dim_UNIV.

tts_lemma independent_card_le_dim:
  assumes "V  UVS" and "B  V" and "¬ dependent B"
  shows "card B  dim V"
    is finite_dimensional_vector_space.independent_card_le_dim.

tts_lemma card_ge_dim_independent:
  assumes "V  UVS" and "B  V" and "¬ dependent B" and "dim V  card B"
  shows "V  span B"
    is finite_dimensional_vector_space.card_ge_dim_independent.

tts_lemma card_le_dim_spanning:
  assumes "V  UVS"
    and "B  V"
    and "V  span B"
    and "finite B"
    and "card B  dim V"
  shows "¬ dependent B"
    is finite_dimensional_vector_space.card_le_dim_spanning.

tts_lemma card_eq_dim:
  assumes "V  UVS" and "B  V" and "card B = dim V" and "finite B"
  shows "(¬ dependent B) = (V  span B)"
    is finite_dimensional_vector_space.card_eq_dim.

tts_lemma subspace_dim_equal:
  assumes "T  UVS"
    and "subspace S"
    and "subspace T"
    and "S  T"
    and "dim T  dim S"
  shows "S = T"
    is finite_dimensional_vector_space.subspace_dim_equal.

tts_lemma dim_eq_span:
  assumes "T  UVS" and "S  T" and "dim T  dim S"
  shows "span S = span T"
    is finite_dimensional_vector_space.dim_eq_span.

tts_lemma dim_psubset:
  assumes "S  UVS" and "T  UVS" and "span S  span T"
  shows "dim S < dim T"
    is finite_dimensional_vector_space.dim_psubset.

tts_lemma indep_card_eq_dim_span:
  assumes "B  UVS" and "¬ dependent B"
  shows "finite B  card B = dim (span B)"
    is finite_dimensional_vector_space.indep_card_eq_dim_span.

tts_lemma independent_bound_general:
  assumes "S  UVS" and "¬ dependent S"
  shows "finite S  card S  dim S"
    is finite_dimensional_vector_space.independent_bound_general.

tts_lemma independent_explicit:
  assumes "B  UVS"
  shows "(¬ dependent B) = 
    (finite B  (x. (vB. x v *s v) = 0  (aB. x a = 0)))"
    is finite_dimensional_vector_space.independent_explicit.

tts_lemma dim_sums_Int:
  assumes "S  UVS" and "T  UVS" and "subspace S" and "subspace T"
  shows 
    "dim {x  UVS. yUVS. zUVS. x = y + z  y  S  z  T} + dim (S  T) = 
      dim S + dim T"
    is finite_dimensional_vector_space.dim_sums_Int.

tts_lemma dependent_biggerset_general:
  assumes "S  UVS" and "finite S  dim S < card S"
  shows "dependent S"
    is finite_dimensional_vector_space.dependent_biggerset_general.

tts_lemma subset_le_dim:
  assumes "S  UVS" and "T  UVS" and "S  span T"
  shows "dim S  dim T"
    is finite_dimensional_vector_space.subset_le_dim.

tts_lemma linear_inj_imp_surj:
  assumes "xUVS. f x  UVS"
    and "linear_on UVS UVS (*s) (*s) f"
    and "inj_on f UVS"
  shows "f ` UVS = UVS"
    is finite_dimensional_vector_space.linear_inj_imp_surj.

tts_lemma linear_surj_imp_inj:
  assumes "xUVS. f x  UVS"
    and "linear_on UVS UVS (*s) (*s) f"
    and "f ` UVS = UVS"
  shows "inj_on f UVS"
    is finite_dimensional_vector_space.linear_surj_imp_inj.

tts_lemma linear_inverse_left:
  assumes "xUVS. f x  UVS"
    and "xUVS. f' x  UVS"
    and "linear_on UVS UVS (*s) (*s) f"
    and "linear_on UVS UVS (*s) (*s) f'"
  shows "(xUVS. (f  f') x = id x) = (xUVS. (f'  f) x = id x)"
    is finite_dimensional_vector_space.linear_inverse_left[unfolded fun_eq_iff].

tts_lemma left_inverse_linear:
  assumes "xUVS. f x  UVS"
    and "xUVS. g x  UVS"
    and "linear_on UVS UVS (*s) (*s) f"
    and "xUVS. (g  f) x = id x"
  shows "linear_on UVS UVS (*s) (*s) g"
    is finite_dimensional_vector_space.left_inverse_linear[unfolded fun_eq_iff].

tts_lemma right_inverse_linear:
  assumes "xUVS. f x  UVS"
    and "xUVS. g x  UVS"
    and "linear_on UVS UVS (*s) (*s) f"
    and "xUVS. (f  g) x = id x"
  shows "linear_on UVS UVS (*s) (*s) g"
    is finite_dimensional_vector_space.right_inverse_linear[unfolded fun_eq_iff].

end

end

context vector_space_pair_on 
begin

tts_context
  tts: (?'b to UM_1::'b set) and (?'c to UM_2::'c set) 
  sbterms: ((+)::?'b::ab_group_add?'b?'b to (+)::'b'b'b)
    and (?s1.0::?'a::field ?'b::ab_group_add?'b to (*s1)::'a'b'b)
    and (0::?'b::ab_group_add to 0::'b) 
    and ((+)::?'c::ab_group_add?'c?'c to (+)::'c'c'c)
    and (?s2.0::?'a::field ?'c::ab_group_add?'c to (*s2)::'a'c'c)
    and (0::?'c::ab_group_add to 0::'c)
  rewriting ctr_simps
  substituting VS1.ab_group_add_ow_axioms
    and VS1.vector_space_ow_axioms
    and VS2.ab_group_add_ow_axioms
    and VS2.vector_space_ow_axioms
    and implicitVS.vector_space_pair_ow_axioms
    and VS1.implicitM.module_ow_axioms
    and VS2.implicitM.module_ow_axioms
  eliminating ?a  UM_1 and ?B  UM_1 and ?a  UM_2 and ?B  UM_2 
    through auto
  applying  
    [
      OF 
        VS1.implicitM.carrier_ne VS2.implicitM.carrier_ne 
        VS1.implicitM.minus_closed' VS1.implicitM.uminus_closed' 
        VS2.implicitVS.minus_closed' VS2.implicitVS.uminus_closed',
      unfolded tts_implicit
    ]
begin

tts_lemma linear_add:
  assumes "xUM_1. f x  UM_2"
    and "b1  UM_1"
    and "b2  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
  shows "f (b1 + b2) = f b1 + f b2"
    is vector_space_pair.linear_add.

tts_lemma linear_scale:
  assumes "xUM_1. f x  UM_2"
    and "b  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
  shows "f (r *s1 b) = r *s2 f b"
    is vector_space_pair.linear_scale.
    
tts_lemma linear_neg:
  assumes "xUM_1. f x  UM_2"
    and "x  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
  shows "f (- x) = - f x"
    is vector_space_pair.linear_neg.
    
tts_lemma linear_diff:
  assumes "xUM_1. f x  UM_2"
    and "x  UM_1"
    and "y  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
  shows "f (x - y) = f x - f y"
    is vector_space_pair.linear_diff.
    
tts_lemma linear_sum:
  assumes "xUM_1. f x  UM_2"
    and "range g  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
  shows "f (sum g S) = (aS. f (g a))"
is vector_space_pair.linear_sum.

tts_lemma linear_inj_on_iff_eq_0:
  assumes "xUM_1. f x  UM_2"
    and "s  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "VS1.subspace s"
  shows "inj_on f s = (xs. f x = 0  x = 0)"
    is vector_space_pair.linear_inj_on_iff_eq_0.

tts_lemma linear_inj_iff_eq_0:
  assumes "xUM_1. f x  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
  shows "inj_on f UM_1 = (xUM_1. f x = 0  x = 0)"
    is vector_space_pair.linear_inj_iff_eq_0.

tts_lemma linear_subspace_image:
  assumes "xUM_1. f x  UM_2"
    and "S  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "VS1.subspace S"
  shows "VS2.subspace (f ` S)"
    is vector_space_pair.linear_subspace_image.

tts_lemma linear_subspace_kernel:
  assumes "xUM_1. f x  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
  shows "VS1.subspace {x  UM_1. f x = 0}"
    is vector_space_pair.linear_subspace_kernel.

tts_lemma linear_span_image:
  assumes "xUM_1. f x  UM_2"
    and "S  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
  shows "VS2.span (f ` S) = f ` VS1.span S"
    is vector_space_pair.linear_span_image.

tts_lemma linear_dependent_inj_imageD:
  assumes "xUM_1. f x  UM_2"
    and "s  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "VS2.dependent (f ` s)"
    and "inj_on f (VS1.span s)"
  shows "VS1.dependent s"
    is vector_space_pair.linear_dependent_inj_imageD.

tts_lemma linear_eq_0_on_span:
  assumes "xUM_1. f x  UM_2"
    and "b  UM_1"
    and "x  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "x. x  UM_1; x  b  f x = 0"
    and "x  VS1.span b"
  shows "f x = 0"
    is vector_space_pair.linear_eq_0_on_span.

tts_lemma linear_independent_injective_image:
  assumes "xUM_1. f x  UM_2"
    and "s  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "¬ VS1.dependent s"
    and "inj_on f (VS1.span s)"
  shows "¬ VS2.dependent (f ` s)"
    is vector_space_pair.linear_independent_injective_image.

tts_lemma linear_inj_on_span_independent_image:
  assumes "xUM_1. f x  UM_2"
    and "B  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "¬ VS2.dependent (f ` B)"
    and "inj_on f B"
  shows "inj_on f (VS1.span B)"
    is vector_space_pair.linear_inj_on_span_independent_image.

tts_lemma linear_inj_on_span_iff_independent_image:
  assumes "xUM_1. f x  UM_2"
    and "B  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "¬ VS2.dependent (f ` B)"
  shows "inj_on f (VS1.span B) = inj_on f B"
    is vector_space_pair.linear_inj_on_span_iff_independent_image.

tts_lemma linear_subspace_linear_preimage:
  assumes "xUM_1. f x  UM_2"
    and "S  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "VS2.subspace S"
  shows "VS1.subspace {x  UM_1. f x  S}"
    is vector_space_pair.linear_subspace_linear_preimage.

tts_lemma linear_spans_image:
  assumes "xUM_1. f x  UM_2"
    and "V  UM_1"
    and "B  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "V  VS1.span B"
  shows "f ` V  VS2.span (f ` B)"
    is vector_space_pair.linear_spans_image.

tts_lemma linear_spanning_surjective_image:
  assumes "xUM_1. f x  UM_2"
    and "S  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "UM_1  VS1.span S"
    and "f ` UM_1 = UM_2"
  shows "UM_2  VS2.span (f ` S)"
    is vector_space_pair.linear_spanning_surjective_image.

tts_lemma linear_eq_on_span:
  assumes "xUM_1. f x  UM_2"
    and "xUM_1. g x  UM_2"
    and "B  UM_1"
    and "x  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "linear_on UM_1 UM_2 (*s1) (*s2) g"
    and "x. x  UM_1; x  B  f x = g x"
    and "x  VS1.span B"
  shows "f x = g x"
    is vector_space_pair.linear_eq_on_span.

tts_lemma linear_compose_scale_right:
  assumes "xUM_1. f x  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
  shows "linear_on UM_1 UM_2 (*s1) (*s2) (λx. c *s2 f x)"
    is vector_space_pair.linear_compose_scale_right.

tts_lemma linear_compose_add:
  assumes "xUM_1. f x  UM_2"
    and "xUM_1. g x  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "linear_on UM_1 UM_2 (*s1) (*s2) g"
  shows "linear_on UM_1 UM_2 (*s1) (*s2) (λx. f x + g x)"
    is vector_space_pair.linear_compose_add.

tts_lemma linear_zero:
  shows "linear_on UM_1 UM_2 (*s1) (*s2) (λx. 0)"
    is vector_space_pair.linear_zero.

tts_lemma linear_compose_sub:
  assumes "xUM_1. f x  UM_2"
    and "xUM_1. g x  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "linear_on UM_1 UM_2 (*s1) (*s2) g"
  shows "linear_on UM_1 UM_2 (*s1) (*s2) (λx. f x - g x)"
    is vector_space_pair.linear_compose_sub.

tts_lemma linear_compose_neg:
  assumes "xUM_1. f x  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
  shows "linear_on UM_1 UM_2 (*s1) (*s2) (λx. - f x)"
    is vector_space_pair.linear_compose_neg.

tts_lemma linear_compose_scale:
  assumes "c  UM_2"
    and "linear_on UM_1 UNIV (*s1) (*) f"
  shows "linear_on UM_1 UM_2 (*s1) (*s2) (λx. f x *s2 c)"
    is vector_space_pair.linear_compose_scale.

tts_lemma linear_indep_image_lemma:
  assumes "xUM_1. f x  UM_2"
    and "B  UM_1"
    and "x  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "finite B"
    and "¬ VS2.dependent (f ` B)"
    and "inj_on f B"
    and "x  VS1.span B"
    and "f x = 0"
  shows "x = 0"
    is vector_space_pair.linear_indep_image_lemma.

tts_lemma linear_eq_on:
  assumes "xUM_1. f x  UM_2"
    and "xUM_1. g x  UM_2"
    and "x  UM_1"
    and "B  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "linear_on UM_1 UM_2 (*s1) (*s2) g"
    and "x  VS1.span B"
    and "b. b  UM_1; b  B  f b = g b"
  shows "f x = g x"
    is vector_space_pair.linear_eq_on.

tts_lemma linear_compose_sum:
  assumes "x. yUM_1. f x y  UM_2"
    and "xS. linear_on UM_1 UM_2 (*s1) (*s2) (f x)"
  shows "linear_on UM_1 UM_2 (*s1) (*s2) (λx. aS. f a x)"
    is vector_space_pair.linear_compose_sum.

tts_lemma linear_independent_extend_subspace:
  assumes "B  UM_1"
    and "xUM_1. f x  UM_2"
    and "¬ VS1.dependent B"
  shows 
    "x.
      (aUM_1. x a  UM_2)  
      linear_on UM_1 UM_2 (*s1) (*s2) x  
      (aB. x a = f a)  
      x ` UM_1 = VS2.span (f ` B)"
    given vector_space_pair.linear_independent_extend_subspace by auto

tts_lemma linear_independent_extend:
  assumes "B  UM_1"
    and "xUM_1. f x  UM_2"
    and "¬ VS1.dependent B"
  shows 
    "x. 
      (aUM_1. x a  UM_2)  
      (aB. x a = f a)  
      linear_on UM_1 UM_2 (*s1) (*s2) x"
    given vector_space_pair.linear_independent_extend by auto

tts_lemma linear_exists_left_inverse_on:
  assumes "xUM_1. f x  UM_2"
    and "V  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "VS1.subspace V"
    and "inj_on f V"
  shows 
    "x. 
      (aUM_2. x a  UM_1)  
      x ` UM_2  V  
      (aV. x (f a) = a)  
      linear_on UM_2 UM_1 (*s2) (*s1) x"
    given vector_space_pair.linear_exists_left_inverse_on by auto

tts_lemma linear_exists_right_inverse_on:
  assumes "xUM_1. f x  UM_2"
    and "V  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "VS1.subspace V"
  shows 
    "x. 
      (aUM_2. x a  UM_1)  
      x ` UM_2  V  
      (af ` V. f (x a) = a)  
      linear_on UM_2 UM_1 (*s2) (*s1) x"
    given vector_space_pair.linear_exists_right_inverse_on by auto

tts_lemma linear_inj_on_left_inverse:
  assumes "xUM_1. f x  UM_2"
    and "S  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "inj_on f (VS1.span S)"
  shows 
    "x. 
      (aUM_2. x a  UM_1)  
      x ` UM_2  VS1.span S  
      (aVS1.span S. x (f a) = a)  
      linear_on UM_2 UM_1 (*s2) (*s1) x"
    given vector_space_pair.linear_inj_on_left_inverse by auto

tts_lemma linear_surj_right_inverse:
  assumes "xUM_1. f x  UM_2"
    and "T  UM_2"
    and "S  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "VS2.span T  f ` VS1.span S"
  shows 
    "x. 
      (aUM_2. x a  UM_1)  
      x ` UM_2  VS1.span S  
      (aVS2.span T. f (x a) = a)  
      linear_on UM_2 UM_1 (*s2) (*s1) x"
    given vector_space_pair.linear_surj_right_inverse by auto

tts_lemma finite_basis_to_basis_subspace_isomorphism:
  assumes "S  UM_1"
    and "T  UM_2"
    and "VS1.subspace S"
    and "VS2.subspace T"
    and "VS1.dim S = VS2.dim T"
    and "finite B"
    and "B  S"
    and "¬ VS1.dependent B"
    and "S  VS1.span B"
    and "card B = VS1.dim S"
    and "finite C"
    and "C  T"
    and "¬ VS2.dependent C"
    and "T  VS2.span C"
    and "card C = VS2.dim T"
  shows 
    "x. 
      (aUM_1. x a  UM_2)  
      linear_on UM_1 UM_2 (*s1) (*s2) x  
      x ` B = C  
      inj_on x S  x ` S = T"
    given vector_space_pair.finite_basis_to_basis_subspace_isomorphism by auto

tts_lemma linear_subspace_vimage:
  assumes "xUM_1. f x  UM_2"
    and "S  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "VS2.subspace S"
  shows "VS1.subspace (f -` S  UM_1)"
    is vector_space_pair.linear_subspace_vimage.

tts_lemma linear_injective_left_inverse:
  assumes "xUM_1. f x  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "inj_on f UM_1"
  shows 
    "x. 
      (aUM_2. x a  UM_1)  
      (aUM_1. (x  f) a = id a)  
      linear_on UM_2 UM_1 (*s2) (*s1) x"
    given vector_space_pair.linear_injective_left_inverse[unfolded fun_eq_iff]
  by auto

tts_lemma linear_surjective_right_inverse:
  assumes "xUM_1. f x  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "f ` UM_1 = UM_2"
  shows 
    "x. 
      (aUM_2. x a  UM_1)  
      (aUM_2. (f  x) a = id a)  
      linear_on UM_2 UM_1 (*s2) (*s1) x"
    given vector_space_pair.linear_surjective_right_inverse[unfolded fun_eq_iff]
  by auto

end

end

context finite_dimensional_vector_space_pair_1_on 
begin

tts_context
  tts: (?'b to UM_1::'b set) and (?'c to UM_2::'c set) 
  sbterms: ((+)::?'b::ab_group_add?'b?'b to (+)::'b'b'b)
    and (?s1.0::?'a::field ?'b::ab_group_add?'b to (*s1)::'a'b'b)
    and (0::?'b::ab_group_add to 0::'b) 
    and ((+)::?'c::ab_group_add?'c?'c to (+)::'c'c'c)
    and (?s2.0::?'a::field ?'c::ab_group_add?'c to (*s2)::'a'c'c)
    and (0::?'c::ab_group_add to 0::'c)
  rewriting ctr_simps
  substituting VS1.ab_group_add_ow_axioms
    and VS1.vector_space_ow_axioms
    and VS2.ab_group_add_ow_axioms
    and VS2.vector_space_ow_axioms
    and implicitVS.vector_space_pair_ow_axioms
    and VS1.implicitM.module_ow_axioms
    and VS2.implicitM.module_ow_axioms 
    and implicitVS.finite_dimensional_vector_space_pair_1_ow_axioms
  applying  
    [
      OF 
        VS1.implicitM.carrier_ne VS2.implicitM.carrier_ne 
        VS1.implicitVS.minus_closed' VS1.implicitVS.uminus_closed' 
        VS2.implicitVS.minus_closed' VS2.implicitVS.uminus_closed'
        VS1.basis_subset,
      unfolded tts_implicit
    ]
begin

tts_lemma lt_dim_image_eq:
  assumes "xUM_1. f x  UM_2"
    and "S  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "inj_on f (VS1.span S)"
  shows "VS2.dim (f ` S) = VS1.dim S"
    is finite_dimensional_vector_space_pair_1.dim_image_eq.

tts_lemma lt_dim_image_le:
  assumes "xUM_1. f x  UM_2"
    and "S  UM_1"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
  shows "VS2.dim (f ` S)  VS1.dim S"
    is finite_dimensional_vector_space_pair_1.dim_image_le.

end

end

context finite_dimensional_vector_space_pair_on 
begin

tts_context
  tts: (?'b to UM_1::'b set) and (?'c to UM_2::'c set) 
  sbterms: ((+)::?'b::ab_group_add?'b?'b to (+)::'b'b'b)
    and (?s1.0::?'a::field ?'b::ab_group_add?'b to (*s1)::'a'b'b)
    and (0::?'b::ab_group_add to 0::'b) 
    and ((+)::?'c::ab_group_add?'c?'c to (+)::'c'c'c)
    and (?s2.0::?'a::field ?'c::ab_group_add?'c to (*s2)::'a'c'c)
    and (0::?'c::ab_group_add to 0::'c)
  rewriting ctr_simps
  substituting VS1.ab_group_add_ow_axioms
    and VS1.vector_space_ow_axioms
    and VS2.ab_group_add_ow_axioms
    and VS2.vector_space_ow_axioms
    and implicitVS.vector_space_pair_ow_axioms
    and VS1.implicitM.module_ow_axioms
    and VS2.implicitM.module_ow_axioms 
    and implicitVS.finite_dimensional_vector_space_pair_ow_axioms
  applying  
    [
      OF 
        VS1.implicitM.carrier_ne VS2.implicitM.carrier_ne 
        VS1.implicitVS.minus_closed' VS1.implicitVS.uminus_closed' 
        VS2.implicitVS.minus_closed' VS2.implicitVS.uminus_closed'
        VS1.basis_subset VS2.basis_subset,
      unfolded tts_implicit
    ]
begin

tts_lemma linear_surjective_imp_injective:
  assumes "xUM_1. f x  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "f ` UM_1 = UM_2"
    and "VS2.dim UM_2 = VS1.dim UM_1"
  shows "inj_on f UM_1"
    is finite_dimensional_vector_space_pair.linear_surjective_imp_injective.

tts_lemma linear_injective_imp_surjective:
  assumes "xUM_1. f x  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "inj_on f UM_1"
    and "VS2.dim UM_2 = VS1.dim UM_1"
  shows "f ` UM_1 = UM_2"
    is finite_dimensional_vector_space_pair.linear_injective_imp_surjective.

tts_lemma linear_injective_isomorphism:
  assumes "xUM_1. f x  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "inj_on f UM_1"
    and "VS2.dim UM_2 = VS1.dim UM_1"
  shows 
    "x. 
      (aUM_2. x a  UM_1)  
      linear_on UM_2 UM_1 (*s2) (*s1) x  
      (aUM_1. x (f a) = a)  
      (aUM_2. f (x a) = a)"
    given finite_dimensional_vector_space_pair.linear_injective_isomorphism
  by auto

tts_lemma linear_surjective_isomorphism:
  assumes "xUM_1. f x  UM_2"
    and "linear_on UM_1 UM_2 (*s1) (*s2) f"
    and "f ` UM_1 = UM_2"
    and "VS2.dim UM_2 = VS1.dim UM_1"
  shows 
    "x.
      (aUM_2. x a  UM_1)  
      linear_on UM_2 UM_1 (*s2) (*s1) x  
      (aUM_1. x (f a) = a)  
      (aUM_2. f (x a) = a)"
    given finite_dimensional_vector_space_pair.linear_surjective_isomorphism
  by auto

tts_lemma basis_to_basis_subspace_isomorphism:
  assumes "S  UM_1"
    and "T  UM_2"
    and "B  UM_1"
    and "C  UM_2"
    and "VS1.subspace S"
    and "VS2.subspace T"
    and "VS1.dim S = VS2.dim T"
    and "B  S"
    and "¬ VS1.dependent B"
    and "S  VS1.span B"
    and "card B = VS1.dim S"
    and "C  T"
    and "¬ VS2.dependent C"
    and "T  VS2.span C"
    and "card C = VS2.dim T"
  shows
    "x.
      (aUM_1. x a  UM_2) 
      linear_on UM_1 UM_2 (*s1) (*s2) x 
      x ` B = C 
      inj_on x S 
      x ` S = T"
  given finite_dimensional_vector_space_pair.basis_to_basis_subspace_isomorphism
  by auto

tts_lemma subspace_isomorphism:
  assumes "S  UM_1"
    and "T  UM_2"
    and "VS1.subspace S"
    and "VS2.subspace T"
    and "VS1.dim S = VS2.dim T"
  shows "x.
    (aUM_1. x a  UM_2) 
    (inj_on x S  x ` S = T) 
    linear_on UM_1 UM_2 (*s1) (*s2) x"
    given finite_dimensional_vector_space_pair.subspace_isomorphism by auto

end

end

text‹\newpage›

end