public IEnumerable <bool> retract(object Head, object Body) { Head = YP.getValue(Head); if (Head is Variable) { throw new PrologException("instantiation_error", "Head is an unbound variable"); } object[] arguments = YP.getFunctorArgs(Head); // We always match Head from _allAnswers, and the Body is Atom.a("true"). #pragma warning disable 0168, 0219 foreach (bool l1 in YP.unify(Body, Atom.a("true"))) { // The caller can assert another answer into this same predicate during yield, so we have to // make a copy of the answers. foreach (object[] answer in _allAnswers.ToArray()) { foreach (bool l2 in YP.unifyArrays(arguments, answer)) { _allAnswers.Remove(answer); clearIndexes(); yield return(false); } } } #pragma warning restore 0168, 0219 }
// disable warning on l1, don't see how we can // code this differently #pragma warning disable 0168, 0219 /// <summary> /// For each result, unify the _freeVariables and unify bagArrayVariable with the associated bag. /// </summary> /// <param name="bagArrayVariable">this is unified with the List<object> of matches for template that /// corresponds to the bindings for freeVariables. Be very careful: this does not unify with a Prolog /// list.</param> /// <returns></returns> public IEnumerable <bool> resultArray(Variable bagArrayVariable) { if (_freeVariables == null) { // No unbound free variables, so we only filled one bag. If empty, bagof fails. if (_findallBagArray.Count > 0) { foreach (bool l1 in bagArrayVariable.unify(_findallBagArray)) { yield return(false); } } } else { foreach (KeyValuePair <object[], List <object> > valuesAndBag in _bagForFreeVariables) { foreach (bool l1 in YP.unifyArrays(_freeVariables, valuesAndBag.Key)) { foreach (bool l2 in bagArrayVariable.unify(valuesAndBag.Value)) { yield return(false); } } // Debug: Should we free memory of the answers already returned? } } }
public IEnumerable <bool> clause(object Head, object Body) { Head = YP.getValue(Head); if (Head is Variable) { throw new PrologException("instantiation_error", "Head is an unbound variable"); } object[] arguments = YP.getFunctorArgs(Head); // We always match Head from _allAnswers, and the Body is Atom.TRUE. foreach (bool l1 in YP.unify(Body, Atom.TRUE)) { // The caller can assert another answer into this same predicate during yield, so we have to // make a copy of the answers. foreach (object[] answer in _allAnswers.ToArray()) { foreach (bool l2 in YP.unifyArrays(arguments, answer)) { yield return(false); } } } }
/// <summary> /// If arg is another Functor, then succeed (yield once) if this and arg have the /// same name and all functor args unify, otherwise fail (don't yield). /// If arg is a Variable, then call its unify to unify with this. /// Otherwise fail (don't yield). /// </summary> /// <param name="arg"></param> /// <returns></returns> public IEnumerable <bool> unify(object arg) { arg = YP.getValue(arg); if (arg is Functor) { Functor argFunctor = (Functor)arg; if (_name.Equals(argFunctor._name)) { return(YP.unifyArrays(_args, argFunctor._args)); } else { return(YP.fail()); } } else if (arg is Variable) { return(((Variable)arg).unify(this)); } else { return(YP.fail()); } }