gates = {
const sqrh = math.sqrt(0.5)
const Z = i => c => new PState([c, c.bit(i)? -1 : 1])
const X = i => c => new PState([c.set(i, !c.bit(i)), 1])
const S = i => c => new PState([c, c.bit(i)? math.complex(0,1) : 1])
const H = i => c => new PState([c.set(i,false), sqrh], [c.set(i,true), c.bit(i)? -sqrh : sqrh])
const C = (op, ...control) => c => control.every(([i,v]) => c.bit(i) == v)? op(c) : new PState([c,1])
return {Z, X, S, H, C}
}