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

Quelle  Matrix_Farkas.thy

  Sprache: Isabelle
 

(* Author: R. Thiemann *)

subsection Farkas Lemma for Matrices

text In this part we convert the simplex-structures like linear polynomials, etc., into
 equivalent formulations using matrices and vectors. As a result we present Farkas' Lemma
 via matrices and vectors.


theory Matrix_Farkas
  imports Farkas
  Jordan_Normal_Form.Matrix
begin

lift_definition poly_of_vec :: "rat vec ==> linear_poly" is
  "λ v x. if (x < dim_vec v) then v $ x else 0" 
  by auto

definition val_of_vec :: "rat vec ==> rat valuation" where
  "val_of_vec v x = v $ x" 

lemma valuate_poly_of_vec: assumes "w carrier_vec n" 
  and "v carrier_vec n"  
shows "valuate (poly_of_vec v) (val_of_vec w) = v w"  
  using assms by (transfer, auto simp: val_of_vec_def scalar_prod_def intro: sum.mono_neutral_left)

definition constraints_of_mat_vec :: "rat mat ==> rat vec ==> rat le_constraint set" where
  "constraints_of_mat_vec A b = (λ i . Leqc (poly_of_vec (row A i)) (b $ i)) ` {0 ..< dim_row A}" 

lemma constraints_of_mat_vec_solution_main: assumes A: "A carrier_mat nr nc" 
  and x: "x carrier_vec nc"
  and b: "b carrier_vec nr" 
  and sol: "A *v x b" 
  and c: "c constraints_of_mat_vec A b" 
shows "val_of_vec x le c" 
proof -
  from c[unfolded constraints_of_mat_vec_def] A obtain i where
    i: "i < nr" and c: "c = Leqc (poly_of_vec (row A i)) (b $ i)" by auto
  from i A have ri: "row A i carrier_vec nc" by auto
  from sol i A x b have sol: "(A *v x) $ i b $ i" unfolding less_eq_vec_def by auto
  thus "val_of_vec x le c" unfolding c satisfiable_le_constraint.simps rel_of.simps
      valuate_poly_of_vec[OF x ri] using A x i by auto
qed

lemma vars_poly_of_vec: "vars (poly_of_vec v) { 0 ..< dim_vec v}" 
  by (transfer', auto)

lemma finite_constraints_of_mat_vec: "finite (constraints_of_mat_vec A b)" 
  unfolding constraints_of_mat_vec_def by auto

lemma lec_rec_constraints_of_mat_vec: "lec_rel ` constraints_of_mat_vec A b {Leq_Rel}" 
  unfolding constraints_of_mat_vec_def by auto

lemma constraints_of_mat_vec_solution_1: 
  assumes A: "A carrier_mat nr nc" 
    and b: "b carrier_vec nr" 
    and sol: " x carrier_vec nc. A *v x b" 
  shows " v. c constraints_of_mat_vec A b. v le c" 
  using constraints_of_mat_vec_solution_main[OF A _ b _] sol by blast

lemma constraints_of_mat_vec_solution_2: 
  assumes A: "A carrier_mat nr nc" 
    and b: "b carrier_vec nr" 
    and sol: " v. c constraints_of_mat_vec A b. v le c" 
  shows " x carrier_vec nc. A *v x b" 
proof -
  from sol obtain v where sol: "v le c" if "c constraints_of_mat_vec A b" for c by auto
  define x where "x = vec nc (λ i. v i)" 
  show ?thesis
  proof (intro bexI[of _ x])
    show x: "x carrier_vec nc" unfolding x_def by auto
    have "row A i x b $ i" if "i < nr" for i
    proof -
      from that have "Leqc (poly_of_vec (row A i)) (b $ i) constraints_of_mat_vec A b" 
        unfolding constraints_of_mat_vec_def using A by auto
      from sol[OF this, simplified] have "valuate (poly_of_vec (row A i)) v b $ i" by simp
      also have "valuate (poly_of_vec (row A i)) v = valuate (poly_of_vec (row A i)) (val_of_vec x)" 
        by (rule valuate_depend, insert A that, 
          auto simp: x_def val_of_vec_def dest!: set_mp[OF vars_poly_of_vec])
      also have " = row A i x" 
        by (subst valuate_poly_of_vec[OF x], insert that A x, auto)
      finally show ?thesis .
    qed
    thus "A *v x b" unfolding less_eq_vec_def using x A b by auto
  qed
qed

lemma constraints_of_mat_vec_solution: 
  assumes A: "A carrier_mat nr nc" 
    and b: "b carrier_vec nr" 
  shows "( x carrier_vec nc. A *v x b) =
    ( v. c constraints_of_mat_vec A b. v le c)" 
  using constraints_of_mat_vec_solution_1[OF assms] constraints_of_mat_vec_solution_2[OF assms]
  by blast 

lemma farkas_lemma_matrix: fixes A :: "rat mat" 
  assumes A: "A carrier_mat nr nc" 
  and b: "b carrier_vec nr" 
shows "( x carrier_vec nc. A *v x b)
  ( y. y 0v nr mat_of_row y * A = 0m 1 nc y b 0)" 
proof -
  define cs where "cs = constraints_of_mat_vec A b" 
  have fin: "finite {0 ..< nr}" by auto
  have dim: "dim_row A = nr" using A by simp
  have sum_id: "( i = 0..<nr. f i) = sum_list (map f [0..<nr])" for f 
    by (subst sum_list_distinct_conv_sum_set, auto)
  have "( x carrier_vec nc. A *v x b) =
   (¬ ( v. c cs. v le c))" 
    unfolding constraints_of_mat_vec_solution[OF assms] cs_def by simp
  also have " = (¬ (v. i{0..<nr}. v le Le_Constraint Leq_Rel (poly_of_vec (row A i)) (b $ i)))" 
    unfolding cs_def constraints_of_mat_vec_def dim by auto
  also have " = (C.
        (i{0..<nr}. 0 C i)
         (i = 0..<nr. (C i *R poly_of_vec (row A i))) = 0
         (i = 0..<nr. (C i * b $ i)) < 0)" 
    unfolding Farkas'_Lemma_indexed[OF 
        lec_rec_constraints_of_mat_vec[unfolded constraints_of_mat_vec_def], of A b,
        unfolded dim, OF fin] sum_id sum_list_lec le_constraint.simps 
        sum_list_Leq_Rel map_map o_def unfolding sum_id[symmetric] by simp
  also have " = ( C. (i {0..<nr}. 0 C i)
         (i = 0..<nr. (C i *R poly_of_vec (row A i))) = 0
         (i = 0..<nr. (C i * b $ i)) 0)" 
    using not_less by blast
  also have " = ( y. y 0v nr mat_of_row y * A = 0m 1 nc y b 0)"
  proof ((standard; intro allI impI), goal_cases)
    case *: (1 y)
    define C where "C = (λ i. y $ i)" 
    note main = *(1)[rule_format, of C]
    from *(2have y: "y carrier_vec nr" and nonneg: "i. i {0..<nr} ==> 0 C i" 
      unfolding less_eq_vec_def C_def by auto
    have sum_0: "(i = 0..<nr. C i *R poly_of_vec (row A i)) = 0" unfolding C_def
      unfolding zero_coeff_zero coeff_sum 
    proof
      fix v
      have "(i = 0..<nr. coeff (y $ i *R poly_of_vec (row A i)) v) =
            (i < nr. y $ i * coeff (poly_of_vec (row A i)) v)" by (rule sum.cong, auto)
      also have " = 0" 
      proof (cases "v < nc")
        case False
        have "(i < nr. y $ i * coeff (poly_of_vec (row A i)) v) =
              (i < nr. y $ i * 0)" 
          by (rule sum.cong[OF refl], rule arg_cong[of _ _ "λ x. _ * x"], insert A False, transfer, auto)
        also have " = 0" by simp
        finally show ?thesis by simp
      next
        case True
        have "(i<nr. y $ i * coeff (poly_of_vec (row A i)) v) =
              (i<nr. y $ i * row A i $ v)" 
          by (rule sum.cong[OF refl], rule arg_cong[of _ _ "λ x. _ * x"], insert A True, transfer, auto)
        also have " = (mat_of_row y * A) $$ (0,v)" 
          unfolding times_mat_def scalar_prod_def
          using A y True by (auto intro: sum.cong)
        also have " = 0" unfolding *(3using True by simp
        finally show ?thesis .
      qed
      finally show "(i = 0..<nr. coeff (y $ i *R poly_of_vec (row A i)) v) = 0" .
    qed
    from main[OF nonneg sum_0] have le: "0 (i = 0..<nr. C i * b $ i)" .
    thus ?case using y b unfolding scalar_prod_def C_def by auto
  next
    case *: (2 C)
    define y where "y = vec nr C" 
    have y: "y carrier_vec nr" unfolding y_def by auto
    note main = *(1)[rule_format, of y]
    from *(2have y0: "y 0v nr" unfolding less_eq_vec_def y_def by auto
    have prod0: "mat_of_row y * A = 0m 1 nc" 
    proof -
      {
        fix j
        assume j: "j < nc"
        from arg_cong[OF *(3), of "λ x. coeff x j", unfolded coeff_sum]
        have "0 = (i = 0..<nr. C i * coeff (poly_of_vec (row A i)) j)" by simp
        also have " = (i = 0..<nr. C i * row A i $ j)" 
          by (rule sum.cong[OF refl], rule arg_cong[of _ _ "λ x. _ * x"], insert A j, transfer, auto)
        also have " = y col A j" unfolding scalar_prod_def y_def using A j 
          by (intro sum.cong, auto)
        finally have "y col A j = 0" by simp
      }
      thus ?thesis by (intro eq_matI, insert A y, auto)
    qed
    from main[OF y0 prod0] have "0 y b" .
    thus ?case unfolding scalar_prod_def y_def using b by auto
  qed
  finally show ?thesis .
qed

lemma farkas_lemma_matrix': fixes A :: "rat mat" 
  assumes A: "A carrier_mat nr nc" 
  and b: "b carrier_vec nr" 
shows "( x 0v nc. A *v x = b)
  ( y carrier_vec nr. mat_of_row y * A 0m 1 nc y b 0)" 
proof -
  define B where "B = (- 1m nc) @r (A @r -A)"   
  define b' where "b' = 0v nc @v (b @v -b)" 
  define n where "n = nc + (nr + nr)" 
  have id0: "0v (nc + (nr + nr)) = 0v nc @v (0v nr @v 0v nr)" by (intro eq_vecI, auto)
  have B: "B carrier_mat n nc" unfolding B_def n_def using A by auto
  have b': "b' carrier_vec n" unfolding b'_def n_def using b by auto
  have "( x 0v nc. A *v x = b) = ( x. x carrier_vec nc x 0v nc A *v x = b)" 
    by (rule arg_cong[of _ _ Ex], intro ext, insert A b, auto simp: less_eq_vec_def)
  also have " = ( x carrier_vec nc. x 0v nc A *v x = b)" by blast
  also have " = ( x carrier_vec nc. 1m nc *v x 0v nc A *v x b A *v x b)" 
    by (rule bex_cong[OF refl], insert A b, auto)
  also have " = ( x carrier_vec nc. (- 1m nc) *v x 0v nc A *v x b (- A) *v x -b)" 
    by (rule bex_cong[OF refl], insert A b, auto simp: less_eq_vec_def)
  also have " = ( x carrier_vec nc. B *v x b')"
    by (rule bex_cong[OF refl], insert A b, unfold B_def b'_def
      subst append_rows_le[of _ ], (auto)[4], intro conj_cong[OF refl], subst append_rows_le, auto)
  also have " = (y0v n. mat_of_row y * B = 0m 1 nc y b' 0)"   
    by (rule farkas_lemma_matrix[OF B b'])
  also have " = ( y. y carrier_vec n y0v n mat_of_row y * B = 0m 1 nc y b' 0)"
    by (intro arg_cong[of _ _ All], intro ext, auto simp: less_eq_vec_def)
  also have " = ( y carrier_vec n. y0v n mat_of_row y * B = 0m 1 nc y b' 0)"
    by blast
  also have " = (y1 carrier_vec nc. y2 carrier_vec nr. y3 carrier_vec nr.
              0v nc @v (0v nr @v 0v nr) y1 @v y2 @v y3
              mat_of_row (y1 @v y2 @v y3) * ((- 1m nc) @r (A @r -A)) = 0m 1 nc
               0 (y1 @v y2 @v y3) (0v nc @v (b @v -b)))" 
    unfolding n_def all_vec_append id0 b'_def B_def by auto
  also have " = (y1 carrier_vec nc. y2 carrier_vec nr. y3 carrier_vec nr.
              0v nc y1 0v nr y2 0v nr y3
              (- mat_of_row y1) +
              (mat_of_row y2 * A - (mat_of_row y3 * A)) = 0m 1 nc
               y2 b - y3 b 0)"
    by (intro ball_cong[OF refl], subst append_vec_le, (auto)[2], subst append_vec_le, (auto)[2], insert A b,
      subst scalar_prod_append, (auto)[4], subst scalar_prod_append, (auto)[4], 
      subst mat_of_row_mult_append_rows, (auto)[4],
      subst mat_of_row_mult_append_rows, (auto)[4],
      subst add_uminus_minus_mat[symmetric], auto)
  also have " = (y1 carrier_vec nc. y2 carrier_vec nr. y3 carrier_vec nr.
              0v nc y1 0v nr y2 0v nr y3
              mat_of_row y1 = mat_of_row y2 * A - mat_of_row y3 * A
               y2 b - y3 b 0)"
  proof ((intro ball_cong[OF refl] arg_cong2[of _ _ _ _ "()"] refl, standard), goal_cases)
    case (1 y1 y2 y3)
    from arg_cong[OF 1(4), of "λ x. mat_of_row y1 + x"show ?case using 1(1-3) A
      by (subst (asm) assoc_add_mat[symmetric], (auto)[3],
        subst (asm) add_uminus_minus_mat, (auto)[1],
        subst (asm) minus_r_inv_mat, force,
        subst (asm) right_add_zero_mat, force,
        subst (asm) left_add_zero_mat, force, auto)
  next
    case (2 y1 y2 y3)
    show ?case unfolding 2(4using 2(1-3) A
      by (intro eq_matI, auto)
  qed
  also have " = (y1 carrier_vec nc. y2 carrier_vec nr. y3 carrier_vec nr.
              0v nc y1 0v nr y2 0v nr y3
              mat_of_row y1 = mat_of_row (y2 - y3) * A
               (y2 - y3) b 0)"
    by (intro ball_cong[OF refl] imp_cong refl 
      arg_cong2[of _ _ _ _ "()"] arg_cong2[of _ _ _ _ "(=)"],
      subst minus_mult_distrib_mat[symmetric], insert A b, auto
      simp: minus_scalar_prod_distrib mat_of_rows_def 
      intro!: arg_cong[of _ _ "λ x. x * _"])
  also have " = (y1 carrier_vec nc. y2 carrier_vec nr. y3 carrier_vec nr.
              0v nc y1 0v nr y2 0v nr y3
              y1 = row (mat_of_row (y2 - y3) * A) 0
               (y2 - y3) b 0)"
  proof (intro ball_cong[OF refl] arg_cong2[of _ _ _ _ "()"] refl, standard, goal_cases)
    case (1 y1 y2 y3)
    from arg_cong[OF 1(4), of "λ x. row x 0"1(1-3) A
    show ?case by auto
  qed (insert A, auto)
  also have " = (y2 carrier_vec nr. y3 carrier_vec nr.
              0v nc row (mat_of_row (y2 - y3) * A) 0 0v nr y2 0v nr y3
              row (mat_of_row (y2 - y3) * A) 0 carrier_vec nc
               (y2 - y3) b 0)" by blast
  also have " = (y2 carrier_vec nr. y3 carrier_vec nr.
              0v nc row (mat_of_row (y2 - y3) * A) 0 0v nr y2 0v nr y3
               (y2 - y3) b 0)"
    by (intro ball_cong[OF refl] arg_cong2[of _ _ _ _ "()"] refl, insert A,
        auto simp: row_def)
  also have " = ( y carrier_vec nr. row (mat_of_row y * A) 0 0v nc y b 0)" 
  proof ((standard; intro ballI impI), goal_cases)
    case (1 y)
    define y2 where "y2 = vec nr (λ i. if y $ i 0 then y $ i else 0)" 
    define y3 where "y3 = vec nr (λ i. if y $ i 0 then 0 else - y $ i)" 
    have y: "y = y2 - y3" unfolding y2_def y3_def using 1(2)
      by (intro eq_vecI, auto)
    show ?case by (rule 1(1)[rule_format, of y2 y3, folded y, OF _ _ 1(3)],
       auto simp: y2_def y3_def less_eq_vec_def)
  qed auto
  also have " = ( y carrier_vec nr. mat_of_row y * A 0m 1 nc y b 0)"
    by (intro ball_cong arg_cong2[of _ _ _ _ "()"] refl,
      insert A, auto simp: less_eq_vec_def less_eq_mat_def)
  finally show ?thesis .
qed 

end

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

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-06-10) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.