From Stdlib Require Import Strings.String.
From Stdlib Require Import String Ascii.
From Stdlib Require Arith.
From stdpp Require Import base.
From stdpp Require Import fin_maps.
From stdpp Require Import gmap.
From stdpp Require Import base gmultiset.
From Stdlib Require Classical.
From Stdlib Require Import ZArith.
From stdpp.bitvector Require Import definitions tactics.
From Stdlib Require Import Sorting.Sorted.
From Stdlib Require Import Reals.Rbasic_fun.
From Stdlib Require Import Reals.Abstract.ConstructiveAbs.
From Stdlib Require Import Reals.Rdefinitions.
From stdpp Require Import list_relations.
From stdpp Require Import list_numbers.
From stdpp Require Import functions.
From Stdlib Require Import ClassicalEpsilon.
From stdpp Require Import base decidable.
From Stdlib Require Import ZArith.Zeuclid.
From Stdlib Require Import ZArith.Znumtheory.
From stdpp Require Import propset.
From Stdlib Require Import Reals.
Require Import Why3.Base.
Require Import Why3.why3.Ref.Ref.
Require Import Why3.matrix.Matrix.
Open Scope Z_scope.
Inductive direction :=
  | Left_bottom : direction
  | Right_bottom : direction
  | Bottom : direction
  | Right : direction.
Axiom direction_inhabited : Inhabited direction.
Global Existing Instance direction_inhabited.
Axiom direction_countable : Countable direction.
Global Existing Instance direction_countable.
Definition left_diag (m : matrix Z) (i : Z) (j : Z) : option Z := if decide (i < rows m ∧ 0%Z ≤ j ∧ 3%Z ≤ i ∧ j < columns m - 3%Z) then Some (elts m i j * elts m (i - 1%Z) (j + 1%Z) * elts m (i - 2%Z) (j + 2%Z) * elts m (i - 3%Z) (j + 3%Z)) else None.
Definition right_diag (m : matrix Z) (i : Z) (j : Z) : option Z := if decide (i < rows m - 3%Z ∧ 0%Z ≤ i ∧ j < columns m - 3%Z ∧ 0%Z ≤ j) then Some (elts m i j * elts m (i + 1%Z) (j + 1%Z) * elts m (i + 2%Z) (j + 2%Z) * elts m (i + 3%Z) (j + 3%Z)) else None.
Definition line (m : matrix Z) (i : Z) (j : Z) : option Z := if decide ((0%Z ≤ j ∧ j < columns m) ∧ 0%Z ≤ i ∧ i < rows m - 3%Z) then Some (elts m i j * elts m (i + 1%Z) j * elts m (i + 2%Z) j * elts m (i + 3%Z) j) else None.
Definition column (m : matrix Z) (i : Z) (j : Z) : option Z := if decide ((0%Z ≤ i ∧ i < rows m) ∧ 0%Z ≤ j ∧ j < columns m - 3%Z) then Some (elts m i j * elts m i (j + 1%Z) * elts m i (j + 2%Z) * elts m i (j + 3%Z)) else None.
Definition compute4 (m : matrix Z) (i : Z) (j : Z) (d : direction) : option Z := if decide (d = Left_bottom) then left_diag m i j else if decide (d = Right_bottom) then right_diag m i j else if decide (d = Bottom) then column m i j else if decide (d = Right) then line m i j else None.
Theorem find_max'vc (m : matrix Z) (o1 : Z) (fact0 : 4%Z < rows m) (fact1 : 4%Z < columns m) (fact2 : match line m 0%Z 0%Z with | None => o1 = 0%Z | Some v => o1 = v end) : let o2 : Z := rows m - 1%Z in (0%Z ≤ o2 + 1%Z -> ((∀(i' : Z) (j' : Z) (d : direction), (0%Z ≤ i' ∧ i' < 0%Z) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v => v ≤ o1 end)) ∧ Some o1 = compute4 m 0%Z 0%Z Right) ∧ (∀(cur_d : direction) (cur_j : Z) (cur_i : Z) (cur_max : Z), (∀(i : Z), (0%Z ≤ i ∧ i ≤ o2) ∧ (∀(i' : Z) (j' : Z) (d : direction), (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v => v ≤ cur_max end)) ∧ Some cur_max = compute4 m cur_i cur_j cur_d -> (let o3 : Z := columns m - 1%Z in (0%Z ≤ o3 + 1%Z -> (Some cur_max = compute4 m cur_i cur_j cur_d ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < 0%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v => v ≤ cur_max end))) ∧ (∀(cur_d1 : direction) (cur_j1 : Z) (cur_i1 : Z) (cur_max1 : Z), (∀(j : Z), (0%Z ≤ j ∧ j ≤ o3) ∧ Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v => v ≤ cur_max1 end)) -> (match left_diag m i j with | None => (match right_diag m i j with | None => (match line m i j with | None => (match column m i j with | None => Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v => v ≤ cur_max1 end)) | Some v => (if decide (cur_max1 < v) then Some v = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v1 => v1 ≤ v end)) else Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v1 => v1 ≤ cur_max1 end))) end) | Some v => (if decide (cur_max1 < v) then match column m i j with | None => Some v = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v1 => v1 ≤ v end)) | Some v1 => (if decide (v < v1) then Some v1 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v1 end)) else Some v = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v end))) end else match column m i j with | None => Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v1 => v1 ≤ cur_max1 end)) | Some v1 => (if decide (cur_max1 < v1) then Some v1 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v1 end)) else Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ cur_max1 end))) end) end) | Some v => (if decide (cur_max1 < v) then match line m i j with | None => (match column m i j with | None => Some v = compute4 m i j Right_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v1 => v1 ≤ v end)) | Some v1 => (if decide (v < v1) then Some v1 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v1 end)) else Some v = compute4 m i j Right_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v end))) end) | Some v1 => (if decide (v < v1) then match column m i j with | None => Some v1 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v1 end)) | Some v2 => (if decide (v1 < v2) then Some v2 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) else Some v1 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v1 end))) end else match column m i j with | None => Some v = compute4 m i j Right_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v end)) | Some v2 => (if decide (v < v2) then Some v2 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) else Some v = compute4 m i j Right_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v end))) end) end else match line m i j with | None => (match column m i j with | None => Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v1 => v1 ≤ cur_max1 end)) | Some v1 => (if decide (cur_max1 < v1) then Some v1 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v1 end)) else Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ cur_max1 end))) end) | Some v1 => (if decide (cur_max1 < v1) then match column m i j with | None => Some v1 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v1 end)) | Some v2 => (if decide (v1 < v2) then Some v2 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) else Some v1 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v1 end))) end else match column m i j with | None => Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ cur_max1 end)) | Some v2 => (if decide (cur_max1 < v2) then Some v2 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) else Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ cur_max1 end))) end) end) end) | Some v => (if decide (cur_max1 < v) then match right_diag m i j with | None => (match line m i j with | None => (match column m i j with | None => Some v = compute4 m i j Left_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v1 => v1 ≤ v end)) | Some v1 => (if decide (v < v1) then Some v1 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v1 end)) else Some v = compute4 m i j Left_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v end))) end) | Some v1 => (if decide (v < v1) then match column m i j with | None => Some v1 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v1 end)) | Some v2 => (if decide (v1 < v2) then Some v2 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) else Some v1 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v1 end))) end else match column m i j with | None => Some v = compute4 m i j Left_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v end)) | Some v2 => (if decide (v < v2) then Some v2 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) else Some v = compute4 m i j Left_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v end))) end) end) | Some v1 => (if decide (v < v1) then match line m i j with | None => (match column m i j with | None => Some v1 = compute4 m i j Right_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v1 end)) | Some v2 => (if decide (v1 < v2) then Some v2 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) else Some v1 = compute4 m i j Right_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v1 end))) end) | Some v2 => (if decide (v1 < v2) then match column m i j with | None => Some v2 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) | Some v3 => (if decide (v2 < v3) then Some v3 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v3 end)) else Some v2 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v2 end))) end else match column m i j with | None => Some v1 = compute4 m i j Right_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v1 end)) | Some v3 => (if decide (v1 < v3) then Some v3 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v3 end)) else Some v1 = compute4 m i j Right_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v1 end))) end) end else match line m i j with | None => (match column m i j with | None => Some v = compute4 m i j Left_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v end)) | Some v2 => (if decide (v < v2) then Some v2 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) else Some v = compute4 m i j Left_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v end))) end) | Some v2 => (if decide (v < v2) then match column m i j with | None => Some v2 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) | Some v3 => (if decide (v2 < v3) then Some v3 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v3 end)) else Some v2 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v2 end))) end else match column m i j with | None => Some v = compute4 m i j Left_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v end)) | Some v3 => (if decide (v < v3) then Some v3 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v3 end)) else Some v = compute4 m i j Left_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v end))) end) end) end else match right_diag m i j with | None => (match line m i j with | None => (match column m i j with | None => Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v1 => v1 ≤ cur_max1 end)) | Some v1 => (if decide (cur_max1 < v1) then Some v1 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v1 end)) else Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ cur_max1 end))) end) | Some v1 => (if decide (cur_max1 < v1) then match column m i j with | None => Some v1 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v1 end)) | Some v2 => (if decide (v1 < v2) then Some v2 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) else Some v1 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v1 end))) end else match column m i j with | None => Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ cur_max1 end)) | Some v2 => (if decide (cur_max1 < v2) then Some v2 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) else Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ cur_max1 end))) end) end) | Some v1 => (if decide (cur_max1 < v1) then match line m i j with | None => (match column m i j with | None => Some v1 = compute4 m i j Right_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ v1 end)) | Some v2 => (if decide (v1 < v2) then Some v2 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) else Some v1 = compute4 m i j Right_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v1 end))) end) | Some v2 => (if decide (v1 < v2) then match column m i j with | None => Some v2 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) | Some v3 => (if decide (v2 < v3) then Some v3 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v3 end)) else Some v2 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v2 end))) end else match column m i j with | None => Some v1 = compute4 m i j Right_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v1 end)) | Some v3 => (if decide (v1 < v3) then Some v3 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v3 end)) else Some v1 = compute4 m i j Right_bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v1 end))) end) end else match line m i j with | None => (match column m i j with | None => Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v2 => v2 ≤ cur_max1 end)) | Some v2 => (if decide (cur_max1 < v2) then Some v2 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) else Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ cur_max1 end))) end) | Some v2 => (if decide (cur_max1 < v2) then match column m i j with | None => Some v2 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ v2 end)) | Some v3 => (if decide (v2 < v3) then Some v3 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v3 end)) else Some v2 = compute4 m i j Right ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v2 end))) end else match column m i j with | None => Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v3 => v3 ≤ cur_max1 end)) | Some v3 => (if decide (cur_max1 < v3) then Some v3 = compute4 m i j Bottom ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ v3 end)) else Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < j + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v4 => v4 ≤ cur_max1 end))) end) end) end) end)) ∧ (Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1 ∧ (∀(i' : Z) (j' : Z) (d : direction), i' = i ∧ 0%Z ≤ j' ∧ j' < o3 + 1%Z ∨ (0%Z ≤ i' ∧ i' < i) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v => v ≤ cur_max1 end)) -> (∀(i' : Z) (j' : Z) (d : direction), (0%Z ≤ i' ∧ i' < i + 1%Z) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v => v ≤ cur_max1 end)) ∧ Some cur_max1 = compute4 m cur_i1 cur_j1 cur_d1))) ∧ (o3 + 1%Z < 0%Z -> (∀(i' : Z) (j' : Z) (d : direction), (0%Z ≤ i' ∧ i' < i + 1%Z) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v => v ≤ cur_max end)) ∧ Some cur_max = compute4 m cur_i cur_j cur_d))) ∧ ((∀(i' : Z) (j' : Z) (d : direction), (0%Z ≤ i' ∧ i' < o2 + 1%Z) ∧ 0%Z ≤ j' ∧ j' < columns m -> (match compute4 m i' j' d with | None => True | Some v => v ≤ cur_max end)) ∧ Some cur_max = compute4 m cur_i cur_j cur_d -> (∀(i : Z) (j : Z) (d : direction), (match compute4 m i j d with | None => True | Some v => v ≤ cur_max end)) ∧ (∃(i : Z) (j : Z) (d : direction), Some cur_max = compute4 m i j d)))) ∧ (o2 + 1%Z < 0%Z -> (∀(i : Z) (j : Z) (d : direction), (match compute4 m i j d with | None => True | Some v => v ≤ o1 end)) ∧ (∃(i : Z) (j : Z) (d : direction), Some o1 = compute4 m i j d)).
Admitted.
