public IEnumerable <Action> GetActionsForActionDef(ActionDef ad) { ParamSet knownSet = null; var names = Facts .Select(p => p.Value.AId) .ToArray(); // If action has no parameters if (ad.Parameters.Length == 0) { yield break; } // Each N+V gets mapped to a paramIdx foreach (VariableRelation varRelation in ad.PositivePreconditions) { IEnumerable <Fact> facts = null; int[] valueIdxs = null; // Exit if no matches found if (knownSet != null && !knownSet.Params.Any()) { break; } // R L R else if (varRelation.A.IsFree && varRelation.Rel.IsBound && varRelation.B.IsFree) { uint property = varRelation.Rel.Id; if (!Rel.Value.ContainsKey(property)) { yield break; } facts = Rel.Value[property]; valueIdxs = new[] { varRelation.A.Idx, varRelation.B.Idx }; } // R L L else if (varRelation.A.IsFree && varRelation.Rel.IsBound && varRelation.B.IsBound) { uint prop = varRelation.Rel.Id; if (!Rel.Value.ContainsKey(prop)) { yield break; } facts = Rel.Value[prop].Where(p => p.BId == varRelation.B.Id); valueIdxs = new[] { varRelation.A.Idx }; } // L L L else if (varRelation.A.IsBound && varRelation.Rel.IsBound && varRelation.B.IsBound) { throw new NotImplementedException(); } // R R R else if (varRelation.A.IsFree && varRelation.Rel.IsFree && varRelation.B.IsFree) { facts = Facts.Values; valueIdxs = new[] { varRelation.A.Idx, varRelation.Rel.Idx, varRelation.B.Idx }; } else { throw new NotImplementedException(); } // Convert Preds to Param objects var validParams = facts .Select(proposition => { var ret = new uint[ad.Parameters.Length]; if (varRelation.A.IsFree) { ret[varRelation.A.Idx] = proposition.AId; } if (varRelation.Rel.IsFree) { ret[varRelation.Rel.Idx] = proposition.RelId; } if (varRelation.B.IsFree) { ret[varRelation.B.Idx] = proposition.BId; } return(ret); }) .ToList(); // If first Proposition if (knownSet == null) { knownSet = new ParamSet(validParams, valueIdxs); } // Join known param with new params else { var newSet = new ParamSet(validParams, valueIdxs); knownSet = knownSet.Join(newSet); } } if (knownSet != null) { knownSet = knownSet.Expand(names); } foreach (VariableRelation varRelation in ad.NegativePreconditions) { IEnumerable <Fact> props = null; int[] valueIdxs = null; // Exit if no matches found if (knownSet != null && !knownSet.Params.Any()) { break; } // R L R else if (varRelation.A.IsFree && varRelation.Rel.IsBound && varRelation.B.IsFree) { uint prop = varRelation.Rel.Id; if (!Rel.Value.ContainsKey(prop)) { break; } props = Rel.Value[prop]; valueIdxs = new[] { varRelation.A.Idx, varRelation.B.Idx }; } // R L L else if (varRelation.A.IsFree && varRelation.Rel.IsBound && varRelation.B.IsBound) { uint prop = varRelation.Rel.Id; if (!Rel.Value.ContainsKey(prop)) { break; } props = Rel.Value[prop] .Where(p => p.BId == varRelation.B.Id); valueIdxs = new[] { varRelation.A.Idx }; } // L L L else if (varRelation.A.IsBound && varRelation.Rel.IsBound && varRelation.B.IsBound) { throw new NotImplementedException(); } // R R R else { props = Facts.Values; valueIdxs = new[] { varRelation.A.Idx, varRelation.Rel.Idx, varRelation.B.Idx }; } // Convert Propositions to Param objects var toRemove = props .Select(prop => { var ret = new uint[ad.Parameters.Length]; if (varRelation.A.IsFree) { ret[varRelation.A.Idx] = prop.AId; } if (varRelation.Rel.IsFree) { ret[varRelation.Rel.Idx] = prop.RelId; } if (varRelation.B.IsFree) { ret[varRelation.B.Idx] = prop.BId; } return(ret); }) .ToList(); // If first Proposition if (knownSet == null) { knownSet = new ParamSet(toRemove, valueIdxs); } // Remove invalid propositions from KnownSet else { var newSet = new ParamSet(toRemove, valueIdxs); knownSet = knownSet.Except(newSet); } } if (knownSet != null) { knownSet = knownSet.Expand(names); foreach (var action in knownSet.Params.Select(p => new Action(ad, p))) { yield return(action); } } }