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); }
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); }
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); }
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); }
/// <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); }
public CausalLinkTest() { testLink = new CausalLink(); }
public PlanSpaceEdge(Operator action, CausalLink clobberedLink, State state) { this.action = action; this.clobberedLink = clobberedLink; this.state = state; }
// 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); }
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)); } }
public MediationEdge() { action = new Operator(); clobberedLink = new CausalLink(); state = new State(); }
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)); } } }
public StateSpaceEdge() { action = new Operator(); actionType = new ActionType(); clobberedLink = new CausalLink <IPlanStep>(); }
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)); } }
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 }
public PlanSpaceEdge() { action = new Operator(); clobberedLink = new CausalLink(); state = new State(); }
public LinkedBy(IPlanStep s, IPlanStep t, IPredicate p) { thisConstraint = new CausalLink <IPlanStep>(p, s, t); }
/// <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); }