def ProbM(myBP): # myBP is a boolean polynomial being converted to probabilty expression1if type(myBP) == sage.rings.integer.Integer:2if myBP%2 == 0:3return QQ(0)4else:5return QQ(1)6myBP.variables()7mystr = str(myBP.variables()) # converting all uppers to lower and lowers to uppercase8newstr = ""9for l in mystr:10if l.isupper():11newstr = newstr + "1" # gotta mark them as upper or lower12else:13newstr = newstr + "0"14NewGens = ""15for ii in range(len(mystr)):16if newstr[ii] == "1":17NewGens = NewGens + mystr[ii].lower()18else:19NewGens = NewGens + mystr[ii].upper() # if boolean variable XcGGt1u then, prob var is xCggT1U etc.20NewGens = NewGens[1:len(NewGens) - 1] # generators for probabilty polynomial assuming boolean generators are independent21if len(myBP.variables()) == 1:22NewGens = NewGens.replace(',','')23CPR = PolynomialRing(QQ,len(myBP.variables()),NewGens.replace(', ',','),order='invlex')24CPR.inject_variables()25nn = myBP.nvariables() # number of generators in boolean polynomial26BPvars = myBP.variables()27BPmons = myBP.monomials()28atoms = 2**nn # number of atoms in corresponding boolean algebra29# should abort this with error, if too many variables in polynomial30Mvect = [0]*atoms31for jj in range(len(BPmons)):32mm = 033for kk in range(len(BPmons[jj].variables())):34mm = mm + 2**BPvars.index(BPmons[jj].variables()[kk])35Mvect[mm] = 136Mvect.reverse()37# Mvect order for instance is (X111,X110,X101,X100,X011,X010,X001,X000) has two nonequiv intepretations38# as monomials or atoms example was for three variables39Mvect = vector(Mvect)40MGinv = matrix(QQ,[1])41for ii in range(1,nn+1):42MGinv = block_matrix(QQ,2,2,[MGinv,-MGinv,0,MGinv],subdivide=False) # creating inverse of multigrade operator 'AND' matrix MG43# modulo 2 it's an involution however...44# MG and MGinv are upper triangular, MG is like Sierpinski triangle see45# https://commons.wikimedia.org/wiki/File:Multigrade_operator_AND.svg46Avect = (MGinv*Mvect)%247Pvect = MGinv*Avect # convert from boolean ring (mons) to boolean algebra (atoms) then to probability polynomial48# ((MGinv*Mvect)%2) is the atoms vector equivalent to the monnomials vector Mvect49# Pvect are the coefficients of prob poly in CPR50newpoly = CPR(1)51for ii in range(0,len(CPR.gens())):52newpoly = newpoly*(CPR(1) + CPR.gen(ii)) # to create all possible monomials in CPR53return Pvect*vector(newpoly.monomials()) # inner product of the two vectors to create prob poly5455