I want to prove that a circuit decomposition into Toffoli gates is correct. In order to do this, I'm trying to explain to Lean what it means to apply a Toffoli gate to bits (flip the target bit if the two control bits are on). But I keep getting stuck on basic details related to decidability, termination, syntax, and naming.
I tried making a state which was a
Set Nat
. But then I couldn't seem to evaluate everything because Lean didn't seem to believe thata \in b
was decidable. That's reasonable for general sets I suppose, but mine are finite integer sets. I then tried making my own set, which was just a list of unique integers, but couldn't convince Lean that my "flip if integer is list" method would terminate, despite all the recursive cases descending into the list. I don't really want to be using representations where these kinds of issues keep cropping up, since my ability to solve them is very limited.My favorite approach in other languages is to use bit packed integers for this. I tried doing this in Lean, but I can't find out where Lean or MathLib define how to say things like "compute the bitwise xor of these two integers" or "left shift this integer".
I asked ChatGPT and it just told me "here's what it would look like if it worked but this won't work: [thing that doesn't work]".
Anyways, strategic advice on the correct way to go would probably be helpful. But mostly I'd just like to get unstuck on the syntax for bitwise arithmetic:
structure Toffoli where
a : Nat
b : Nat
t : Nat
structure SimState where
bit_packed_state : Nat
def SimState.after
(s : SimState)
(op : Toffoli)
: SimState
:=
let m := s.bit_packed_state
-- syntax error on should-be-bitwiseand '&', should-be-leftshift '<<'
let a := (m & (1 << op.a)) != 0
-- syntax error on should-be-bitwiseand '&', should-be-leftshift '<<'
let b := (m & (1 << op.b)) != 0
-- syntax error on should-be-bitwisexor '^', should-be-leftshift '<<;
let m2 := m ^ ((a && b) << op.t)
SimState.mk m2
Set
is for arbitrary possibly infinite sets.PersistentHashSet
andHashSet
are more like sets in Python. For bit sets, the operations on Nat (or Uint8) are&&&
,|||
,^^^
,<<<
, and>>>
. (ByteArray
may also come in handy.) $\endgroup$