private ActionDef ParseActionDef( Tokenizer tok, Dictionary <string, ActionDef> parsedActions) { var posPre = new HashSet <VariableRelation>(); var negPre = new HashSet <VariableRelation>(); var posPost = new HashSet <VariableRelation>(); var negPost = new HashSet <VariableRelation>(); string name = tok.Consume(TokenType.Id).Value; // Signature var parameters = ParseSignature(tok); var paramVars = parameters .ToDictionary(k => k.Name); // Optional Dependent Actions while (tok.PeekType() == TokenType.LParen) { tok.Consume(TokenType.LParen); // Dependent Action if (tok.PeekType() == TokenType.Id) { var depAction = ParseDependentAction(tok, parsedActions, paramVars); posPre.AddRange(depAction.PositivePreconditions); negPre.AddRange(depAction.NegativePreconditions); posPost.AddRange(depAction.PositivePostconditions); negPost.AddRange(depAction.NegativePostconditions); } // Pre Expression else if (tok.PeekType() == TokenType.Pre) { tok.Consume(TokenType.Pre); if (tok.PeekToken().Type != TokenType.RParen) { var propDefs = ParseVariableRelations(paramVars, tok); foreach (var pd in propDefs) { var b = pd.Negated ? negPre.Add(pd) : posPre.Add(pd); } } } // Post Expression else if (tok.PeekType() == TokenType.Post) { tok.Consume(TokenType.Post); if (tok.PeekToken().Type != TokenType.RParen) { var propDefs = ParseVariableRelations(paramVars, tok); foreach (var pd in propDefs) { var b = pd.Negated ? negPost.Add(pd) : posPost.Add(pd); } } } tok.Consume(TokenType.RParen); } tok.Consume(TokenType.RParen); var ret = new ActionDef( name, paramVars.Values.ToArray(), posPre, negPre, posPost, negPost ); return(ret); }
public Action(ActionDef def, uint[] parameters) { Definition = def; Parameters = parameters; }
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); } } }