Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proving length of large array by rfl hangs #5502

Open
3 tasks done
vihdzp opened this issue Sep 27, 2024 · 2 comments
Open
3 tasks done

Proving length of large array by rfl hangs #5502

vihdzp opened this issue Sep 27, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@vihdzp
Copy link
Contributor

vihdzp commented Sep 27, 2024

Prerequisites

Please put an X between the brackets as you perform the following steps:

Description

The following snippet summarizes the issue:

import Init.Prelude

structure MyVector (α : Type u) (n : Nat) where
  toArray : Array α
  size_eq : toArray.size = n

-- works almost instantly
example : MyVector Nat 32 :=
  ⟨#[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], rfl⟩

-- (deterministic) timeout at `whnf`, maximum number of heartbeats (200000) has been reached
example : MyVector Nat 33 :=
  ⟨#[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], rfl⟩

Context

This is affecting batteries, as the v# notation doesn't work with vectors of length 33 or above. See Zulip.

Steps to Reproduce

  1. Declare a Batteries vector with length 33 or above.

Expected behavior: The code typechecks with no issues

Actual behavior: The code hangs indefinitely

Versions

4.12.0-rc1

Additional Information

by simp works just fine in these proofs.

There's a seemingly related issue I've found relating to this code snippet:

import Init.Prelude

example : List Nat :=
  let l := [1]
  -- 32 copies
  [l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0], l[0]]

Adding one more instance of l[0] makes this typecheck noticeably slower. In my production code where l was some more complicated list, adding this extra entry made Lean eat all of my remaining 5GB of RAM (whereas it was running on only 1GB beforehand)

Impact

Add 👍 to issues you consider important. If others are impacted by this issue, please ask them to add 👍 to it.

@vihdzp vihdzp added the bug Something isn't working label Sep 27, 2024
@kmill
Copy link
Collaborator

kmill commented Sep 27, 2024

Using by rfl instead of rfl somehow works around the issue:

example : MyVector Nat 33 :=
  ⟨#[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1], by rfl⟩

@kmill
Copy link
Collaborator

kmill commented Sep 28, 2024

Some more context for by rfl working: I was wondering whether by rfl was fast because it used the kernel defeq, but the difference between the meta defeq working or not is just whether pending metavariables have been synthesized.

open Lean Meta Elab Command Term
elab tk:"check_defeq " ker?:(&"kernel ")? synth?:(&"synth ")? a:term " =?= " b:term : command => liftTermElabM do
  let mut x ← elabTerm a none
  let mut y ← elabTerm b none
  if synth?.isSome then
    synthesizeSyntheticMVarsUsingDefault
    x ← instantiateMVars x
    y ← instantiateMVars y
  let success ←
    if ker?.isSome then
      ofExceptKernelException (Kernel.isDefEq (← getEnv) {} x y)
    else
      isDefEq x y
  if success then
    logInfoAt tk "defeq"
  else
    logErrorAt tk "not defeq"

check_defeq kernel synth #[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1].size =?= (33 : Nat)
-- defeq
check_defeq synth #[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1].size =?= (33 : Nat)
-- defeq
check_defeq #[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1].size =?= (33 : Nat)
-- error: timeout

Interestingly, the following succeeds

-- works
notation "z" => Nat.zero
check_defeq #[z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z].size =?= (33 : Nat)

This works for the MyVector case as well

-- works
notation "z" => Nat.zero
example : MyVector Nat 33 :=
  ⟨#[z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z,z], rfl⟩

But, strangely, using a local variable instead of this notation causes a timeout, so it's not just a matter of somehow avoiding OfNat instance problems.

-- times out
example (n : Nat) : MyVector Nat 33 :=
  ⟨#[n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n], rfl⟩

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants