func (cs *CS) divlc(num, den LinearCombination) *Constraint {
	var left, right linearExpression
	for _, t := range den {
		left = append(left, term{Wire: t.Constraint.outputWire, Coeff: t.Coeff, Operation: mul})
	}
	for _, t := range num {
		right = append(right, term{Wire: t.Constraint.outputWire, Coeff: t.Coeff, Operation: mul})
	}
	expression := &quadraticExpression{
		left:      left,
		right:     right,
		operation: div,
	}
	return newConstraint(cs, expression)
}
divlc divides two linear combination of constraints
package frontend
import (
	"errors"
	"fmt"
	"math/big"
	"strconv"
	"github.com/consensys/gnark/backend"
	"github.com/consensys/gnark/internal/utils/debug"
)
var (
	ErrInconsistantConstraint = errors.New("inconsistant constraint")
)
type CS struct {
	Constraints map[uint64]*Constraint
	MOConstraints []moExpression
	NOConstraints []expression
	nbConstraints uint64
}
func New() CS {
	cs := CS{
		Constraints: make(map[uint64]*Constraint),
	}
	oneConstraint := &Constraint{
		outputWire: &wire{
			Name:         backend.OneWire,
			WireID:       -1,
			ConstraintID: -1,
			IsConsumed:   true,  
			Tags:         []string{},
		},
	}
	cs.addConstraint(oneConstraint)
	return cs
}
func (cs *CS) addConstraint(c *Constraint) {
	debug.Assert(c.constraintID == 0)
	c.constraintID = cs.nbConstraints
	cs.Constraints[c.constraintID] = c
	cs.nbConstraints++
}
func (cs *CS) mul(c1, c2 *Constraint) *Constraint {
	expression := &quadraticExpression{
		left:      linearExpression{term{Wire: c1.outputWire, Coeff: bigOne()}},
		right:     linearExpression{term{Wire: c2.outputWire, Coeff: bigOne()}},
		operation: mul,
	}
	return newConstraint(cs, expression)
}
func (cs *CS) mulConstant(c *Constraint, constant big.Int) *Constraint {
	expression := &term{
		Wire:      c.outputWire,
		Coeff:     constant,
		Operation: mul,
	}
	return newConstraint(cs, expression)
}
func (cs *CS) div(c1, c2 *Constraint) *Constraint {
	expression := quadraticExpression{
		left:      linearExpression{term{Wire: c2.outputWire, Coeff: bigOne()}},
		right:     linearExpression{term{Wire: c1.outputWire, Coeff: bigOne()}},
		operation: div,
	}
	return newConstraint(cs, &expression)
}
func (cs *CS) divConstantRight(c1 *Constraint, c2 big.Int) *Constraint {
	expression := quadraticExpression{
		left:      linearExpression{term{Wire: cs.Constraints[0].outputWire, Coeff: c2}},
		right:     linearExpression{term{Wire: c1.outputWire, Coeff: bigOne()}},
		operation: div,
	}
	return newConstraint(cs, &expression)
}
func (cs *CS) divConstantLeft(c1 big.Int, c2 *Constraint) *Constraint {
	expression := quadraticExpression{
		left:      linearExpression{term{Wire: c2.outputWire, Coeff: bigOne()}},
		right:     linearExpression{term{Wire: cs.Constraints[0].outputWire, Coeff: c1}},
		operation: div,
	}
	return newConstraint(cs, &expression)
}
func (cs *CS) inv(c1 *Constraint, e big.Int) *Constraint {
	expression := &term{
		Wire:      c1.outputWire,
		Coeff:     e,
		Operation: div,
	}
	return newConstraint(cs, expression)
}
func (cs *CS) add(c1 *Constraint, c2 *Constraint) *Constraint {
	expression := &linearExpression{
		term{Wire: c1.outputWire, Coeff: bigOne()},
		term{Wire: c2.outputWire, Coeff: bigOne()},
	}
	return newConstraint(cs, expression)
}
func (cs *CS) addConstant(c *Constraint, constant big.Int) *Constraint {
	expression := &linearExpression{
		term{Wire: c.outputWire, Coeff: bigOne()},
		term{Wire: cs.Constraints[0].outputWire, Coeff: constant},
	}
	return newConstraint(cs, expression)
}
func (cs *CS) sub(c1 *Constraint, c2 *Constraint) *Constraint {
	var minusOne big.Int
	one := bigOne()
	minusOne.Neg(&one)
	expression := &linearExpression{
		term{Wire: c1.outputWire, Coeff: one},
		term{Wire: c2.outputWire, Coeff: minusOne},
	}
	return newConstraint(cs, expression)
}
func (cs *CS) subConstant(c *Constraint, constant big.Int) *Constraint {
	var minusOne big.Int
	one := bigOne()
	minusOne.Neg((&constant))
	expression := &linearExpression{
		term{Wire: c.outputWire, Coeff: one},
		term{Wire: cs.Constraints[0].outputWire, Coeff: minusOne},
	}
	return newConstraint(cs, expression)
}
func (cs *CS) subConstraint(constant big.Int, c *Constraint) *Constraint {
	var minusOne big.Int
	one := bigOne()
	minusOne.Neg((&one))
	expression := &linearExpression{
		term{Wire: cs.Constraints[0].outputWire, Coeff: constant},
		term{Wire: c.outputWire, Coeff: minusOne},
	}
	return newConstraint(cs, expression)
}