// difference between this and overrided method is that this packages list of decompositions with a substep dictionary int -> replaced plan step
        public static List <Tuple <TimelineDecomposition, Dictionary <int, IPlanStep> > > FilterDecompCandidates(TimelineDecomposition decomp)
        {
            // find and replace sub-steps
            var comboList = new List <List <IOperator> >();
            var ID_List   = new List <int>();

            foreach (var substep in decomp.SubSteps)
            {
                ID_List.Add(substep.ID);
                // each substep has ground terms that are already consistent. Composite IS-A Operator
                var cndts = ConsistentSteps(substep.Action as Operator);

                // If there's no cndts for this substep, then abandon this decomp.
                if (cndts.Count == 0)
                {
                    return(new List <Tuple <TimelineDecomposition, Dictionary <int, IPlanStep> > >());
                }

                comboList.Add(cndts);
            }

            // update to this method is to track, for each decomposition, which number substep goes to which grounded plan step
            List <Tuple <TimelineDecomposition, Dictionary <int, IPlanStep> > > decompMap = new List <Tuple <TimelineDecomposition, Dictionary <int, IPlanStep> > >();

            foreach (var combination in EnumerableExtension.GenerateCombinations(comboList))
            {
                var decompClone = decomp.Clone() as TimelineDecomposition;
                var newSubsteps = new List <IPlanStep>();
                var substepDict = new Dictionary <int, IPlanStep>();

                var order = 0;
                foreach (var item in combination)
                {
                    var originalID  = ID_List[order++];
                    var newPlanStep = new PlanStep(item);
                    substepDict[originalID] = newPlanStep;
                    newSubsteps.Add(newPlanStep);
                }

                var newSuborderings = new List <Tuple <IPlanStep, IPlanStep> >();
                foreach (var subordering in decomp.SubOrderings)
                {
                    var first  = substepDict[subordering.First.ID];
                    var second = substepDict[subordering.Second.ID];
                    newSuborderings.Add(new Tuple <IPlanStep, IPlanStep>(first, second));
                }

                var linkWorlds = new List <List <CausalLink <IPlanStep> > >();
                linkWorlds.Add(new List <CausalLink <IPlanStep> >());
                var newSublinks = new List <CausalLink <IPlanStep> >();
                foreach (var sublink in decomp.SubLinks)
                {
                    var head = substepDict[sublink.Head.ID];
                    var tail = substepDict[sublink.Tail.ID];
                    List <IPredicate> cndts = new List <IPredicate>();
                    //var cndts = head.Effects.Where(eff => eff.IsConsistent(sublink.Predicate) && tail.Preconditions.Any(pre => pre.Equals(eff)));
                    foreach (var eff in head.Effects)
                    {
                        foreach (var pre in tail.Preconditions)
                        {
                            if (eff.Equals(pre))
                            {
                                cndts.Add(eff);
                                //Debug.Log("here");
                            }
                        }
                    }

                    if (cndts.Count() == 0)
                    {
                        // forfeit this entire subplan
                        linkWorlds = new List <List <CausalLink <IPlanStep> > >();
                        continue;
                    }
                    if (cndts.Count() == 1)
                    {
                        var cndt       = cndts.First();
                        var dependency = cndt.Clone() as Predicate;
                        var newLink    = new CausalLink <IPlanStep>(dependency, head, tail);
                        newLink.Tail.Fulfill(cndt);
                        foreach (var linkworld in linkWorlds)
                        {
                            linkworld.Add(newLink);
                        }
                    }
                    else
                    {
                        foreach (var cndt in cndts)
                        {
                            var dependency = cndt.Clone() as Predicate;

                            var newLink = new CausalLink <IPlanStep>(dependency, head, tail);
                            newLink.Tail.Fulfill(cndt);

                            var clonedLinks = EnumerableExtension.CloneList(newSublinks);

                            linkWorlds.Add(clonedLinks);
                            foreach (var linkworld in linkWorlds)
                            {
                                linkworld.Add(newLink);
                            }
                        }
                    }
                }

                foreach (var linkworld in linkWorlds)
                {
                    var newDecomp = decomp.Clone() as TimelineDecomposition;
                    newDecomp.SubSteps     = newSubsteps;
                    newDecomp.SubOrderings = newSuborderings;
                    newDecomp.SubLinks     = linkworld;

                    var outputTuple = new Tuple <TimelineDecomposition, Dictionary <int, IPlanStep> >(newDecomp, substepDict);
                    decompMap.Add(outputTuple);
                }
            }
            return(decompMap);
        }
Пример #2
0
        /// <summary>
        /// Filters candidates for substeps, at least one with height "height"
        /// </summary>
        /// <param name="decomp"></param>
        /// <returns> List of decompositions with ground sub-steps. </returns>
        public static List <Decomposition> FilterDecompCandidates(Decomposition decomp, int height)
        {
            // find and replace sub-steps
            var comboList = new List <List <IOperator> >();
            var ID_List   = new List <int>();

            foreach (var substep in decomp.SubSteps)
            {
                ID_List.Add(substep.ID);
                // each substep has ground terms that are already consistent. Composite IS-A Operator
                var cndts = ConsistentSteps(substep.Action as Operator);

                // If there's no cndts for this substep, then abandon this decomp.
                if (cndts.Count == 0)
                {
                    return(new List <Decomposition>());
                }

                comboList.Add(cndts);
            }

            List <Decomposition> decompList = new List <Decomposition>();

            foreach (var combination in EnumerableExtension.GenerateCombinations(comboList))
            {
                var decompClone           = decomp.Clone() as Decomposition;
                var newSubsteps           = new List <IPlanStep>();
                var substepDict           = new Dictionary <int, IPlanStep>();
                var order                 = 0;
                var hasPrerequisiteHeight = false;
                foreach (var item in combination)
                {
                    if (item.Height >= height)
                    {
                        // meets height requirement
                        hasPrerequisiteHeight = true;
                    }
                    var originalID = ID_List[order++];
                    if (item.Height > 0)
                    {
                        var newPlanStep = new CompositePlanStep(item as Composite);
                        substepDict[originalID] = newPlanStep;
                        newSubsteps.Add(newPlanStep);
                    }
                    else
                    {
                        var newPlanStep = new PlanStep(item);
                        substepDict[originalID] = newPlanStep;
                        newSubsteps.Add(newPlanStep);
                    }
                }

                // Did not meet requirements for height.
                if (!hasPrerequisiteHeight)
                {
                    continue;
                }

                var newSuborderings = new List <Tuple <IPlanStep, IPlanStep> >();
                foreach (var subordering in decomp.SubOrderings)
                {
                    var first  = substepDict[subordering.First.ID];
                    var second = substepDict[subordering.Second.ID];
                    newSuborderings.Add(new Tuple <IPlanStep, IPlanStep>(first, second));
                }

                var linkWorlds = new List <List <CausalLink <IPlanStep> > >();
                linkWorlds.Add(new List <CausalLink <IPlanStep> >());
                var newSublinks = new List <CausalLink <IPlanStep> >();
                foreach (var sublink in decomp.SubLinks)
                {
                    var head  = substepDict[sublink.Head.ID];
                    var tail  = substepDict[sublink.Tail.ID];
                    var cndts = head.Effects.Where(eff => eff.IsConsistent(sublink.Predicate) && tail.Preconditions.Any(pre => pre.Equals(eff)));

                    //// swap tall members
                    //if (head.Height > 0)
                    //{
                    //    var Chead = head as CompositePlanStep;
                    //    head = Chead.GoalStep;
                    //}
                    //if (tail.Height > 0)
                    //{
                    //    var Ctail = tail as CompositePlanStep;
                    //    tail = Ctail.InitialStep;
                    //}

                    if (cndts.Count() == 0)
                    {
                        // forfeit this entire subplan
                        linkWorlds = new List <List <CausalLink <IPlanStep> > >();
                        continue;
                    }
                    if (cndts.Count() == 1)
                    {
                        var cndt       = cndts.First();
                        var dependency = cndt.Clone() as Predicate;
                        var newLink    = new CausalLink <IPlanStep>(dependency, head, tail);
                        newLink.Tail.Fulfill(cndt);
                        foreach (var linkworld in linkWorlds)
                        {
                            linkworld.Add(newLink);
                        }
                    }
                    else
                    {
                        foreach (var cndt in cndts)
                        {
                            var dependency = cndt.Clone() as Predicate;

                            var newLink = new CausalLink <IPlanStep>(dependency, head, tail);
                            newLink.Tail.Fulfill(cndt);

                            var clonedLinks = EnumerableExtension.CloneList(newSublinks);

                            linkWorlds.Add(clonedLinks);
                            foreach (var linkworld in linkWorlds)
                            {
                                linkworld.Add(newLink);
                            }
                        }
                    }
                }

                foreach (var linkworld in linkWorlds)
                {
                    var newDecomp = decomp.Clone() as Decomposition;
                    newDecomp.SubSteps     = newSubsteps;
                    newDecomp.SubOrderings = newSuborderings;
                    newDecomp.SubLinks     = linkworld;

                    decompList.Add(newDecomp);
                }
            }
            return(decompList);
        }
Пример #3
0
        /// <summary>
        /// Takes a fabula-valid decomposition and generates a list of discourse worlds (different camera shots to display the fabula)
        /// </summary>
        /// <param name="decompPackage"> Grounded fabula substeps and a mapping from step variables to those substeps </param>
        /// <param name="height"> Among CamOptions would include composite options... but may </param>
        /// <param name="camOptions"> From "Cameras" GameObject </param>
        /// <param name="locationMap"> Mapping location names to specific coordinates (used to determine orientation in space, and possibly for navigation estimates. </param>
        /// <returns> A list of TimelineDecomposition which all have fabula-valid and discourse-valid sub-plan</returns>
        public static List <TimelineDecomposition> FilterTimelineDecompCandidates(TimelineDecomposition TD, Tuple <TimelineDecomposition, Dictionary <int, IPlanStep> > decompPackage, int height,
                                                                                  List <CamSchema> camOptions, Dictionary <string, Vector3> locationMap)
        {
            var timelineDecompList = new List <TimelineDecomposition>();

            var decomp      = decompPackage.First;
            var substepDict = decompPackage.Second;

            // mapping ID of substeps to orientations
            var orientLocationTuple = GetOrientsAndLocations(decomp, locationMap);
            var orientDict          = orientLocationTuple.First;
            var locationDict        = orientLocationTuple.Second;

            // Easier list to reference later
            //var discourseSubStepList = new List<CamPlanStep>();

            // create permutation for each combination of legal subcams
            var permList = GetPermutationCameraShots(TD.discourseSubSteps, substepDict, TD.fabulaActionNameMap, orientDict, locationDict, camOptions);

            //ist<CamPlanStep> discourseSubSteps, Dictionary<int, IPlanStep> fabsubstepDict, Dictionary<string, IPlanStep> fabulaActionNameMap,
            //Dictionary<int, int> orientDict, Dictionary< int, string> locationDict, List<CamAttributesStruct> camOptions

            // foreach combination, check if step constraints are true
            foreach (var combination in EnumerableExtension.GenerateCombinations(permList))
            {
                // clone decomp
                var decompClone          = decomp.Clone() as TimelineDecomposition;
                var camSubStepDict       = new Dictionary <int, CamPlanStep>();
                var newDiscourseSubSteps = new List <CamPlanStep>();
                for (int j = 0; j < combination.Count; j++)
                {
                    // a reference to the camera object candidate
                    //var camObj = combination[j].AttributesToSchema();

                    // a reference to the j'th discourse step
                    var camStep = TD.discourseSubSteps[j].Clone() as CamPlanStep;
                    camStep.CamDetails = combination[j].Clone() as CamSchema;
                    //camStep.CamObject = camObj.gameObject;

                    // a cloning of the cam plan step
                    //var newPlanStep = camStep.Clone();
                    //newPlanStep.CamObject = camObj.gameObject;

                    // storing a mapping from old cam plan step ID to new cam plan step
                    camSubStepDict[camStep.ID] = camStep;
                    newDiscourseSubSteps.Add(camStep);
                }

                var boolOutcome = ValidateConstraints(substepDict, camSubStepDict, TD.fabConstraints, TD.discConstraints, orientDict);
                //    public static bool ValidateConstraints(Dictionary<int, IPlanStep> fabsubstepDict, Dictionary<int, CamPlanStep> discsubstepDict,
                //List<Tuple<string, Tuple<IPlanStep, IPlanStep>>> fabConstraints, List<Tuple<string, Tuple<IPlanStep, IPlanStep>>> discConstraints,
                //Dictionary<int, int> orientDict)
                if (!boolOutcome)
                {
                    continue;
                }

                // these are done here, but they could/should have been performed during regular legacy decomposition filtering.
                var newFabCntgs = new List <Tuple <IPlanStep, IPlanStep> >();
                foreach (var subCntg in TD.fabCntgs)
                {
                    var newcntg = new Tuple <IPlanStep, IPlanStep>(substepDict[subCntg.First.ID], substepDict[subCntg.Second.ID]);
                    newFabCntgs.Add(newcntg);
                }


                var newDOrderings = new List <Tuple <CamPlanStep, CamPlanStep> >();
                foreach (var subOrdering in TD.discOrderings)
                {
                    var newOrdering = new Tuple <CamPlanStep, CamPlanStep>(camSubStepDict[subOrdering.First.ID], camSubStepDict[subOrdering.Second.ID]);
                    newDOrderings.Add(newOrdering);
                }

                var newDiscCntgs = new List <Tuple <CamPlanStep, CamPlanStep> >();
                foreach (var subCntg in TD.discCntgs)
                {
                    var newcntg = new Tuple <CamPlanStep, CamPlanStep>(camSubStepDict[subCntg.First.ID], camSubStepDict[subCntg.Second.ID]);
                    newDiscCntgs.Add(newcntg);
                }


                var linkWorlds = new List <List <CausalLink <CamPlanStep> > >();
                linkWorlds.Add(new List <CausalLink <CamPlanStep> >());
                var newSublinks = new List <CausalLink <CamPlanStep> >();
                foreach (var subLink in TD.discLinks)
                {
                    var head  = camSubStepDict[subLink.Head.ID];
                    var tail  = camSubStepDict[subLink.Tail.ID];
                    var cndts = head.Effects.Where(eff => eff.IsConsistent(subLink.Predicate) && tail.Preconditions.Any(pre => pre.Equals(eff)));
                    if (cndts.Count() == 0)
                    {
                        // forfeit this entire subplan
                        linkWorlds = new List <List <CausalLink <CamPlanStep> > >();
                        break;
                    }
                    if (cndts.Count() == 1)
                    {
                        var cndt       = cndts.First();
                        var dependency = cndt.Clone() as Predicate;
                        var newLink    = new CausalLink <CamPlanStep>(dependency, head, tail);
                        newLink.Tail.Fulfill(cndt);
                        foreach (var linkworld in linkWorlds)
                        {
                            linkworld.Add(newLink);
                        }
                    }
                    else
                    {
                        foreach (var cndt in cndts)
                        {
                            var dependency = cndt.Clone() as Predicate;

                            var newLink = new CausalLink <CamPlanStep>(dependency, head, tail);
                            newLink.Tail.Fulfill(cndt);

                            var clonedLinks = EnumerableExtension.CloneList(newSublinks);

                            linkWorlds.Add(clonedLinks);
                            foreach (var linkworld in linkWorlds)
                            {
                                linkworld.Add(newLink);
                            }
                        }
                    }
                }

                foreach (var linkworld in linkWorlds)
                {
                    var newDecomp = decomp.Clone() as TimelineDecomposition;
                    newDecomp.discourseSubSteps = TD.discourseSubSteps;
                    newDecomp.discOrderings     = newDOrderings;
                    newDecomp.fabCntgs          = newFabCntgs;
                    newDecomp.discCntgs         = newDiscCntgs;
                    newDecomp.discLinks         = linkworld;

                    timelineDecompList.Add(newDecomp);
                }
            }

            return(timelineDecompList);
        }