Ejemplo n.º 1
0
        public void Filter()
        {
            var root = new Operator(new Predicate(gameObject.name, Terms, true)) as IOperator;

            PartialDecomp = new TimelineDecomposition(root, new List <IPredicate>(), cntgs, dcntgs, stepConstraints, dstepConstraints, SubSteps, DSubSteps, orderings, dorderings, links, dlinks, fabVarStepMap);
            var camOptions = new List <CamSchema>();

            if (CameraHost == null)
            {
                CameraHost = GameObject.FindGameObjectWithTag("Cameras");
            }
            for (int i = 0; i < CameraHost.transform.childCount; i++)
            {
                var cameraSchema = CameraHost.transform.GetChild(i).GetComponent <CamAttributesStruct>().AsSchema();
                camOptions.Add(cameraSchema);
            }
            if (LocationHost == null)
            {
                LocationHost = GameObject.FindGameObjectWithTag("LocationHost");
            }
            var locationMap = new Dictionary <string, Vector3>();

            for (int i = 0; i < LocationHost.transform.childCount; i++)
            {
                var locationObj = LocationHost.transform.GetChild(i);
                locationMap[locationObj.name] = locationObj.transform.position;
            }
            GroundDecomps    = TimelineDecompositionHelper.Compose(0, PartialDecomp, camOptions, locationMap);
            NumGroundDecomps = GroundDecomps.Count();
            // foreach cndt, create a child gameobject and create a playable director and a control track. for each action in
        }
Ejemplo n.º 2
0
        /// <summary>
        /// The compositeschedule has terms, preconditions, and effects.
        /// All preconditions and effects are expected to be ground because they are created based on the ground decomposition
        /// Thus, unlike the parent class, there is no need to propagate bindings to terms, preconditions, and effects.
        /// </summary>
        /// <param name="td"></param>
        public void ApplyDecomposition(TimelineDecomposition td)
        {
            subSteps     = td.SubSteps;
            subOrderings = td.SubOrderings;
            subLinks     = td.SubLinks;

            foreach (var substep in subSteps)
            {
                foreach (var term in substep.Terms)
                {
                    if (!td.Terms.Contains(term))
                    {
                        //var termAsPredicate = term as Predicate;
                        //if (termAsPredicate != null)
                        //{

                        //}
                        Terms.Add(term);
                    }
                }
            }

            Cntgs = td.fabCntgs;

            // The way things are done round here is just to group in discourse stuff with fabula stuff. We have two plans... but they can go in one plan.
            foreach (var camplanstep in td.discourseSubSteps)
            {
                SubSteps.Add(camplanstep as IPlanStep);
            }
            foreach (var dordering in td.discOrderings)
            {
                SubOrderings.Add(new Tuple <IPlanStep, IPlanStep>(dordering.First, dordering.Second));
            }
            foreach (var discCntg in td.discCntgs)
            {
                Cntgs.Add(new Tuple <IPlanStep, IPlanStep>(discCntg.First, discCntg.Second));
            }
            foreach (var dlink in td.discLinks)
            {
                SubLinks.Add(new CausalLink <IPlanStep>(dlink.Predicate, dlink.Head, dlink.Tail));
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// The Decomposition is composed of a sub-plan with at least sub-step at height "height"
        /// </summary>
        /// <returns>A list of decompositions with ground terms and where each sub-step is ground. </returns>
        public static List <TimelineDecomposition> Compose(int height, TimelineDecomposition TD, List <CamSchema> camOptions, Dictionary <string, Vector3> locationMap)
        {
            ///////////////////////////////////////
            // START BY ADDING BINDINGS TO TERMS //
            ///////////////////////////////////////
            var permList = new List <List <string> >();

            foreach (Term variable in TD.Terms)
            {
                permList.Add(GroundActionFactory.TypeDict[variable.Type] as List <string>);
            }

            var decompList = new List <TimelineDecomposition>();

            foreach (var combination in EnumerableExtension.GenerateCombinations(permList))
            {
                // Add bindings
                var decompClone        = TD.Clone() as TimelineDecomposition;
                var termStringList     = from term in decompClone.Terms select term.Variable;
                var constantStringList = combination;

                decompClone.AddBindings(termStringList.ToList(), constantStringList.ToList());

                /////////////////////////////////////////////////////////
                // PROPAGATE BINDINGS TO NONEQUALITY CONSTRAINTS
                /////////////////////////////////////////////////////////
                var newNonEqualities = new List <List <ITerm> >();
                if (TD.NonEqualities == null)
                {
                    TD.NonEqualities = new List <List <ITerm> >();
                }
                else
                {
                    foreach (var nonequals in TD.NonEqualities)
                    {
                        var newNonEquals = new List <ITerm>();
                        newNonEquals.Add(decompClone.Terms.First(dterm => dterm.Variable.Equals(nonequals[0].Variable)));
                        newNonEquals.Add(decompClone.Terms.First(dterm => dterm.Variable.Equals(nonequals[1].Variable)));
                        newNonEqualities.Add(newNonEquals);
                    }
                    decompClone.NonEqualities = newNonEqualities;

                    if (!decompClone.NonEqualTermsAreNonequal())
                    {
                        continue;
                    }
                }

                // zip to dict
                var varDict = EnumerableExtension.Zip(termStringList, constantStringList).ToDictionary(x => x.Key, x => x.Value);

                /////////////////////////////////////////////////////////
                // BINDINGS ARE ADDED. NEED TO APPLY BINDINGS TO SUBSTEPS
                /////////////////////////////////////////////////////////

                // Need to propagate bindings to sub-steps
                foreach (var substep in decompClone.SubSteps)
                {
                    var op = substep.Action as Operator;
                    foreach (var term in substep.Terms)
                    {
                        op.AddBinding(term.Variable, varDict[term.Variable]);
                    }
                    foreach (var precon in substep.Preconditions)
                    {
                        foreach (var term in precon.Terms)
                        {
                            if (!term.Bound)
                            {
                                var decompTerm = decompClone.Terms.First(dterm => dterm.Variable.Equals(term.Variable));
                                op.Terms.Add(term);
                                op.AddBinding(term.Variable, decompTerm.Constant);
                            }
                        }
                    }
                    foreach (var eff in substep.Effects)
                    {
                        foreach (var term in eff.Terms)
                        {
                            if (!term.Bound)
                            {
                                var decompTerm = decompClone.Terms.First(dterm => dterm.Variable.Equals(term.Variable));
                                op.Terms.Add(term);
                                op.AddBinding(term.Variable, decompTerm.Constant);
                            }
                        }
                    }
                }

                ////////////////////////////////////////////////////////////////
                // FILTER CANDIDATES FOR SUBSTEPS AND PASS BACK GROUNDED DECOMPS
                ////////////////////////////////////////////////////////////////

                // legacy for fabula subplan. returns a list of decomp packages, whose second member is a map from fabula substep IDs to substeps
                var fabulaGroundedDecompMap = TimelineDecomposition.FilterDecompCandidates(decompClone);

                // foreach decomposition including a mapping from fabula substep IDs to substeps
                foreach (Tuple <TimelineDecomposition, Dictionary <int, IPlanStep> > decompPackage in fabulaGroundedDecompMap)
                {
                    // get candidates and ground for camera steps
                    var newGroundDecomps = TimelineDecompositionHelper.FilterTimelineDecompCandidates(TD, decompPackage, height, camOptions, locationMap);

                    foreach (var gdecomp in newGroundDecomps)
                    {
                        // This function updates the mapping from action variable names to step-variables, and repoints mapping to grounded fabula substep. These names used by camera shots.
                        gdecomp.UpdateActionVarMap(decompPackage.Second);
                        // Add new ground decomposition to map.
                        decompList.Add(gdecomp);
                    }
                }
            }

            return(decompList);
        }
Ejemplo n.º 4
0
        // 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);
        }
Ejemplo n.º 5
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);
        }