public void HeavilyConstrainedMultipleCardinalityTest() { var p = new Problem("Heavily constrained multiple cardinality test"); p.AddClause(2, 2, "w", "x", "y", "z"); p.AddClause(1, 1, "x", "y"); p.AddClause("w"); for (int i = 0; i < 10; i++) { var m = p.Solve(); var count = 0; if (m.IsTrue("w")) { count++; } if (m.IsTrue("x")) { count++; } if (m.IsTrue("y")) { count++; } if (m.IsTrue("z")) { count++; } Assert.AreEqual(2, count); Assert.IsTrue(m.IsTrue("x") ^ m.IsTrue("y")); Assert.IsTrue(m.IsTrue("w")); } }
//Test wp under regular pseudo bool constrains public void BigConstrainTest5() { var p = new Problem("cardinality"); var clause = p.AddClause(1, 1, "w", "x", "y", "z"); p.AddClause("w"); p.AddClause(1, 1, "a", "b", "c"); p.AddClause(1, 1, "e", "f"); p.AddClause(1, 1, "e"); for (int i = 0; i < 3; i++) { var m = p.Solve(); var count = 0; if (m.IsTrue("w")) { count++; } if (m.IsTrue("x")) { count++; } if (m.IsTrue("y")) { count++; } if (m.IsTrue("z")) { count++; } Assert.AreEqual("w", p.KeyOf(clause, 0).Name); } }
//Test if noise pushed up with Big constrains public void BigConstrainTest3() { var prob = new Problem("bigCardinality3"); var clause = prob.AddClause(10, 29, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "ll", "mm", "nn", "oo"); prob.AddClause(20, 29, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "p", "q", "r", "s", "t", "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "pp", "qq", "rr", "ss", "tt"); prob.AddClause(10, 29, "a", "b", "c", "d", "e", "f", "g", "h", "i", "t", "u", "v", "w", "x", "y", "z", "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "kk", "ll", "mm", "nn", "oo"); for (int i = 0; i < 5; i++) { var m = prob.Solve(); var count = 0; if (m.IsTrue("w")) { count++; } if (m.IsTrue("x")) { count++; } if (m.IsTrue("y")) { count++; } if (m.IsTrue("z")) { count++; } //Assert.AreEqual(3, count); //Assert.IsTrue(m.IsTrue("w")); Assert.AreEqual("a", prob.KeyOf(clause, 0).Name); } }
//Test if noise pushed up with Big pseudo bool constrains public void BigConstrainTest4() { var prob = new Problem("bigCardinality3"); var clause = prob.AddClause(1, 1, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "ab", "cd", "ac", "ad"); prob.AddClause(1, 1, "ef", "eg", "hi", "hl", "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "kk", "ll", "mm", "nn", "oo", "pp", "qq", "rr", "ss", "tt", "uu", "vv", "ww", "xx", "yy", "zz"); prob.AddClause(1, 1, "aab", "abb", "ccd", "ddc", "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo", "ppp", "qqq", "rrr", "sss", "ttt", "uuu", "vvv", "www", "xxx", "yyy", "zzz"); //prob.AddClause(1, 1, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "ab", "cd", "ac", "ad"); //prob.AddClause(1, 1, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "ab", "cd", "ac", "ad"); for (int i = 0; i < 3; i++) { var m = prob.Solve(); var count = 0; if (m.IsTrue("w")) { count++; } if (m.IsTrue("x")) { count++; } if (m.IsTrue("y")) { count++; } if (m.IsTrue("z")) { count++; } Assert.AreEqual("a", prob.KeyOf(clause, 0).Name); } }
public void NegativeSolveTest() { var p = new Problem("Negative solve test"); var positiveSolutionCount = 0; var negativeSolutionCount = 0; p.AddClause("x", Not("y")); // x -> y p.AddClause(Not("x"), "y"); // y -> x // This should only have two models: both true or both false. for (int i = 0; i < 1000; i++) { var m = p.Solve(); Assert.IsTrue(m.IsTrue("x") == m.IsTrue("y")); if (m.IsTrue("x")) { positiveSolutionCount++; } else { negativeSolutionCount++; } } Assert.IsTrue(positiveSolutionCount > 0, "Didn't generate any positive solutions!"); Assert.IsTrue(negativeSolutionCount > 0, "Didn't generate any negative solutions!"); }
public void ManualFluentTest() { var p = new Problem("Manual fluent test"); var after = (Proposition)"after"; var before = (Proposition)"before"; var activate = (Proposition)"activate"; var deactivate = (Proposition)"deactivate"; // activate => after p.AddClause(after, Not(activate)); // deactivate => not after p.AddClause(Not(after), Not(deactivate)); // before => after | deactivate p.AddClause(Not(before), after, deactivate); // not before => not after | activate p.AddClause(before, Not(after), activate); // Can't simultaneously activate and deactivate p.AddClause(0, 1, activate, deactivate); for (int i = 0; i < 100; i++) { var s = p.Solve(); if (s[after]) { Assert.IsTrue(s[before] || s[activate]); Assert.IsFalse(s[deactivate]); } else { Assert.IsTrue(!s[before] || s[deactivate]); Assert.IsFalse(s[activate]); } } }
public void UnsatisfiableTest() { var p = new Problem("Unsatisfiable test"); p.AddClause(2, 2, "w", "x", "y", "z"); p.AddClause(1, 1, "x", "y"); p.AddClause("w"); p.AddClause("z"); p.Solve(); Assert.Fail(); }
public void ConditionalTest2() { var p = new Problem("Compare with test 1"); p.AddClause(2, 2, "a", "c"); p.AddClause(1, 1, "b", "c"); for (int i = 0; i < 1000; i++) { var m = p.Solve(); Assert.IsFalse(m.IsTrue("b")); } }
public void PositiveSolveTest() { var p = new Problem("Positive solve test"); p.AddClause("x", "y"); p.AddClause("z"); for (int i = 0; i < 100; i++) { var m = p.Solve(); Assert.IsTrue(m.IsTrue("z")); Assert.IsTrue(m.IsTrue("x") || m.IsTrue("y")); } }
public void BiconditionalTest() { var p = new Problem(nameof(BiconditionalTest)); // Assert a <-> b void IfAndOnlyIf(Proposition a, Proposition b) { // a -> b p.AddClause(Not(a), b); // b -> a p.AddClause(Not(b), a); } // This only has two models: a=b=c=d=true, and a=b=c=d=false // This is the best-case for the Propagation step in BooleanSolver.MakeRandomAssignment // because once it chooses the value of the first variable, it should immediately propagate // to all other variables. IfAndOnlyIf("a", "b"); IfAndOnlyIf("b", "c"); IfAndOnlyIf("c", "d"); var trueCount = 0; for (var i = 0; i < 100; i++) { var m = p.Solve(); // This shouldn't have used any flips because propagation in initialization // should always produce a valid model Assert.AreEqual(0, p.SolveFlips.Max); // Make sure all variables have the same value if (m["a"]) { trueCount++; Assert.IsTrue(m["b"]); Assert.IsTrue(m["c"]); } else { Assert.IsFalse(m["b"]); Assert.IsFalse(m["c"]); } } // True and false models ought to be more or less equally likely. Assert.IsTrue(trueCount > 40); Assert.IsTrue(trueCount < 60); }
public void ForcePreSettingVariablesTest() { var p = new Problem("Force Extension hook test"); var preset = true; void MaybeSetVarX(Problem _) { // ReSharper disable once AccessToModifiedClosure if (preset) { p.SetPredeterminedValue("x", true, SATVariable.DeterminationState.Preinitialized); } } p.AddClause("x", "y"); p.AddClause("x", "z"); p.AddClause(Not("x"), "z"); p.AddClause(Not("x"), "y"); p.InitializeTruthAssignment += MaybeSetVarX; int numTrue = 0; int numTests = 1000; for (int i = 0; i < numTests; i++) { var m = p.Solve(); if (m.IsTrue("x")) { numTrue++; } } Console.WriteLine(numTrue); Assert.IsTrue(numTrue == numTests); preset = false; numTrue = 0; numTests = 1000; for (int i = 0; i < numTests; i++) { var m = p.Solve(); if (m.IsTrue("x")) { numTrue++; } } Console.WriteLine(numTrue); Assert.IsTrue(numTrue != numTests); }
public void PreSettingVariablesTest() { var p = new Problem("Extension hook test"); p.AddClause("x", "y"); p.AddClause("z"); p.InitializeTruthAssignment += SetVarX; for (int i = 0; i < 100; i++) { var m = p.Solve(); Assert.IsTrue(m.IsTrue("z")); Assert.IsTrue(m.IsTrue("x")); } }
public void UniqueTest() { var p = new Problem("Unique test"); p.AddClause(1, 1, "w", "x", "y", "z"); for (int i = 0; i < 100; i++) { var m = p.Solve(); var count = 0; if (m.IsTrue("w")) { count++; } if (m.IsTrue("x")) { count++; } if (m.IsTrue("y")) { count++; } if (m.IsTrue("z")) { count++; } Assert.AreEqual(1, count); } }
public void FixedCardinalityTest() { var p = new Problem("Fixed cardinality test"); p.AddClause(2, 2, "w", "x", "y", "z"); for (int i = 0; i < 100; i++) { var m = p.Solve(); var count = 0; if (m.IsTrue("w")) { count++; } if (m.IsTrue("x")) { count++; } if (m.IsTrue("y")) { count++; } if (m.IsTrue("z")) { count++; } Assert.AreEqual(2, count); } }
public void BoundedCardinalityTest() { var p = new Problem("Bounded cardinality test"); p.AddClause(1, 3, "w", "x", "y", "z"); for (int i = 0; i < 100; i++) { var m = p.Solve(); var count = 0; if (m.IsTrue("w")) { count++; } if (m.IsTrue("x")) { count++; } if (m.IsTrue("y")) { count++; } if (m.IsTrue("z")) { count++; } Assert.IsTrue(count >= 1 && count <= 3); } }
public void AddClauseTest() { var p = new Problem("Add clause test"); var clause = p.AddClause("x", "y"); Assert.AreEqual("x", p.KeyOf(clause, 0).Name); Assert.AreEqual("y", p.KeyOf(clause, 1)); }
public void NormalClause3() { var prob = new Problem("normal clause - more disjuncts and less clauses"); prob.AddClause("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "ll", "mm", "nn", "oo"); prob.AddClause("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "p", "q", "r", "s", "t", "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "pp", "qq", "rr", "ss", "tt"); prob.AddClause("a", "b", "c", "d", "e", "f", "g", "h", "i", "t", "u", "v", "w", "x", "y", "z", "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "kk", "ll", "mm", "nn", "oo"); prob.AddClause("a", "b", "c", "d", "e", "f", "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "s", "t", "u", "v", "w", "x", "y", "z", "ab", "cd", "ac", "ad"); prob.AddClause("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "hh", "ii", "jj", "kk", "ll", "mm", "nn", "oo", "y", "z", "ab", "cd", "ac", "ad"); int[] flip = new int[1000]; for (int i = 0; i < 1000; i++) { var m = prob.Solve(); flip[i] = m.Problem.BooleanSolver.SolveFlips; } int average = flip.Sum() / flip.Length; Console.WriteLine(average); // average 0 flip 10 ms with propagation, 0 flip 7 ms w/o }
//Test wp in regular constrains public void CardinalityConstrainTest() { var p = new Problem("cardinality"); var clause = p.AddClause(2, 4, "w", "x", "y", "z"); p.AddClause(0, 2, "x", "y"); p.AddClause("w"); p.AddClause(0, 3, "w", "x", "y"); p.AddClause(0, 2, "x", "y"); p.AddClause("w"); for (int i = 0; i < 10; i++) { var m = p.Solve(); var count = 0; if (m.IsTrue("w")) { count++; } if (m.IsTrue("x")) { count++; } if (m.IsTrue("y")) { count++; } if (m.IsTrue("z")) { count++; } Assert.AreEqual("w", p.KeyOf(clause, 0).Name); } }
public void ConditionalTest1() { var p = new Problem("MultipleCardinality"); p.QuantifyIf("a", 2, 2, "a", "c"); p.AddClause(1, 1, "b", "c"); for (int i = 0; i < 1000; i++) { var m = p.Solve(); Assert.IsTrue(m.Model.Equals("{a, c}") | m.Model.Equals("{b}") | m.Model.Equals("{c}")); Assert.IsFalse(m.Model.Equals("{b, c}")); } }
public void RangeConstraintPropagationTest() { // This should come out of the initialization process with a valid model // So this shouldn't require any flips var p = new Problem("normal clauses mixed with large PBCs and conditional PBCs2"); p.AddClause(3, 5, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"); for (int i = 0; i < 1000; i++) { var m = p.Solve(); Assert.AreEqual(0, m.Problem.BooleanSolver.SolveFlips); } }
public void ConditionalTest5() { var p = new Problem("MultipleCardinality2"); p.AddClause(10, 29, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "ll", "mm", "nn", "oo"); p.AddClause(20, 29, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "p", "q", "r", "s", "t", "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "pp", "qq", "rr", "ss", "tt"); p.AddClause(10, 29, "a", "b", "c", "d", "e", "f", "g", "h", "i", "t", "u", "v", "w", "x", "y", "z", "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "kk", "ll", "mm", "nn", "oo"); p.AddClause(1, 1, "e"); p.QuantifyIf("a", 2, 2, "a", "c"); p.AddClause(1, 1, "b", "c"); p.AddClause(1, 1, "d"); for (int i = 0; i < 100; i++) { var m = p.Solve(); Assert.IsTrue(m.IsTrue("e")); Assert.IsTrue(m.IsTrue("d")); Assert.IsFalse(m.Model.Equals("{e, c, b}")); Assert.IsFalse(m.Model.Equals("{e, c, b, d}")); Assert.IsFalse(m.Model.Equals("{e, a, b}")); } }
public void NormalAndPbc1() { var p = new Problem("normal clauses mixed with PBCs"); p.AddClause("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "ll", "mm", "nn", "oo"); p.AddClause("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "p", "q", "r", "s", "t", "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "pp", "qq", "rr", "ss", "tt"); p.AddClause("a", "b", "c", "d", "e", "f", "g", "h", "i", "t", "u", "v", "w", "x", "y", "z", "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "kk", "ll", "mm", "nn", "oo"); p.AddClause(1, 1, "e", "f"); p.AddClause("w"); p.AddClause(1, 1, "a", "b", "c"); int[] flip = new int[1000]; for (int i = 0; i < 1000; i++) { var m = p.Solve(); flip[i] = m.Problem.BooleanSolver.SolveFlips; } int average = flip.Sum() / flip.Length; Console.WriteLine(average); // average 1 flip 12ms with propagation, 1 flip 26ms w/o }
public void SkipPropagationTest() { var p = new Problem("Skip last test's propagation during initialization"); p.AddClause("b", "c"); p.AddClause("a", "d"); p.AddClause("d", "c"); p.AddClause("e", "c"); p.AddClause("f", "g"); p.AddClause("g", "c"); p.AddClause("h", "k"); p.AddClause("i", "c"); p.AddClause("j", "g"); p.AddClause("k", "c"); p.AddClause("l", "c"); p.AddClause("m", "c"); p.AddClause("n", "r"); p.AddClause(1, 1, "e", "f"); p.AddClause("w"); p.QuantifyIf("a", 2, 2, "a", "c"); p.AddClause(1, 1, "b", "c"); p.PropagateConstraintsDuringInitialization = false; int[] flip = new int[1000]; for (int i = 0; i < 1000; i++) { var m = p.Solve(); flip[i] = m.Problem.BooleanSolver.SolveFlips; } int average = flip.Sum() / flip.Length; p.Assert(average == 4); }
public void NormalAndPbc4() { var p = new Problem("normal clauses mixed with large PBCs and conditional PBCs2"); p.AddClause("b", "c"); p.AddClause("a", "d"); p.AddClause("d", "c"); p.AddClause("e", "c"); p.AddClause("f", "g"); p.AddClause("g", "c"); p.AddClause("h", "k"); p.AddClause("i", "c"); p.AddClause("j", "g"); p.AddClause("k", "c"); p.AddClause("l", "c"); p.AddClause("m", "c"); p.AddClause("n", "r"); p.AddClause(1, 1, "e", "f"); p.AddClause("w"); p.QuantifyIf("a", 2, 2, "a", "c"); p.AddClause(1, 1, "b", "c"); int[] flip = new int[1000]; for (int i = 0; i < 1000; i++) { var m = p.Solve(); flip[i] = m.Problem.BooleanSolver.SolveFlips; } int average = flip.Sum() / flip.Length; Console.WriteLine(average); // average 2 flip 10 ms w/ propagation, 4 flip 6 ms w/o }
public void NormalClause1() { var p = new Problem("normal clause - short and more clauses"); p.AddClause("b", "c"); p.AddClause("a", "c"); p.AddClause("d", "c"); p.AddClause("e", "c"); p.AddClause("f", "c"); p.AddClause("g", "c"); p.AddClause("h", "c"); p.AddClause("i", "c"); p.AddClause("j", "c"); p.AddClause("k", "c"); p.AddClause("l", "c"); p.AddClause("m", "c"); p.AddClause("n", "c"); p.AddClause("o", "c"); p.AddClause("p", "c"); p.AddClause("q", "c"); p.AddClause("r", "c"); p.AddClause("s", "c"); p.AddClause("t", "c"); p.AddClause("u", "c"); p.AddClause("v", "c"); p.AddClause("w", "c"); p.AddClause("x", "c"); p.AddClause("y", "c"); p.AddClause("z", "c"); p.AddClause("a", "b"); p.AddClause("d", "b"); int[] flip = new int[1000]; for (int i = 0; i < 1000; i++) { var m = p.Solve(); flip[i] = m.Problem.BooleanSolver.SolveFlips; } int average = flip.Sum() / flip.Length; Console.WriteLine(average); // average 0 flip 6 mswith propagation, 1 flip 7 ms w/o }