public bool Resolve(XPredicate target, IXExpression expression, out List <XPredicate> facts, out List <XPredicate> localFacts) { if (expression == null) { facts = new List <XPredicate>(); localFacts = new List <XPredicate>(); return(true); } switch (expression.Type) { case XOperand.Predicate: var predicateExp = expression as XExpression; facts = new List <XPredicate>(); if (Run(predicateExp.Predicate, out localFacts)) { foreach (var f in localFacts) { var clone = target.Clone(); for (int i = 0; i < f.Vars.Length; ++i) { var sArg = predicateExp.Predicate.Vars[i]; var dArg = f.Vars[i]; if (sArg.Type == XType.Var && dArg.Type == XType.Const) { clone.Bind(sArg, dArg); } } facts.Add(clone); } return(true); } return(false); case XOperand.Not: var notExp = expression as XNot; return(!Resolve(target, notExp.Expression.Clone(), out facts, out localFacts)); default: var andExp = expression as XAnd; return(Resolve2(target, andExp, out facts, out localFacts)); } }
public bool Run(XPredicate target, out List <XPredicate> solutions) { logger.LogD("Target: {0}", target); solutions = new List <XPredicate>(); if (!VerifySignature(target.Signature)) { logger.LogD("FAILED"); return(false); } foreach (var c in Database.Clauses) { var clause = c.Bind(target.Clone()); if (clause != null) { logger.LogD("Suitable clause: {0}", clause); ++logger.Indent; var newTarget = clause.Predicate; if (Resolve(newTarget, clause.Body, out List <XPredicate> partialSolutions, out _)) { if (clause.Body == null && !solutions.Contains(newTarget)) { solutions.Add(newTarget); } else { solutions.AddRange(partialSolutions); } } --logger.Indent; } } if (solutions.Count != 0) { logger.LogD("SUCCESS"); return(true); } logger.LogD("FAILED"); return(false); }