예제 #1
0
        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);
                }
            }
        }