private void UnitPropagation(TrailNode node, out Conflict conflict) { conflict = null; foreach (var clause in ClauseReferences[node.Literal.index]) { if (TryPropagate(node, clause, out bool error) is Literal empty) { AssignLiteral(empty); var newNode = new TrailNode(level, empty, clause); trail.Add(newNode); UnitPropagation(newNode, out conflict); if (conflict != null) { return; } } if (error) { var learnedClause = trail.GetUIP(clause, out int targetLevel); conflict = new Conflict(targetLevel, learnedClause); return; } } }
private TrailNode Backtrack() { var conflict = latestConflict; latestConflict = null; AddClause(conflict.Clause); RevertToLevel(conflict.Level); ApplyVSIDS(conflict.Clause); var empty = FindEmpty(conflict.Clause); if (debug) { Console.WriteLine($"Revert to level {level} | Learned: {conflict.Clause} | Empty: {string.Join(" ", empty)}"); StateDebug(); } if (empty.Count == 1) { AssignLiteral(empty[0]); var node = new TrailNode(level, empty[0], conflict.Clause); trail.Add(node); return(node); } else { return(Decision()); } }
private TrailNode Decision(Literal?force = null) { level++; Literal literal = force ?? SelectLiteral(); AssignLiteral(literal); var node = new TrailNode(level, literal); trail.Add(node); return(node); }
private Literal?TryPropagate(TrailNode node, Clause clause, out bool conflict) { int assignedValues = 0; int falseValues = 0; Literal empty = default; conflict = false; foreach (var lit in clause) { if (literals[lit.index].HasValue) { if (literals[lit.index].Value.value != lit.value) { falseValues++; } assignedValues++; } else { empty = lit; } } if (assignedValues != falseValues) { return(null); } if (assignedValues == clause.Count - 1) { return(empty); } if (falseValues == clause.Count) { conflict = true; return(null); } return(null); }
private void InitialUnitPropagation(out Conflict conflict) { conflict = null; foreach (var clause in Clauses) { if (clause.Count == 1) { Literal literal = clause[0]; if (!literals[literal.index].HasValue) { AssignLiteral(literal); var node = new TrailNode(level, literal, clause); trail.Add(node); UnitPropagation(node, out conflict); if (conflict != null) { return; } } } } }
public override SolverResult Run() { if (Running) { throw new InvalidOperationException("Solver is already running"); } Running = true; totalwatch = Stopwatch.StartNew(); InitialUnitPropagation(out Conflict conflict); if (conflict != null) { Running = false; return(SolverResult.Fail(0)); } if (AllAssigned) { Running = false; return(SolverResult.Success(0, literals)); } if (debug) { Console.WriteLine(); } while (true) { if (debug && latestConflict != null) { Console.WriteLine("- Conflict"); Console.WriteLine(trail.DebugMessage); } iterations++; TrailNode node = Travel(); UnitPropagation(node, out conflict); if (debug) { StateDebug(); } if (conflict == null && AllAssigned) { Running = false; return(SolverResult.Success(iterations, literals)); } if (conflict != null && level == 0) { Running = false; return(SolverResult.Fail(iterations)); } if (conflict != null) { latestConflict = conflict; } if (timeout != 0 && totalwatch.ElapsedMilliseconds > timeout) { Running = false; return(SolverResult.Timeout(iterations, (int)totalwatch.ElapsedMilliseconds)); } } }