Zulip Chat Archive
Stream: general
Topic: Can `simp` introduce variables?
l1mey (Sep 16 2025 at 05:53):
I have these definitions of a structure:
/--
LLVM-style integers with poison value.
-/
structure iN (bits : Nat) : Type where
protected bitvec : BitVec bits
protected poison : Bool
protected poison_inv : poison → bitvec = 0
def poison {n : Nat} : iN n := ⟨0, true, by simp⟩
def bitvec {n : Nat} (value : BitVec n) : iN n := ⟨value, false, by simp⟩
To create a value of poison, use the poison function, and the bitvec a with a : BitVec n to instantiate a bitvector. In general you shouldn't construct iN directly. I would like to create a normal form for when some x : iN n is either poison or a bitvec.
@[simp, grind]
theorem poison_norm {n} (x : iN n) {h : x.poison = true}
: x = poison := by
obtain ⟨x_bitvec, is_poison, poison_inv⟩ := x
have h' : x_bitvec = 0 := poison_inv h
subst h'
subst h
rfl
@[simp, grind]
theorem bitvec_norm {n} (x : iN n) {_h : ¬x.poison = true}
: ∃ (a : BitVec n), x.bitvec = bitvec a := by
unfold bitvec
simp
The poison_norm turns all x : iN n that have x.poison into the actual poison definition. However, for the bitvec_norm, i would have to introduce variables. What would be the best way to allow simp to introduce these variables? I have used an exists here, but simp wouldn't instantiate it. Would a simproc work for this?
Yan Yablonovskiy 🇺🇦 (Sep 16 2025 at 09:30):
Perhaps you mean :
@[simp, grind]
theorem bitvec_norm {n} (x : iN n) {_h : ¬x.poison = true}
: ∃ (a : BitVec n), x.bitvec = (bitvec a).1 := by
unfold bitvec
simp
If I fill in your simp with sorry, I get a type error for the statements definition. And such questions may get better traction in the `new members' chat channel :slight_smile: .
Eric Wieser (Sep 16 2025 at 17:47):
Have you considered using Option (BitVec bits) instead?
Last updated: Dec 20 2025 at 21:32 UTC