Notes concerning the hashing of boolean functions f and g.

Using arithmetic modulo p throughout (for example -1 means p-1).

hf(x,y,z)=                // uvw    f(u,v,w)
f0 * (1-x)*(1-y)*(1-z) +  // 000 -> f0
f1 * (1-x)*(1-y)*   z  +  // 001 -> f1
f2 * (1-x)*   y *(1-z) +  // 010 -> f2
f3 * (1-x)*   y *   z  +  // 011 -> f3
f4 *    x *(1-y)*(1-z) +  // 100 -> f4
f5 *    x *(1-y)*   z  +  // 101 -> f5
f6 *    x *   y *(1-z) +  // 110 -> f6
f7 *    x *   y *   z     // 111 -> f7

and 

hg(x,y,z)=                // uvw    g(u,v,w)
g0 * (1-x)*(1-y)*(1-z) +  // 000 -> g0
g1 * (1-x)*(1-y)*   z  +  // 001 -> g1
g2 * (1-x)*   y *(1-z) +  // 010 -> g2
g3 * (1-x)*   y *   z  +  // 011 -> g3
g4 *    x *(1-y)*(1-z) +  // 100 -> g4
g5 *    x *(1-y)*   z  +  // 101 -> g5
g6 *    x *   y *(1-z) +  // 110 -> g6
g7 *    x *   y *   z     // 111 -> g7

If the boolean functions f and g differ in just one minterm,
without loss of generality we can assume fi=gi, for i=0..6
and f7~=g7. The difference between the two hash values is

d(x,y,z) = hf(x,y,x)-hg(x,y,z) = (f7-g7)*x*y*z

In this case, 1<x,y,z<p implies d(x,y,z) is non zero.

If two or more minterms differ, without loss of generality assume
f7~=g7.

d(x,y,z)=                      // uvw    f(u,v,w)-g(u,v,w)
(f0-g0) * (1-x)*(1-y)*(1-z) +  // 000 -> f0-g0
(f1-g1) * (1-x)*(1-y)*   z  +  // 001 -> f1-g1
(f2-g2) * (1-x)*   y *(1-z) +  // 010 -> f2-g2
(f3-g3) * (1-x)*   y *   z  +  // 011 -> f3-g3
(f4-g4) *    x *(1-y)*(1-z) +  // 100 -> f4-g4
(f5-g5) *    x *(1-y)*   z  +  // 101 -> f5-g5
(f6-g6) *    x *   y *(1-z) +  // 110 -> f6-g6
(f7-g7) *    x *   y *   z     // 111 -> f7-g7

This can be written as

d(x,y,z) = X + (f7-g7)*x*y*z

If x,y and z are uniformly distributed random variables in the range
2..(p-1), it is reasonable to believe that X is a uniformly
distributed random variable in the range 1..(p-1). It is also
reasonable to assume that the distribution of X is indepenednt of the
distribution of -(f7-g7)*x*y*z and so the probability that
X=-(f7-g7)*x*y*z is approximately 1/(p-1). This suggests that our hash
function is as good as we can hope for (and perfect if the boolean
functions differ in just one minterm).


Extended boolen functions

x 1100
y 1010                 extended function

  0000  FF    False        0
  0001  xy=00   Nor        1 - x - y + xy
  0010  xy=01    Lt                y - xy
  0011  x0     Notx        1 - x
  0100  xy=10    Gt            x     - xy
  0101  y0     Noty        1     - y
  0110  x#y     Xor            x + y -2xy
  0111  xy#11  Nand        1         - xy
  1000  xy=11   And                    xy
  1001  x=y     Eqv        1 - x - y +2xy
  1010  y1        Y                y
  1011  xy#10   Imp        1 - x     + xy
  1100  x1        X            x
  1101  xy#01    Ge        1     - y + xy
  1110  xy#00    Or            x + y - xy
  1111  TT     True        1



FUN hash
: [Id,x], env => lookup(x,env)
: [Num, k], ? => k
: [True],   ? => 1
: [False],  ? => 0
: t[op, x, y], env => 
     if x and y have no free variables in common
        return Fop(hash(x,env), hash(y,env))
     else
       LET id = most frequently used common variable
       LET rid = lookup(id, env)
       return hash[Mul, [Num, 1-rid], subst(t, id, 0)] +
              hash[Mul, [Num,   rid], subst(t, id, 1)]










