public bool IsModelFor(ClauseSet clauseSet) { foreach (var literals in clauseSet.Clauses.Select(clause => clause.Literals)) { var isClauseSatisfied = literals.Any(literal => ModelValues.Single(val => val.Name == literal.Name) == literal); if (!isClauseSatisfied) { return(false); } } return(true); }
public static void Run() { var solver = prepareSolver(); rawEncodeSudokuGame(solver); if (solver.Solve()) { var modelValues = solver.FoundModel !.ModelValues.Where(mv => mv.IsTrue).OrderBy(mv => mv.Name); foreach (var modelValue in modelValues) { Console.WriteLine(modelValue.ToString()); } } else { Console.WriteLine("No solution found!"); } }
public override string ToString() { return ($"{nameof(Index)}: {Index} {ModelValues.Aggregate(new StringBuilder(), (sb, modelValue) => sb.Append(modelValue + "\n"))}"); }
protected ModelValue DetermineParameterValue(ModelParameter parameter) { ModelValues values = new ModelValues(); values.Add(parameter.Values); //Parameter values, can be specified in numerous ways: // 1. Value list - simply choose one of them // 2. Expression - generate value that meets the criteria (ie: <, >, !=, etc) // 3. Variable - simply obtain the value by calling a method/field //#3. Variable - simply obtain the value by calling a method/field if(parameter.Variable != null) { object current = parameter.Variable.CachedValue; if(current is IEnumerable && !typeof(IEnumerable).IsAssignableFrom(parameter.Type)) { foreach(object v in (IEnumerable)current) values.Add(new ModelValue(v)); } else { values.Add(new ModelValue(current)); } } //First ensure we have a set of values/requirements to choose from if(values.Count <= 0) throw new ModelException(parameter, "No values specified to choose from"); //Note: Since we allow the operator on the individual values, this is a little more complex. //Note: We allow multiple operators, not just one, (ie: x > 5, < 10, and != 7). //This gives you great power and flexibility in expressions, but means we have to work a //little hard in determing a value that meets the requirements //#1. Value list - simply choose one of them //Note: Bitmask is already exploded into combinations ModelValues equalvalues = values.FindOperator(ModelValueOperator.Equal); //#2. Expression - generate value that meets the criteria (ie: <, >, !=, etc) //Note: Since we allow the operator on the individual values, this is a little more complex. //Note: We allow multiple operators, not just one, (ie: x > 5, < 10, and != 7). //This gives you great power and flexibility in expressions, but means we have to work a //little hard in determing a value that meets the requirements. int min = Int32.MinValue; int max = Int32.MaxValue; //Adjust our parameter, simplier to loop over all of them foreach(ModelValue value in values.FindOperator(ModelValueOperator.Equal, false).FindOperator(ModelValueOperator.NotEqual, false)) { //To keep this simple, we just support integers (for now). if(!(value.Value is int || value.Value is Nullable<int>)) throw new ModelException(parameter, "Generated value range must be specified in terms of integers, not '" + value.Type + "'"); //Simplify our life int v = (int)value.Value; //Adjust Max (if there is one) switch(value.Operator) { case ModelValueOperator.LessThanOrEqual: if(v < max) max = v; break; case ModelValueOperator.GreaterThanOrEqual: if(v > min) min = v; break; case ModelValueOperator.LessThan: if(v-1 < max && v > Int32.MinValue/*prevent underflow*/) max = v-1; break; case ModelValueOperator.GreaterThan: if(v+1 > min && v < Int32.MaxValue/*prevent overflow*/) min = v+1; break; }; } //Choose a new value, within the specified range //Note: We retry in case it equals one of the existing invalid values (ie: !=) while(true) { ModelValue choice = null; if(equalvalues.Count > 0) { //Simple: Choose one of the specified values choice = new ModelValue(equalvalues.Choose(this).Value); } else { //Otherwise: Choose a value within in the range //Note: Random.Next = min <= x < max (so we have to add one) int index = _options.Random.Next(min, max < Int32.MaxValue ? max + 1 : max); //Prevent overflow choice = new ModelValue(index); } //As soon as we find a value, within the range, (and not in the invalid list), were done bool valid = true; foreach(ModelValue invalid in values.FindOperator(ModelValueOperator.NotEqual)) { if(invalid.Evaluate(choice.Value, ModelValueOperator.Equal)) valid = false; } if(valid) return choice; } }