Ejemplo n.º 1
0
 bool resolveConflicts(CausalLink cl, Affordance act)
 {
     foreach (Condition effect in act.getEffects())
     {
         if (!(cl.act1.getActionInstance().Equals(act.getActionInstance())) &&
             !(cl.act2.getActionInstance().Equals(act.getActionInstance())) &&
             (effect.negation(cl.p)))
         {
             Debug.Log("resolveConflicts : ");
             act.disp();
             cl.disp();
             if (cl.act2.isGoal())
             {
                 constraints.Add(Tuple.New(act, cl.act1));
                 addToOrderingConstraints(act, cl.act1);
             }
             else if (!cl.act1.isStart())
             {
                 constraints.Add(Tuple.New(cl.act2, act));
                 addToOrderingConstraints(cl.act2, act);
             }
         }
     }
     return(true);
 }
Ejemplo n.º 2
0
        public static List <CausalLink <IPlanStep> > CausalLinksFromJsonArray(JsonArray jsoncausallinkslist)
        {
            var clinks = new List <CausalLink <IPlanStep> >();

            foreach (var jsonlink in jsoncausallinkslist)
            {
                var       clink = CausalLinkFromJsonArray(jsonlink as JsonArray);
                IPlanStep head;
                if (clink.Head.Height > 0)
                {
                    head = new CompositePlanStep(clink.Head as IComposite);
                }
                else
                {
                    head = new PlanStep(clink.Head as IOperator);
                }
                IPlanStep tail;
                if (clink.Tail.Height > 0)
                {
                    tail = new CompositePlanStep(clink.Tail as IComposite);
                }
                else
                {
                    tail = new PlanStep(clink.Tail as IOperator);
                }
                var newLink = new CausalLink <IPlanStep>(clink.Predicate, head, tail);
                clinks.Add(newLink);
            }
            return(clinks);
        }
Ejemplo n.º 3
0
        public bool computePlan(Affordance start, Affordance goal)
        {
            instantiatePlan(start, goal);
            do
            {
                Tuple <Condition, Affordance> subG = agenda.Pop();
                Affordance act;
                if (!preConditionAlreadySatisfied(subG, out act))
                {
                    if (checkActionsForPrecondition(subG, out act))
                    {
                        actions.Add(act);
                        constraints.Add(Tuple.New(start, act));
                        addToOrderingConstraints(start, act);
                        foreach (CausalLink cl in causalLinks)
                        {
                            resolveConflicts(cl, act);
                        }

                        foreach (Condition p in act.getPreconditions())
                        {
                            agenda.Push(Tuple.New(p, act));
                        }
                    }
                    else
                    {
                        Debug.LogError("Plan Failed for condition - ");
                        subG.First.disp();
                        showActions();
                        return(false);
                    }
                }

                constraints.Add(Tuple.New(act, subG.Second));
                addToOrderingConstraints(act, subG.Second);
                CausalLink cLink = new CausalLink(act, subG.First, subG.Second);
                causalLinks.Add(cLink);

                foreach (Affordance a in actions)
                {
                    if (!a.isStart())
                    {
                        resolveConflicts(cLink, a);
                    }
                }

                //Debug.Log("In While loop!!");
            } while (agenda.Count() != 0);

            constraints = Utils.Utils.removeDuplicateConstraints(constraints);
            Debug.LogError("Goal Reached!!");
            return(true);
        }
Ejemplo n.º 4
0
        public void RepairWithComposite(OpenCondition oc, CompositeSchedulePlanStep repairStep)
        {
            var needStep = Find(oc.step);

            if (!needStep.Name.Equals("DummyGoal") && !needStep.Name.Equals("DummyInit"))
            {
                needStep.Fulfill(oc.precondition);
            }

            // need to merge all steps that are being connected by this predicate:
            if (oc.precondition.Name.Equals("obs-starts"))
            {
                var       stepThatNeedsToBeMerged = oc.precondition.Terms[0];
                IPlanStep ReferencedStep1         = new PlanStep();
                IPlanStep ReferencedStep2         = new PlanStep();
                foreach (var step in Steps)
                {
                    if (step.Action.ID.ToString().Equals(stepThatNeedsToBeMerged))
                    {
                        if (repairStep.SubSteps.Contains(step))
                        {
                            ReferencedStep1 = step;
                        }

                        else
                        {
                            ReferencedStep2 = step;
                        }
                    }
                }
                if (ReferencedStep1.Name.Equals("") || ReferencedStep2.Name.Equals(""))
                {
                    Debug.Log("never found steps to merge");
                    throw new System.Exception();
                }
                if (ReferencedStep1.OpenConditions.Count > ReferencedStep2.OpenConditions.Count)
                {
                    MergeSteps(ReferencedStep1, ReferencedStep2);
                }
                else
                {
                    MergeSteps(ReferencedStep2, ReferencedStep1);
                }
            }

            orderings.Insert(repairStep.GoalStep as IPlanStep, needStep);
            var clink = new CausalLink <IPlanStep>(oc.precondition as Predicate, repairStep.GoalStep as IPlanStep, needStep);

            causalLinks.Add(clink);
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
0
 public CausalLinkTest()
 {
     testLink = new CausalLink();
 }
Ejemplo n.º 7
0
 public PlanSpaceEdge(Operator action, CausalLink clobberedLink, State state)
 {
     this.action        = action;
     this.clobberedLink = clobberedLink;
     this.state         = state;
 }
Ejemplo n.º 8
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.º 9
0
        public void InsertDecomp(CompositeSchedulePlanStep newStep)
        {
            var IDMap = new Dictionary <int, IPlanStep>();

            // Clone, Add, and Order Initial step
            var dummyInit = new PlanStep(newStep.InitialStep) as IPlanStep;

            dummyInit.InitCndt = newStep.InitialStep.InitCndt;

            dummyInit.Depth = newStep.Depth;
            IDMap[newStep.InitialStep.ID] = dummyInit;
            Steps.Add(dummyInit);
            Orderings.Insert(InitialStep, dummyInit);
            Orderings.Insert(dummyInit, GoalStep);


            // Clone, Add, and order Goal step
            var dummyGoal = new PlanStep(newStep.GoalStep) as IPlanStep;

            dummyGoal.Depth    = newStep.Depth;
            dummyGoal.InitCndt = dummyInit;
            dummyGoal.GoalCndt = newStep.GoalStep.GoalCndt;
            InsertPrimitiveSubstep(dummyGoal, dummyInit.Effects, true);
            IDMap[newStep.GoalStep.ID] = dummyGoal;
            Orderings.Insert(dummyInit, dummyGoal);

            dummyInit.GoalCndt = dummyGoal;

            //this.ID += "([" + dummyInit.ID.ToString() + ',' + dummyGoal.ID.ToString() + "])";


            // needs same operator ID as newStep, in order to still be referenced for primary-effect-based open conditions
            //var newStepCopy = new CompositeSchedulePlanStep(new Operator(newStep.Action.Predicate.Name, newStep.Action.Terms, new Hashtable(), new List<IPredicate>(), new List<IPredicate>(), newStep.Action.ID));
            Steps.Add(newStep);

            //newStepCopy.Height = newStep.Height;
            //newStepCopy.Depth = newStep.Depth;
            var newSubSteps = new List <IPlanStep>();

            newStep.Preconditions = new List <IPredicate>();
            newStep.Effects       = new List <IPredicate>();

            newStep.InitialStep = dummyInit;
            newStep.GoalStep    = dummyGoal;

            DeLinks.Insert(newStep, dummyGoal);
            DeLinks.Insert(newStep, dummyInit);

            //newStepCopy.InitialStep = dummyInit;
            //newStepCopy.GoalStep = dummyGoal;

            var newCamPlanSteps = new List <CamPlanStep>();

            foreach (var substep in newStep.SubSteps)
            {
                // substep is either a IPlanStep or ICompositePlanStep
                if (substep.Height > 0)
                {
                    var compositeSubStep = new CompositeSchedulePlanStep(substep.Clone() as CompositeSchedulePlanStep)
                    {
                        Depth = newStep.Depth + 1
                    };

                    // Avoid the following issue: compositeSubStep's initial and goal step will be reassigned its ID AFTER it is inserted; thus, insert first
                    newSubSteps.Add(compositeSubStep);
                    DeLinks.Insert(newStep, compositeSubStep);
                    Insert(compositeSubStep);

                    Orderings.Insert(compositeSubStep.GoalStep, dummyGoal);
                    Orderings.Insert(dummyInit, compositeSubStep.InitialStep);

                    //this.ID += "(^Oss[" + compositeSubStep.GoalStep.ID.ToString() + ',' + dummyGoal.ID.ToString() + "])";
                    //   this.ID += "(^Oss[" + dummyInit.ID.ToString() + ',' + compositeSubStep.InitialStep.ID.ToString() + "])";

                    IDMap[substep.ID] = compositeSubStep;

                    // The initial step of the sub-step looks to this local-subplan's dummy init as it's init cndt
                    compositeSubStep.InitialStep.InitCndt = dummyInit;
                    // The goal step of the sub-step looks to this local sub-plan's dummy goal step as it's goal candidate
                    compositeSubStep.GoalStep.GoalCndt = dummyGoal;
                }
                else
                {
                    IPlanStep newsubstep;
                    // new substep is either CamPlanStep or PlanStep
                    if (substep is CamPlanStep cps)
                    {
                        newsubstep = new CamPlanStep(cps)
                        {
                            Depth = newStep.Depth + 1
                        };
                        newCamPlanSteps.Add(newsubstep as CamPlanStep);
                    }
                    else
                    {
                        newsubstep = new PlanStep(substep.Clone() as IPlanStep)
                        {
                            Depth = newStep.Depth + 1
                        };
                    }

                    Orderings.Insert(newsubstep, dummyGoal);
                    Orderings.Insert(dummyInit, newsubstep);
                    IDMap[substep.ID] = newsubstep;
                    newSubSteps.Add(newsubstep);
                    newsubstep.InitCndt = dummyInit;
                    newsubstep.GoalCndt = dummyGoal;
                    //newsubstep.Parent = newStep;
                    DeLinks.Insert(newStep, newsubstep);

                    InsertPrimitiveSubstep(newsubstep, dummyInit.Effects, false);

                    // Pre-Mod
                    //if (newsubstep.Depth > Hdepth)
                    //{
                    //    Hdepth = newsubstep.Depth;
                    //}
                }
            }

            newStep.InitialAction = IDMap[newStep.InitialAction.ID];
            if (newStep.InitialAction is CompositeSchedulePlanStep cspsNewStep)
            {
                newStep.InitialCamAction = cspsNewStep.InitialCamAction;
            }
            else
            {
                newStep.InitialCamAction = IDMap[newStep.InitialCamAction.ID] as CamPlanStep;
            }

            newStep.FinalAction = IDMap[newStep.FinalAction.ID];

            if (newStep.FinalAction is CompositeSchedulePlanStep cspsNewStepf)
            {
                newStep.FinalCamAction = cspsNewStepf.FinalCamAction;
            }
            else
            {
                newStep.FinalCamAction = IDMap[newStep.FinalCamAction.ID] as CamPlanStep;
            }

            // update action seg targets
            foreach (var cps in newCamPlanSteps)
            {
                cps.UpdateActionSegs(IDMap);
            }

            //foreach (var precon in newStep.ContextPrecons)
            //{
            //    // these precons MUST be referencing a local sub-step; or else, they reference a precondition or effect of a sub-step.
            //    precon.ActionRef = IDMap[precon.ActionRef.ID];
            //}
            //foreach (var eff in newStep.ContextEffects)
            //{
            //    eff.ActionRef = IDMap[eff.ActionRef.ID];
            //}

            //foreach(var precon in )

            foreach (var tupleOrdering in newStep.SubOrderings)
            {
                // Don't bother adding orderings to dummies
                if (tupleOrdering.First.Equals(newStep.InitialStep))
                {
                    continue;
                }
                if (tupleOrdering.Second.Equals(newStep.GoalStep))
                {
                    continue;
                }

                var head = IDMap[tupleOrdering.First.ID];
                var tail = IDMap[tupleOrdering.Second.ID];
                if (head.Height > 0)
                {
                    // can you pass it back?
                    var temp = head as CompositeSchedulePlanStep;
                    head = temp.GoalStep as IPlanStep;
                }
                if (tail.Height > 0)
                {
                    var temp = tail as CompositeSchedulePlanStep;
                    tail = temp.InitialStep as IPlanStep;
                }
                //this.ID += string.Format("(^Oso[{0},{1}])", head.ID, tail.ID);
                Orderings.Insert(head, tail);
            }

            // in this world, all composite plan steps are composite schedule plan steps.
            var schedulingStepComponent = newStep as CompositeSchedulePlanStep;

            foreach (var cntg in schedulingStepComponent.Cntgs)
            {
                var head = IDMap[cntg.First.ID];
                var tail = IDMap[cntg.Second.ID];
                if (head.Height > 0)
                {
                    // how do we describe a composite as being contiguous with another step?
                    var temp = head as CompositeSchedulePlanStep;
                    //var fas = temp.FinalActionSeg;
                    if (tail is CamPlanStep cps)
                    {
                        // then get final discourse step of temp // This is a HACK - because the last camera substep may be on a grandchild
                        head = temp.FinalCamAction as IPlanStep;
                    }
                    else
                    {
                        // then get the action referenced by the final action segment - already updated actionID and is already in plan.
                        head = temp.FinalAction;
                    }
                }
                if (tail.Height > 0)
                {
                    var temp = tail as CompositeSchedulePlanStep;
                    if (head is CamPlanStep cps)
                    {
                        // then get first discourse step of temp // This is a HACK - because the first camera substep may be on a grandchild
                        tail = temp.InitialCamAction;
                    }
                    else
                    {
                        tail = temp.InitialAction;
                    }
                }
                Cntgs.Insert(head, tail);
                // also add orderings just in case
                Orderings.Insert(head, tail);
                // this.ID += string.Format("(^Osc[{0},{1}])", head.ID, tail.ID);
            }

            foreach (var clink in newStep.SubLinks)
            {
                var head = IDMap[clink.Head.ID];
                var tail = IDMap[clink.Tail.ID];


                if (head.Height > 0)
                {
                    var temp = head as CompositeSchedulePlanStep;
                    head = temp.GoalStep as IPlanStep;
                }
                if (tail.Height > 0)
                {
                    var temp = tail as CompositeSchedulePlanStep;
                    tail = temp.InitialStep as IPlanStep;
                }

                var newclink = new CausalLink <IPlanStep>(clink.Predicate, head, tail);
                CausalLinks.Add(newclink);
                Orderings.Insert(head, tail);
                //this.ID += string.Format("(^Osl[{0},{1}])", head.ID, tail.ID);

                // check if this causal links is threatened by a step in subplan
                foreach (var step in newSubSteps)
                {
                    // Prerequisite criteria 1
                    if (step.ID == head.ID || step.ID == tail.ID)
                    {
                        continue;
                    }

                    // Prerequisite criteria 2
                    if (!CacheMaps.IsThreat(clink.Predicate, step))
                    {
                        continue;
                    }

                    // If the step has height, need to evaluate differently
                    if (step.Height > 0)
                    {
                        var temp = step as ICompositePlanStep;
                        if (Orderings.IsPath(head, temp.InitialStep))
                        {
                            continue;
                        }
                        if (Orderings.IsPath(temp.GoalStep, tail))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (Orderings.IsPath(head, step))
                        {
                            continue;
                        }
                        if (Orderings.IsPath(step, tail))
                        {
                            continue;
                        }
                    }

                    Flaws.Add(new ThreatenedLinkFlaw(newclink, step));
                    //if (step.Height > 0)
                    //{
                    //    // Then we need to dig deeper to find the step that threatens
                    //    DecomposeThreat(clink, step as ICompositePlanStep);
                    //}
                    //else
                    //{
                    //    Flaws.Add(new ThreatenedLinkFlaw(newclink, step));
                    //}
                }
            }


            // This is needed because we'll check if these substeps are threatening links
            newStep.SubSteps = newSubSteps;
            //newStepCopy.SubSteps = newSubSteps;
            // inital


            newStep.InitialStep = dummyInit;

            // goal

            newStep.GoalStep = dummyGoal;

            foreach (var pre in newStep.OpenConditions)
            {
                Flaws.Add(this, new OpenCondition(pre, dummyInit as IPlanStep));
            }
        }
Ejemplo n.º 10
0
 public MediationEdge()
 {
     action        = new Operator();
     clobberedLink = new CausalLink();
     state         = new State();
 }
Ejemplo n.º 11
0
        public void RepairWithComposite(OpenCondition oc, CompositeSchedulePlanStep repairStep)
        {
            var needStep = Find(oc.step);

            if (!needStep.Name.Equals("DummyGoal") && !needStep.Name.Equals("DummyInit"))
            {
                needStep.Fulfill(oc.precondition);
            }


            // need to merge all steps that are being connected by this predicate:
            if (oc.precondition.Name.Equals("obs-starts"))
            //if (oc.precondition is ContextPredicate cxtp)
            {
                this.ID += "s";
                //var repairEff = repairStep.Effects.Where(e => cxtp.Equals(oc.precondition)).First() ;
                RepairWithMerge(oc.precondition, needStep, repairStep);
                var otherflawsFromSameNeedStep = this.flaws.OpenConditions.Where(openC => openC.step.ID == oc.step.ID).ToList();
                foreach (var otherFlaw in otherflawsFromSameNeedStep)
                {
                    if (CacheMaps.IsCndt(otherFlaw.precondition, repairStep))
                    {
                        // Remove this flaw, because it would have been satisfied by this repair step. SHOULD produce new plan for each decision.
                        this.flaws.OpenConditions.Remove(otherFlaw);
                    }
                }
                return;
            }
            //if (oc.precondition.Name.Equals("obs-starts"))
            //{
            //    Console.WriteLine("obs-starts");

            //}

            orderings.Insert(repairStep.GoalStep as IPlanStep, needStep);
            //this.ID += string.Format("(^Orl[{0},{1}])", repairStep.GoalStep.ID, needStep.ID);

            var clink = new CausalLink <IPlanStep>(oc.precondition as Predicate, repairStep.GoalStep as IPlanStep, needStep);

            causalLinks.Add(clink);


            foreach (var step in Steps)
            {
                if (step.ID == repairStep.ID || step.ID == needStep.ID)
                {
                    continue;
                }
                if (!CacheMaps.IsThreat(oc.precondition, step))
                {
                    continue;
                }

                if (step.Height > 0)
                {
                    // we need to check that this step's goal step
                    var stepAsComp = step as CompositeSchedulePlanStep;


                    if (DeLinks.OnDecompPath(clink.Head, step.ID))
                    {
                        // must be ordered within
                        if (Orderings.IsPath(clink.Tail, stepAsComp.GoalStep))
                        {
                            // already tucked into Q's borders
                            continue;
                        }

                        if (!DeLinks.OnDecompPath(clink.Tail, step.ID))
                        {
                            // Special Case is when clink.Tail is goal step. Then we cannot tuck clink.Tail into borders.
                            if (clink.Tail.Equals(goalStep))
                            {
                                // We want to end this plan's existence, so we add a threat that cannot be resolved.
                                Flaws.Add(new ThreatenedLinkFlaw(clink, step));
                                continue;
                            }
                            // Q --> s -p-> t, not p in eff(Q), not Q --> t
                            // then, need to tuck t into Q's borders.

                            var tailRoot = GetStepByID(DeLinks.GetRoot(clink.Tail)) as CompositePlanStep;
                            Orderings.Insert(tailRoot.GoalStep, stepAsComp.InitialStep);
                            //this.ID += string.Format("(^Od[{0},{1}])", tailRoot.GoalStep.ID, stepAsComp.InitialStep.ID);
                        }

                        continue;
                    }

                    if (DeLinks.OnDecompPath(clink.Tail, step.ID))
                    {
                        // step cannot threaten
                        continue;
                    }


                    // step is a threat to need precondition
                    if (Orderings.IsPath(clink.Tail, stepAsComp.InitialStep))
                    {
                        continue;
                    }
                    if (Orderings.IsPath(stepAsComp.GoalStep, repairStep.InitialStep as IPlanStep))
                    {
                        continue;
                    }


                    Flaws.Add(new ThreatenedLinkFlaw(clink, stepAsComp));
                    // Flaws.Add(new ThreatenedLinkFlaw(clink, compInit));
                }

                else
                {
                    // is it possible that step is a sub-step of repair step? Yes it is.
                    if (DeLinks.OnDecompPath(step, repairStep.ID))
                    {
                        // but, there's nothing we can do about it; and all links to repairStep.GoalStep are there to be threatened
                        continue;
                    }

                    // step is a threat to need precondition
                    if (Orderings.IsPath(needStep, step))
                    {
                        continue;
                    }
                    if (Orderings.IsPath(step, repairStep.InitialStep as IPlanStep))
                    {
                        continue;
                    }

                    Flaws.Add(new ThreatenedLinkFlaw(clink, step));
                }
            }
        }
Ejemplo n.º 12
0
 public StateSpaceEdge()
 {
     action        = new Operator();
     actionType    = new ActionType();
     clobberedLink = new CausalLink <IPlanStep>();
 }
Ejemplo n.º 13
0
        public void InsertDecomp(CompositeSchedulePlanStep newStep)
        {
            Decomps += 1;
            var IDMap = new Dictionary <int, IPlanStep>();

            // Clone, Add, and Order Initial step
            var dummyInit = newStep.InitialStep.Clone() as IPlanStep;

            dummyInit.Depth = newStep.Depth;
            IDMap[newStep.InitialStep.ID] = dummyInit;
            Steps.Add(dummyInit);
            Orderings.Insert(InitialStep, dummyInit);
            Orderings.Insert(dummyInit, GoalStep);

            // Clone, Add, and order Goal step
            var dummyGoal = newStep.GoalStep.Clone() as IPlanStep;

            dummyGoal.Depth    = newStep.Depth;
            dummyGoal.InitCndt = dummyInit;
            InsertPrimitiveSubstep(dummyGoal, dummyInit.Effects, true);
            IDMap[newStep.GoalStep.ID] = dummyGoal;
            Orderings.Insert(dummyInit, dummyGoal);


            var newStepCopy = new PlanStep(new Operator(newStep.Action.Predicate as Predicate, new List <IPredicate>(), new List <IPredicate>()));

            Steps.Add(newStepCopy);
            //  orderings.Insert(dummyInit, newStepCopy);
            //  orderings.Insert(newStepCopy, dummyGoal);
            newStepCopy.Height = newStep.Height;
            var newSubSteps = new List <IPlanStep>();

            foreach (var substep in newStep.SubSteps)
            {
                // substep is either a IPlanStep or ICompositePlanStep
                if (substep.Height > 0)
                {
                    var compositeSubStep = new CompositeSchedulePlanStep(substep.Clone() as IPlanStep)
                    {
                        Depth = newStep.Depth + 1
                    };

                    Orderings.Insert(compositeSubStep.GoalStep, dummyGoal);
                    Orderings.Insert(dummyInit, compositeSubStep.InitialStep);
                    IDMap[substep.ID] = compositeSubStep;
                    compositeSubStep.InitialStep.InitCndt = dummyInit;
                    newSubSteps.Add(compositeSubStep);
                    Insert(compositeSubStep);
                    // Don't bother updating hdepth yet because we will check on recursion
                }
                else
                {
                    var newsubstep = new PlanStep(substep.Clone() as IPlanStep)
                    {
                        Depth = newStep.Depth + 1
                    };
                    Orderings.Insert(newsubstep, dummyGoal);
                    Orderings.Insert(dummyInit, newsubstep);
                    IDMap[substep.ID] = newsubstep;
                    newSubSteps.Add(newsubstep);
                    newsubstep.InitCndt = dummyInit;
                    InsertPrimitiveSubstep(newsubstep, dummyInit.Effects, false);

                    if (newsubstep.Depth > Hdepth)
                    {
                        Hdepth = newsubstep.Depth;
                    }
                }
            }

            foreach (var tupleOrdering in newStep.SubOrderings)
            {
                // Don't bother adding orderings to dummies
                if (tupleOrdering.First.Equals(newStep.InitialStep))
                {
                    continue;
                }
                if (tupleOrdering.Second.Equals(newStep.GoalStep))
                {
                    continue;
                }

                var head = IDMap[tupleOrdering.First.ID];
                var tail = IDMap[tupleOrdering.Second.ID];
                if (head.Height > 0)
                {
                    // can you pass it back?
                    var temp = head as ICompositePlanStep;
                    head = temp.GoalStep as IPlanStep;
                }
                if (tail.Height > 0)
                {
                    var temp = tail as ICompositePlanStep;
                    tail = temp.InitialStep as IPlanStep;
                }
                Orderings.Insert(head, tail);
            }

            // in this world, all composite plan steps are composite schedule plan steps.
            var schedulingStepComponent = newStep as CompositeSchedulePlanStep;

            foreach (var cntg in schedulingStepComponent.Cntgs)
            {
                var head = IDMap[cntg.First.ID];
                var tail = IDMap[cntg.Second.ID];
                if (head.Height > 0)
                {
                    // how do we describe a composite as being contiguous with another step?
                    var temp = head as ICompositePlanStep;
                    head = temp.GoalStep as IPlanStep;
                }
                if (tail.Height > 0)
                {
                    var temp = tail as ICompositePlanStep;
                    tail = temp.InitialStep as IPlanStep;
                }
                Cntgs.Insert(head, tail);
                // also add orderings just in case
                Orderings.Insert(head, tail);
            }

            foreach (var clink in newStep.SubLinks)
            {
                var head = IDMap[clink.Head.ID];
                var tail = IDMap[clink.Tail.ID];
                if (head.Height > 0)
                {
                    var temp = head as CompositePlanStep;
                    head = temp.GoalStep as IPlanStep;
                }
                if (tail.Height > 0)
                {
                    var temp = tail as CompositePlanStep;
                    tail = temp.InitialStep as IPlanStep;
                }

                var newclink = new CausalLink <IPlanStep>(clink.Predicate, head, tail);
                CausalLinks.Add(newclink);
                Orderings.Insert(head, tail);

                // check if this causal links is threatened by a step in subplan
                foreach (var step in newSubSteps)
                {
                    // Prerequisite criteria 1
                    if (step.ID == head.ID || step.ID == tail.ID)
                    {
                        continue;
                    }

                    // Prerequisite criteria 2
                    if (!CacheMaps.IsThreat(clink.Predicate, step))
                    {
                        continue;
                    }

                    // If the step has height, need to evaluate differently
                    if (step.Height > 0)
                    {
                        var temp = step as ICompositePlanStep;
                        if (Orderings.IsPath(head, temp.InitialStep))
                        {
                            continue;
                        }
                        if (Orderings.IsPath(temp.GoalStep, tail))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (Orderings.IsPath(head, step))
                        {
                            continue;
                        }
                        if (Orderings.IsPath(step, tail))
                        {
                            continue;
                        }
                    }

                    if (step.Height > 0)
                    {
                        // Then we need to dig deeper to find the step that threatens
                        DecomposeThreat(clink, step as ICompositePlanStep);
                    }
                    else
                    {
                        Flaws.Add(new ThreatenedLinkFlaw(newclink, step));
                    }
                }
            }


            // This is needed because we'll check if these substeps are threatening links
            newStep.SubSteps    = newSubSteps;
            newStep.InitialStep = dummyInit;
            newStep.GoalStep    = dummyGoal;

            foreach (var pre in newStep.OpenConditions)
            {
                Flaws.Add(this, new OpenCondition(pre, dummyInit as IPlanStep));
            }
        }
Ejemplo n.º 14
0
        public void Assemble()
        {
            SubSteps  = new List <IPlanStep>();
            DSubSteps = new List <CamPlanStep>();

            // Collect step-typed variables
            fabClipStepMap  = new Dictionary <ClipSchema <FabulaAsset>, PlanStep>();
            discClipStepMap = new Dictionary <ClipSchema <DiscourseAsset>, CamPlanStep>();

            // used to identify references of constraints
            fabVarStepMap  = new Dictionary <string, PlanStep>();
            discVarStepMap = new Dictionary <string, CamPlanStep>();

            // if there's a gap, then it's a "before" relation
            orderings  = new List <Tuple <IPlanStep, IPlanStep> >();
            dorderings = new List <Tuple <CamPlanStep, CamPlanStep> >();

            // if the clip is contiguous with the last one, then it's "cntg"
            cntgs  = new List <Tuple <IPlanStep, IPlanStep> >();
            dcntgs = new List <Tuple <CamPlanStep, CamPlanStep> >();

            // keep a map of literals based on names so that one can assign precondition and effects; specified in global constraints, only used for causal links locally
            var literalMap = new Dictionary <string, IPredicate>();

            // collect links specified in constraints
            links  = new List <CausalLink <IPlanStep> >();
            dlinks = new List <CausalLink <CamPlanStep> >();

            // constraints that are stored between shots or between actions, each a tuple
            stepConstraints  = new List <Tuple <string, Tuple <PlanStep, PlanStep> > >();
            dstepConstraints = new List <Tuple <string, Tuple <CamPlanStep, CamPlanStep> > >();

            // keeping track of last clip to determine ordering and cntg relations with last.
            // TODO: support multiple fabula timelines
            ClipSchema <FabulaAsset> last = fabulaClips[0];
            var visitedVariables          = new List <string>();

            for (int i = 0; i < fabulaClips.Count; i++)
            {
                var fabClip = fabulaClips[i];

                // read the step variable from the asset
                var planStep = ReadStepVariable(fabClip);

                // Add terms to decomp terms
                foreach (var term in planStep.Terms)
                {
                    if (visitedVariables.Contains(term.Variable))
                    {
                        term.Variable = term.Variable + planStep.GetHashCode().ToString();
                    }
                    visitedVariables.Add(term.Variable);
                    Terms.Add(term);
                }

                SubSteps.Add(planStep);

                // now check against the last item in there for timing.
                if (i > 0)
                {
                    var lastItemEndTime = last.start + last.duration;
                    if (fabClip.start - lastItemEndTime < 0.3)
                    {
                        // these are cntg
                        var newCntg = new Tuple <IPlanStep, IPlanStep>(fabClipStepMap[last], planStep);
                        cntgs.Add(newCntg);
                    }
                    else if (fabClip.start - lastItemEndTime >= 0.3)
                    {
                        // what's the maximum amount of space that can go into here? This is calculated by looking at specific action.
                        var ordering = new Tuple <IPlanStep, IPlanStep>(fabClipStepMap[last], planStep);
                        orderings.Add(ordering);
                    }
                }
                last = fabClip;
                fabClipStepMap.Add(fabClip, planStep);
                fabVarStepMap.Add(fabClip.display, planStep);
            }
            // ... including camera-step variables
            ClipSchema <DiscourseAsset> dlast = discourseClips[0];

            for (int i = 0; i < discourseClips.Count; i++)
            //foreach (var discClip in discourseClips)
            {
                var discClip = discourseClips[i];
                var camstep  = ReadCamStepVariable(discClip);

                DSubSteps.Add(camstep);

                /// Thus, the camera plan shot cannot itself hold a fixed duration as a term as input (though a maximum default would be practical).
                /// Precisely what is needed are those details related to global constraints...
                /// The benefit of breaking them up is that it's clear that a new camera shot can be inserted between them with a new action segment.
                discClipStepMap[discClip]        = camstep;
                discVarStepMap[discClip.display] = camstep;

                if (i > 0)
                {
                    var lastItemEndTime = dlast.start + dlast.duration;
                    if (discClip.start - lastItemEndTime < 0.3)
                    {
                        // these are cntg
                        var newCntg = new Tuple <CamPlanStep, CamPlanStep>(discClipStepMap[dlast], camstep);
                        dcntgs.Add(newCntg);
                    }
                    else if (discClip.start - lastItemEndTime >= 0.3)
                    {
                        // what's the maximum amount of space that can go into here? This is calculated by looking at specific action.
                        var ordering = new Tuple <CamPlanStep, CamPlanStep>(discClipStepMap[dlast], camstep);
                        dorderings.Add(ordering);
                    }
                }

                dlast = discClip;
            }

            // iterate through global constraints
            foreach (var constraintClipSchema in globalConstraints)
            {
                var constraints = constraintClipSchema.asset.Constraints;
                foreach (var constraint in constraints)
                {
                    var constraintParts = constraint.Split(' ');

                    if (constraintParts[0].Equals("="))
                    {
                        // this could mean that 2 variables are equal, or that a new constant is to be declared that has the name and terms
                    }

                    if (constraintParts[0].Equals("hangle"))
                    {
                        // hangle shot1 (between value1 value2) [[[[ this should be on single shot]]]]
                        // hangle shot1 (reverse shot2)
                        if (constraintParts[2].Equals("reverse"))
                        {
                            // do something
                        }
                        // hangle shot1 (differ 90 shot2)
                        if (constraintParts[2].Equals("differ"))
                        {
                            // do something
                        }
                    }

                    if (constraintParts[0].Equals("orient"))
                    {
                        // orient action1 reverse action2
                        if (constraintParts[2].Equals("reverse"))
                        {
                            var planstepTuple       = new Tuple <PlanStep, PlanStep>(fabVarStepMap[constraintParts[1]], fabVarStepMap[constraintParts[3]]);
                            var stepConstraintTuple = new Tuple <string, Tuple <PlanStep, PlanStep> >("orient reverse", planstepTuple);
                            stepConstraints.Add(stepConstraintTuple);
                        }
                        // orient action1 = action2
                        if (constraintParts[2].Equals("="))
                        {
                            var planstepTuple       = new Tuple <PlanStep, PlanStep>(fabVarStepMap[constraintParts[1]], fabVarStepMap[constraintParts[3]]);
                            var stepConstraintTuple = new Tuple <string, Tuple <PlanStep, PlanStep> >("orient =", planstepTuple);
                            stepConstraints.Add(stepConstraintTuple);
                        }
                    }

                    // user to define a literal as variable -- essentially only used for causal link dependencies
                    if (constraintParts[0].Equals("literal"))
                    {
                        // literal literalAsVariableName predicatename, term_0, term_1...., term_k
                        // indicates declaration of literal
                        var predicate = ProcessPredicateString(constraintParts.Skip(1).ToArray());
                    }

                    // if constraints[0] is some kind of ordering constraint that's different from those
                    if (constraintParts[0].Equals("linked") || constraintParts[0].Equals("link") || constraintParts[0].Equals("linked-by"))
                    {
                        int sourceNum  = 1;
                        var dependency = new Predicate() as IPredicate;
                        if (constraintParts.Count() == 4)
                        {
                            // linked dependencyCondition sourceStepname sinkStepName
                            // 0      1                   2              3
                            dependency = literalMap[constraintParts[1]];
                            sourceNum += 1;
                        }

                        // find the planstep based on the step-variable name
                        var source = fabVarStepMap[constraintParts[sourceNum]];
                        var sink   = fabVarStepMap[constraintParts[sourceNum + 1]];
                        var cl     = new CausalLink <IPlanStep>(dependency, source, sink);
                        links.Add(cl);
                    }
                }
            }
            /// next we have to filter the schemas based on actual candidates. for steps that's groundActions, and for cams that's gameObjects with the camAttributeStruct
            /// then, we filter based on global constraints
        }
Ejemplo n.º 15
0
 public PlanSpaceEdge()
 {
     action        = new Operator();
     clobberedLink = new CausalLink();
     state         = new State();
 }
Ejemplo n.º 16
0
 public LinkedBy(IPlanStep s, IPlanStep t, IPredicate p)
 {
     thisConstraint = new CausalLink <IPlanStep>(p, s, t);
 }
Ejemplo n.º 17
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);
        }