/// <summary> /// Returns a symmetrical input boolean fact. /// For example, A is married to B if B is married to A. /// </summary> /// <remarks> /// See unit tests for the truth table, which ensures that the existence /// of one false causes a false to be returned. /// Note that the Sym() functions are also designed to add facts to the /// Facts.Unknowns list in the proper order and with proper short- /// circuiting. /// </remarks> public static Tbool Sym(object subj, string rel, object directObj) { if (Facts.HasBeenAsserted(rel, subj, directObj)) { return(QueryTvar <Tbool>(rel, subj, directObj)); } return(QueryTvar <Tbool>(rel, directObj, subj)); }
/// <summary> /// Determines whether the rule should short-circuit before firing the actual rule logic. /// </summary> public static RulePreCheckResponse ShortCircuitValue <T>(string rel, string symIndicator, string questionIndicator, params object[] argList) where T : Tvar { // First, determine whether any of the Things are unknown. Hstate h = EntityArgIsUnknown(argList); if (h != Hstate.Known) { T scv = (T)Util.ReturnProperTvar <T>(new Hval(null, h)); return(new RulePreCheckResponse(scv, true)); } // Extract argument parameters from argList object param1 = argList[0]; object param2 = argList.Length > 1 ? argList[1] : null; object param3 = argList.Length > 2 ? argList[2] : null; // Adds the function node to the proof tree Engine.AddToProofTree(new Facts.Fact(rel, param1, param2, param3, "?")); // Handle symmetrical facts if (symIndicator == "Sym") { // If the fact has not been asserted, add it to the list of unknown facts, so it gets asked. if (!Facts.HasBeenAssertedSym(param1, rel, param2)) { // EXPERIMENTAL: First, ask any assumed facts if (Facts.GetUnknowns) { // if (Facts.Sym(param1, rel, param2).IsEternallyUncertain) // { // Assumptions.AskAssumedFacts(rel, param1, param2, param3); // Assumptions.AskAssumedFacts(rel, param2, param1, param3); // } // "?" indicates that this node is a question to be asked of the user if (questionIndicator == "?") { Facts.AddUnknown(rel, param1, param2, null); } } } // If the fact has been asserted and is not "uncertain", return the asserted value. else { Tbool f = Facts.Sym(param1, rel, param2); if (!f.IsEternallyUncertain) { return(new RulePreCheckResponse(f, true)); } } } // Handle non-symmetrical facts (same code pattern as above) else { if (!Facts.HasBeenAsserted(rel, param1, param2, param3)) { if (Facts.GetUnknowns) { // EXPERIMENTAL: First, ask any assumed facts // Assumptions.AskAssumedFacts(rel, param1, param2, param3, false); if (questionIndicator == "?") { Facts.AddUnknown(rel, param1, param2, param3); } } } else { T f = Facts.QueryTvar <T>(rel, param1, param2, param3); if (!f.IsEternallyUncertain) { return(new RulePreCheckResponse(f, true)); } } } // Otherwise, proceed to examine the rule conditions and sub-rules. return(new RulePreCheckResponse(null, false)); }