///// <summary> ///// Satisfy either of the two goals. ///// </summary> ///// <param name="left">The left goal to satisfy.</param> ///// <param name="right">The right goal to satisfy.</param> ///// <returns>A <see cref="Goal"/> describing the equalities to satisfy.</returns> //public static Goal Disjunction(params Goal[] goals) //{ // // concat works here, but is less fair than interleaving evaluation between left and right // //return new Goal { Thunk = state => left.Thunk(state).Concat(right.Thunk(state)) }; // return new Goal { Thunk = state => Interleave(left.Thunk(state), right.Thunk(state)) }; //} /// <summary> /// Satisfy both two goals simultaneously. /// </summary> /// <param name="left">The left goal to satisfy.</param> /// <param name="right">The right goal to satisfy.</param> /// <returns>A <see cref="Goal"/> describing the equalities to satisfy.</returns> public static Goal Recurse(Func <Kanren, Goal> body, Kanren x) { return(new Goal { Thunk = state => new Lifo <State>(new State { incomplete = () => body(x).Thunk(state) }) }); }
/// <summary> /// Extend the set of bindings. /// </summary> /// <param name="x"></param> /// <param name="v"></param> /// <returns></returns> internal State Extend(Kanren x, object v) { //FIXME: shouldn't duplicate a binding, but if it would, should return null? return(new State { substitutions = substitutions.Add(x, v), next = next, incomplete = incomplete }); }
/// <summary> /// Obtain the value bound to the variable, if any. /// </summary> /// <param name="x"></param> /// <returns></returns> internal object Get(Kanren x) { object v; return(substitutions.TryGetValue(x, out v) ? v : null); }
public static Goal operator &(Goal left, Goal right) { return(Kanren.Conjunction(left, right)); }
public override bool Equals(object other) { Kanren x = other as Kanren; return(!ReferenceEquals(x, null) && Id == x.Id); }