Zulip Chat Archive
Stream: new members
Topic: How to compute something computable, when proving something?
Ilmārs Cīrulis (Sep 24 2025 at 22:13):
I have something like this. I can post the definition of determinant too if necessary, but I wasn't sure that it is relevant here.
Is there some command/tactic that I can use when doing proof by tactics - in this case to "evaluate" determinant test to 12?
def test : Array (Array Int) := #[#[1, 1, 1, 1], #[1, 2, 4, 8], #[1, 3, 9, 27], #[1, 4, 16, 64]]
#eval determinant test
-- it is 12, as expected
theorem determinant_of_test_eq_12 : determinant test = 12 := by
sorry
Aaron Liu (Sep 24 2025 at 22:13):
decide will do it
Aaron Liu (Sep 24 2025 at 22:14):
if your definition is transparent enough
Ilmārs Cīrulis (Sep 24 2025 at 22:21):
Maybe it isn't transparent enough. Here is all the code (I was learning how to do basic imperative programming in Lean).
def μ {α} [Inhabited α] [Zero α] [Add α] [Neg α] (M : Array (Array α)) : Array (Array α) := Id.run do
let size := M.size
let mut temp := Array.replicate size 0
for i in (Array.range (size-1)).reverse do
temp := temp.set! i (temp[i+1]! + M[i+1]![i+1]!)
temp := temp.map (fun x => -x)
let mut output := Array.replicate size (Array.replicate size 0)
for i in (0...size) do
let mut row := output[i]!
row := row.set! i temp[i]!
for j in ((i+1)...size) do
row := row.set! j M[i]![j]!
output := output.set! i row
return output
def mul {α} [Inhabited α] [Zero α] [Add α] [Mul α] (M1 M2 : Array (Array α)) : Array (Array α) := Id.run do
let number_of_rows := M1.size
let number_of_cols := M2[0]!.size
let mut output := Array.emptyWithCapacity number_of_rows
let columns_of_M2 := Array.ofFn (fun (i : Fin number_of_cols) => M2.map (fun x => x[i.val]!))
for r in (0...number_of_rows) do
let mut row := Array.emptyWithCapacity number_of_cols
for c in (0...number_of_cols) do
let value := (Array.zipWith (fun x y => x * y) M1[r]! columns_of_M2[c]!).sum
row := row.push value
output := output.push row
return output
def F {α} [Inhabited α] [Zero α] [Add α] [Neg α] [Mul α] (A : Array (Array α)) (n : Nat): Array (Array α) :=
match n with
| 0 => A
| m + 1 => mul (μ (F A m)) A
def determinant {α} [Inhabited α] [Zero α] [Add α] [Neg α] [Mul α] (A : Array (Array α)) : α :=
let result := (F A (A.size - 1))[0]![0]!
if (A.size % 2 = 0) then -result else result
def test : Array (Array Int) := #[#[1, 1, 1, 1], #[1, 2, 4, 8], #[1, 3, 9, 27], #[1, 4, 16, 64]]
#eval determinant test
theorem determinant_of_test_eq_12 : determinant test = 12 := by
decide
sorry
Weiyi Wang (Sep 24 2025 at 22:29):
I am not sure why this doesn't work, but at least native_decide works so I guess at least the statement is likely correct...
Aaron Liu (Sep 24 2025 at 22:30):
looks like it got stuck at docs#Std.PRange.RangeIterator.instIteratorLoop.loop
Kenny Lau (Sep 24 2025 at 22:31):
so decide mirrors #reduce and native_decide mirrors #eval (and is not safe) so you can see that #reduce also fails
Ilmārs Cīrulis (Sep 24 2025 at 23:09):
So... is it not provable? :melt:
Aaron Liu (Sep 24 2025 at 23:11):
probably provable you just need to unfold that definition
Ilmārs Cīrulis (Sep 25 2025 at 01:01):
Removed those PRange and also the use of Array.reverse and now it works.
def μ {α} [Inhabited α] [Zero α] [Add α] [Neg α] (M : Array (Array α)) : Array (Array α) := Id.run do
let size := M.size
let mut temp := Array.replicate size 0
for i in Array.range (size - 1) do
temp := temp.set! (size - 2 - i) (temp[size - 1 - i]! + M[size - 1 - i]![size - 1 - i]!)
temp := temp.map (fun x => -x)
let mut output := Array.replicate size (Array.replicate size 0)
for i in Array.range (size - 1) do
let mut row := output[i]!
row := row.set! i temp[i]!
for j in Array.range' (i+1) (size-i-1) do
row := row.set! j M[i]![j]!
output := output.set! i row
return output
def mul {α} [Inhabited α] [Zero α] [Add α] [Mul α] (M1 M2 : Array (Array α)) : Array (Array α) := Id.run do
let number_of_rows := M1.size
let number_of_cols := M2[0]!.size
let mut output := Array.emptyWithCapacity number_of_rows
let columns_of_M2 := Array.ofFn (fun (i : Fin number_of_cols) => M2.map (fun x => x[i.val]!))
for r in Array.range number_of_rows do
let mut row := Array.emptyWithCapacity number_of_cols
for c in Array.range number_of_cols do
let value := (Array.zipWith (fun x y => x * y) M1[r]! columns_of_M2[c]!).sum
row := row.push value
output := output.push row
return output
def F {α} [Inhabited α] [Zero α] [Add α] [Neg α] [Mul α] (A : Array (Array α)) (n : Nat): Array (Array α) :=
match n with
| 0 => A
| m + 1 => mul (μ (F A m)) A
def determinant {α} [Inhabited α] [Zero α] [Add α] [Neg α] [Mul α] (A : Array (Array α)) : α :=
let result := (F A (A.size - 1))[0]![0]!
if (A.size % 2 = 0) then -result else result
def test : Array (Array Int) := #[#[1, 1, 1, 1], #[1, 2, 4, 8], #[1, 3, 9, 27], #[1, 4, 16, 64]]
#eval determinant test
#reduce determinant test
theorem determinant_of_test_eq_12 : determinant test = 12 := by
decide
Last updated: Dec 20 2025 at 21:32 UTC