func (constraint *Constraint) Satisfied(variables *Variables) bool {
	constraintVariablesSatisfied := true
	domainSatisfied := true
	for _, varname := range constraint.Vars {
		constraintVariablesSatisfied = constraintVariablesSatisfied && (variables.Contains(varname))
	}
	for _, variable := range *variables {
		domainSatisfied = domainSatisfied && (variable.Domain.Contains(variable.Value) || variable.Empty)
		if !variable.Domain.Contains(variable.Value) && !variable.Empty {
			fmt.Printf("Variable %v with domain %v does not support value %v\n", variable.Name, variable.Domain, variable.Value)
		}
	}
	if !constraintVariablesSatisfied {
		panic(fmt.Sprintf("Insufficient variables provided. Expected %v", constraint.Vars))
	}
	if !domainSatisfied {
		panic("Variables do not satisfy the domains given.")
	}
	return constraint.ConstraintFunction(variables)
}
Satisfied checks to see if the given Constraint is satisfied by the variables presented
package centipede
import (
	"fmt"
)
type Constraint struct {
	Vars               VariableNames
	ConstraintFunction VariablesConstraintFunction
}
type Constraints []Constraint
type VariablesConstraintFunction func(variables *Variables) bool
func (constraints *Constraints) AllSatisfied(variables *Variables) bool {
	flag := true
	for _, constraint := range *constraints {
		flag = flag && constraint.Satisfied(variables)
	}
	return flag
}
func (constraints *Constraints) FilterByName(name VariableName) Constraints {
	filtered := make(Constraints, 0)
	for _, constraint := range *constraints {
		if constraint.Vars.Contains(name) {
			filtered = append(filtered, constraint)
		}
	}
	return filtered
}
func (constraints *Constraints) FilterByOrder(order int) Constraints {
	filtered := make(Constraints, 0)
	for _, constraint := range *constraints {
		if len(constraint.Vars) == order {
			filtered = append(filtered, constraint)
		}
	}
	return filtered
}