/// <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))); 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); }