Zulip Chat Archive

Stream: new members

Topic: Track no. of recursive calls


Vivek Rajesh Joshi (Jul 05 2024 at 11:30):

import Mathlib.Data.Matrix.Notation

variable {F : Type} [Field F] [DecidableEq F]

def Vector.any {F : Type} (v : Vector F n) (p : F  Bool) := v.toList.any p

@[simp] theorem Vector.any_def (v : Vector F n) (p : F  Bool) : v.any p = v.toList.any p := rfl

def Vector.firstNonzElt {F : Type} [Field F] [DecidableEq F] (v : Vector F n) (h: v.any (·  0)) : {x:F // x0}×(i : Fin n)×(Vector F (n-i-1)) :=
  match v with
  | [],hv => by simp at h
  | x::ys,ha =>
    have hn : n > 0 := by rw [ ha]; simp
    if hx:x  0
    then (x, hx, ⟨⟨0,hn,ys,by simp_rw [ ha];simp⟩⟩)
    else
      by
      have ys_nontriv: ys.any (·  0) := by
        simp at hx
        simp [List.any_cons, hx] at h
        simp [h]
      let (value, index, tail) := firstNonzElt (ys,by simp at ha; rw [ ha]; simp : Vector F (n-1)) ys_nontriv
      exact (value, index.succ.cast (by simp [Nat.sub_add_cancel hn]),tail.congr (by simp [Nat.Simproc.sub_add_eq_comm n (index) 1]))

abbrev Vector.allZero (v : Vector F n) := v.toList.all (.=0)

lemma Vector.allZero_not_anyN0 (v : Vector F n) : ¬ v.allZero  v.any (.≠0) := by
  constructor <;> (intro hv;simp at hv ⊢; exact hv)

def findPivotAuxN0 (l : List (Vector F m)) (hl : l.any (fun c => ¬c.allZero)) (j : Nat) : {c : F // c0}×(Fin m)×(Nat) :=
    match l with
    | [] => by simp at hl
    | col::as =>
      if hc : ¬ (col.allZero) then
        let piv,rowInd,_⟩ := (col.firstNonzElt (col.allZero_not_anyN0.mp (by simp at hc ⊢; exact hc)))
        (piv,rowInd,0)
      else
        by
        have as_nontriv: as.any (fun c => ¬c.allZero) := by
          simp at hc
          simp [List.any_cons, hc] at hl
          rcases hl with hl|hl
          · rcases hl with x,xc,hx⟩; have := hc x xc; contradiction
          · simp [hl]
        let (piv,rowInd,colInd) := findPivotAuxN0 as as_nontriv j
        exact (piv,rowInd,colInd+1)

Any way to show that the Nat output for findPivotAuxN0 is always less than the length of the list? The only way I can think of is to show that the function cannot be recursively called more than l.length+1 times, but I don't know how to prove that. Is there any other way?

Arthur Adjedj (Jul 05 2024 at 12:45):

You can prove this by induction over your list l:

example (l : List (Vector F m)) (hl : l.any (fun c => ¬c.allZero)) (j : Nat) : (findPivotAuxN0 l hl j).2.2  l.length := by
  induction l with
  | nil => simp [List.any] at hl
  | cons h tl tl_ih =>
    dsimp [findPivotAuxN0]
    split <;> simp
    apply tl_ih

Vivek Rajesh Joshi (Jul 05 2024 at 12:47):

Great, thanks!

Vivek Rajesh Joshi (Jul 06 2024 at 03:40):

Okay, I realised that my problem was different. I want to use j as a term of type Fin n in the function itself, and want to show that in the col::as case of match l, l.get j = col. Any way to show this?

Bbbbbbbbba (Jul 06 2024 at 03:58):

If l matches col :: as, should't it be l.get 0 = col?

Vivek Rajesh Joshi (Jul 06 2024 at 04:37):

Right, sorry. That's not what I meant, I mean that I need a way to show that in the kth recursive call of the function (when the j argument takes on the value k), the value of col is the kth element of the list I'm inducting over.
In case that too is wrong, I'll just state my objective: I want the index of the vector containing c, and I want to show that if I extract the element at that index from l, it will contain c.


Last updated: May 02 2025 at 03:31 UTC