/// <summary> ///<code> /// procedure OTTER(sos, usable) /// inputs: sos, a set of support-clauses defining the problem (a global variable) /// usable, background knowledge potentially relevant to the problem ///</code> /// </summary> /// <param name="ansHandler"></param> /// <param name="idxdClauses"></param> /// <param name="sos"></param> /// <param name="usable"></param> /// <returns></returns> private IInferenceResult Otter(OTTERAnswerHandler ansHandler, IndexedClauses idxdClauses, ISet<Clause> sos, ISet<Clause> usable) { LightestClauseHeuristic.InitialSOS(sos); // * repeat do { // * clause <- the lightest member of sos Clause clause = LightestClauseHeuristic.GetLightestClause(); if (null != clause) { // * move clause from sos to usable sos.Remove(clause); LightestClauseHeuristic.RemovedClauseFromSOS(clause); usable.Add(clause); // * PROCESS(INFER(clause, usable), sos) this.Process(ansHandler, idxdClauses, this.Infer(clause, usable), sos, usable); } // * until sos = [] or a refutation has been found } while (sos.Count != 0 && !ansHandler.IsComplete()); return ansHandler; }
// procedure PROCESS(clauses, sos) private void Process(OTTERAnswerHandler ansHandler, IndexedClauses idxdClauses, ISet<Clause> clauses, ISet<Clause> sos, ISet<Clause> usable) { // * for each clause in clauses do foreach (Clause clause in clauses) { // * clause <- SIMPLIFY(clause) var simplifiedClause = ClauseSimplifier.Simplify(clause); // * merge identical literals // Note: Not required as handled by Clause Implementation // which keeps literals within a ISet, so no duplicates // will exist. // * discard clause if it is a tautology if (simplifiedClause.IsTautology()) { continue; } // * if clause has no literals then a refutation has been found // or if it just Contains the answer literal. if (!ansHandler.IsAnswer(simplifiedClause)) { // * sos <- [clause | sos] // This check ensure duplicate clauses are not // introduced which will cause the // ILightestClauseHeuristic to loop continuously // on the same pair of objects. if (!sos.Contains(simplifiedClause) && !usable.Contains(simplifiedClause)) { foreach (var ac in simplifiedClause.GetFactors().Where(ac => !sos.Contains(ac) && !usable.Contains(ac))) { idxdClauses.addClause(ac, sos, usable); // * if clause has one literal then look for unit // refutation this.LookForUnitRefutation(ansHandler, idxdClauses, ac, sos, usable); } } } if (ansHandler.IsComplete()) { break; } } }
private void LookForUnitRefutation(OTTERAnswerHandler ansHandler, IndexedClauses idxdClauses, Clause clause, ISet<Clause> sos, ISet<Clause> usable) { ISet<Clause> toCheck = new HashedSet<Clause>(); if (ansHandler.IsCheckForUnitRefutation(clause)) { foreach (Clause s in sos) { if (s.IsUnitClause()) { toCheck.Add(s); } } foreach (Clause u in usable) { if (u.IsUnitClause()) { toCheck.Add(u); } } } if (toCheck.Count > 0) { toCheck = this.Infer(clause, toCheck); foreach (Clause t in toCheck) { // * clause <- SIMPLIFY(clause) var simplifiedT = ClauseSimplifier.Simplify(t); // * discard clause if it is a tautology if (simplifiedT.IsTautology()) { continue; } // * if clause has no literals then a refutation has been found // or if it just Contains the answer literal. if (!ansHandler.IsAnswer(simplifiedT)) { // * sos <- [clause | sos] // This check ensure duplicate clauses are not // introduced which will cause the // ILightestClauseHeuristic to loop continuously // on the same pair of objects. if (!sos.Contains(simplifiedT) && !usable.Contains(simplifiedT)) { idxdClauses.addClause(simplifiedT, sos, usable); } } if (ansHandler.IsComplete()) { break; } } } }