func (cd *Cond) Eval(rls *Rules) bool {
	if cd.El == CRule {
		if cd.Rule[0] == '\'' {
			return rls.HasOutput(cd.Rule)
		} else {
			return rls.HasFired(cd.Rule)
		}
	}
	if cd.El == SubCond && cd.Conds != nil {
		return cd.Conds.Eval(rls)
	}
	return false
}
True returns true if conditional expression is true
package esg
import (
	"fmt"
	"github.com/goki/ki/kit"
)
type Conds []*Cond
func (cs *Conds) String() string {
	str := ""
	for ci := range *cs {
		cd := (*cs)[ci]
		str += cd.String() + " "
	}
	return str
}
func (cs *Conds) Eval(rls *Rules) bool {
	cval := true
	hasCval := false
	lastBin := CondElsN  
	lastNot := false
	for ci := range *cs {
		cd := (*cs)[ci]
		switch cd.El {
		case And, Or:
			lastBin = cd.El
		case Not:
			lastNot = true
		default:
			tst := cd.Eval(rls)
			if lastNot {
				tst = !tst
				lastNot = false
			}
			if !hasCval {
				cval = tst
				hasCval = true
				continue
			}
			hasCval = true
			switch lastBin {
			case And:
				cval = cval && tst
			case Or:
				cval = cval || tst
			}
			lastBin = CondElsN
		}
	}
	return cval
}
func (cs *Conds) Validate(rl *Rule, it *Item, rls *Rules) []error {
	lastBin := CondElsN  
	lastNot := false
	var errs []error
	ncd := len(*cs)
	for ci := range *cs {
		cd := (*cs)[ci]
		switch cd.El {
		case And, Or:
			if lastBin != CondElsN {
				errs = append(errs, fmt.Errorf("Rule: %v Item: %v Condition has two binary logical operators in a row", rl.Name, it.String()))
			}
			if ci == 0 || ci == ncd-1 {
				errs = append(errs, fmt.Errorf("Rule: %v Item: %v Condition has binary logical operator at start or end", rl.Name, it.String()))
			}
			lastBin = cd.El
		case Not:
			if lastNot {
				errs = append(errs, fmt.Errorf("Rule: %v Item: %v Condition has two Not operators in a row", rl.Name, it.String()))
			}
			if ci == 0 || ci == ncd-1 {
				errs = append(errs, fmt.Errorf("Rule: %v Item: %v Condition has Not operator at start or end", rl.Name, it.String()))
			}
			lastNot = true
		default:
			elers := cd.Validate(rl, it, rls)
			if elers != nil {
				errs = append(errs, elers...)
			}
			lastNot = false
			lastBin = CondElsN
		}
	}
	return errs
}
type Cond struct {
	El    CondEls `desc:"what type of conditional element is this"`
	Rule  string  `desc:"name of rule or token to evaluate for CRule"`
	Conds Conds   `desc:"sub-conditions for SubCond"`
}
func (cd *Cond) String() string {
	switch cd.El {
	case And:
		return "&&"
	case Or:
		return "||"
	case Not:
		return "!"
	case CRule:
		return cd.Rule
	case SubCond:
		return "(" + cd.Conds.String() + ")"
	}
	return ""
}