func (cs *ConstraintSystem) FromBinary(b ...Variable) Variable {
	for i := 0; i < len(b); i++ {
		b[i].assertIsSet()
	}
	var res, v Variable
	res = cs.Constant(0)  
	var c big.Int
	c.SetUint64(1)
	L := make(compiled.LinearExpression, len(b))
	for i := 0; i < len(L); i++ {
		v = cs.Mul(c, b[i])       
		res = cs.Add(v, res)      
		cs.AssertIsBoolean(b[i])  
		c.Lsh(&c, 1)
	}
	return res
}
FromBinary packs b, seen as a fr.Element in little endian
package frontend
import (
	"math/big"
	"github.com/consensys/gnark/backend/hint"
	"github.com/consensys/gnark/internal/backend/compiled"
)
func (cs *ConstraintSystem) Add(i1, i2 interface{}, in ...interface{}) Variable {
	var res Variable
	res.linExp = make(compiled.LinearExpression, 0, 2+len(in))
	add := func(_i interface{}) {
		switch t := _i.(type) {
		case Variable:
			t.assertIsSet()  
			res.linExp = append(res.linExp, t.linExp.Clone()...)
		default:
			v := cs.Constant(t)
			res.linExp = append(res.linExp, v.linExp.Clone()...)
		}
	}
	add(i1)
	add(i2)
	for i := 0; i < len(in); i++ {
		add(in[i])
	}
	res.linExp = cs.reduce(res.linExp)
	return res
}
func (cs *ConstraintSystem) Neg(i interface{}) Variable {
	var res Variable
	switch t := i.(type) {
	case Variable:
		res.linExp = cs.negateLinExp(t.linExp)
	default:
		n := FromInterface(t)
		n.Neg(&n)
		if n.IsUint64() && n.Uint64() == 1 {
			return cs.one()
		}
		res = cs.Constant(n)
	}
	return res
}
func (cs *ConstraintSystem) negateLinExp(l compiled.LinearExpression) compiled.LinearExpression {
	res := make(compiled.LinearExpression, len(l))
	var coeff, coeffCopy big.Int
	for i, t := range l {
		coeffID, variableID, constraintVis := t.Unpack()
		coeff = cs.coeffs[coeffID]
		coeffCopy.Neg(&coeff)
		res[i] = cs.makeTerm(Wire{constraintVis, variableID, nil}, &coeffCopy)
	}
	return res
}
func (cs *ConstraintSystem) Sub(i1, i2 interface{}) Variable {
	var res Variable
	res.linExp = make(compiled.LinearExpression, 0, 2)
	switch t := i1.(type) {
	case Variable:
		t.assertIsSet()
		res.linExp = t.linExp.Clone()
	default:
		v := cs.Constant(t)
		res.linExp = v.linExp.Clone()
	}
	switch t := i2.(type) {
	case Variable:
		t.assertIsSet()
		negLinExp := cs.negateLinExp(t.linExp)
		res.linExp = append(res.linExp, negLinExp...)
	default:
		v := cs.Constant(t)
		negLinExp := cs.negateLinExp(v.linExp)
		res.linExp = append(res.linExp, negLinExp...)
	}
	res.linExp = cs.reduce(res.linExp)
	return res
}
func (cs *ConstraintSystem) mulConstant(i interface{}, v Variable) Variable {
	var linExp compiled.LinearExpression
	var newCoeff big.Int
	lambda := FromInterface(i)
	for _, t := range v.linExp {
		cID, vID, visibility := t.Unpack()
		switch cID {
		case compiled.CoeffIdMinusOne:
			newCoeff.Neg(&lambda)
		case compiled.CoeffIdZero:
			newCoeff.SetUint64(0)
		case compiled.CoeffIdOne:
			newCoeff.Set(&lambda)
		case compiled.CoeffIdTwo:
			newCoeff.Add(&lambda, &lambda)
		default:
			coeff := cs.coeffs[cID]
			newCoeff.Mul(&coeff, &lambda)
		}
		linExp = append(linExp, cs.makeTerm(Wire{visibility, vID, nil}, &newCoeff))
	}
	return Variable{Wire{}, linExp}
}
func (cs *ConstraintSystem) Mul(i1, i2 interface{}, in ...interface{}) Variable {
	mul := func(_i1, _i2 interface{}) Variable {
		var _res Variable
		switch t1 := _i1.(type) {
		case Variable:
			t1.assertIsSet()
			switch t2 := _i2.(type) {
			case Variable:
				t2.assertIsSet()
				_res = cs.newInternalVariable()  
				cs.constraints = append(cs.constraints, newR1C(t1, t2, _res))
				return _res
			default:
				_res = cs.mulConstant(t2, t1)
				return _res
			}
		default:
			switch t2 := _i2.(type) {
			case Variable:
				t2.assertIsSet()
				_res = cs.mulConstant(t1, t2)
				return _res
			default:
				n1 := FromInterface(t1)
				n2 := FromInterface(t2)
				n1.Mul(&n1, &n2)
				_res = cs.Constant(n1)
				return _res
			}
		}
	}
	res := mul(i1, i2)
	for i := 0; i < len(in); i++ {
		res = mul(res, in[i])
	}
	return res
}
func (cs *ConstraintSystem) Inverse(v Variable) Variable {
	v.assertIsSet()
	res := cs.newInternalVariable()
	debug := cs.addDebugInfo("inverse", v, "*", res, " == 1")
	cs.addConstraint(newR1C(v, res, cs.one()), debug)
	return res
}
func (cs *ConstraintSystem) Div(i1, i2 interface{}) Variable {
	res := cs.newInternalVariable()
	v1 := cs.Constant(i1)
	v2 := cs.Constant(i2)
	debug := cs.addDebugInfo("div", v1, "/", v2, " == ", res)
	cs.addConstraint(newR1C(v2, res, v1), debug)
	return res
}
func (cs *ConstraintSystem) Xor(a, b Variable) Variable {
	a.assertIsSet()
	b.assertIsSet()
	cs.AssertIsBoolean(a)
	cs.AssertIsBoolean(b)
	res := cs.newInternalVariable()
	v1 := cs.Mul(2, a)    
	v2 := cs.Add(a, b)    
	v2 = cs.Sub(v2, res)  
	cs.constraints = append(cs.constraints, newR1C(v1, b, v2))
	return res
}
func (cs *ConstraintSystem) Or(a, b Variable) Variable {
	a.assertIsSet()
	b.assertIsSet()
	cs.AssertIsBoolean(a)
	cs.AssertIsBoolean(b)
	res := cs.newInternalVariable()
	v1 := cs.Sub(1, a)
	v2 := cs.Sub(res, a)
	cs.constraints = append(cs.constraints, newR1C(b, v1, v2))
	return res
}
func (cs *ConstraintSystem) And(a, b Variable) Variable {
	a.assertIsSet()
	b.assertIsSet()
	cs.AssertIsBoolean(a)
	cs.AssertIsBoolean(b)
	res := cs.Mul(a, b)
	return res
}
func (cs *ConstraintSystem) IsZero(a Variable) Variable {
	a.assertIsSet()
	debug := cs.addDebugInfo("isZero", a)
	m := cs.NewHint(hint.IsZero, a)
	cs.addConstraint(newR1C(a, m, cs.Constant(0)), debug)
	cs.AssertIsBoolean(m)
	ma := cs.Add(m, a)
	_ = cs.Inverse(ma)
	return m
}
func (cs *ConstraintSystem) ToBinary(a Variable, nbBits int) []Variable {
	a.assertIsSet()
	b := make([]Variable, nbBits)
	for i := 0; i < nbBits; i++ {
		b[i] = cs.NewHint(hint.IthBit, a, i)
		cs.AssertIsBoolean(b[i])
	}
	var c big.Int
	c.SetUint64(1)
	var Σbi Variable
	Σbi.linExp = make(compiled.LinearExpression, nbBits)
	for i := 0; i < nbBits; i++ {
		Σbi.linExp[i] = cs.makeTerm(Wire{compiled.Internal, b[i].id, nil}, &c)
		c.Lsh(&c, 1)
	}
	cs.constraints = append(cs.constraints, newR1C(Σbi, cs.one(), a))
	return b
}