public Plan FormulatePlan( IKnowledgeProvider knowledgeProvider, IEnumerable <PlanningAction> availableActions, Goal goal ) { // TODO: Ideally, world state should be populated lazily, not in advance, like here. // Some symbols may not be needed at all to build a plan! // (also see comments on IPrecondition and IEffect RelevantActions property) var initialWorldState = new RelevantSymbolsPopulator(availableActions, goal) .PopulateWorldState(knowledgeProvider); // TODO: After lazy population is implemented, the following part of the method is the only thing // that must remain. var goalConstraints = new RegressiveStatePopulator().Populate(goal); try { var path = this.pathfinder.FindPath( RegressiveNode.MakeRegular( goalConstraints, initialWorldState, new RegressiveNodeExpander(availableActions) ), RegressiveNode.MakeTarget(initialWorldState) ); // UnityEngine.Debug.Log("Regressive path:"); // for(int i = 0; i < path.Edges.Count(); i++) // { // if(i == 0) // { // UnityEngine.Debug.LogFormat("Initial: {0}", path.Edges.ElementAt(i).SourceNode); // } // UnityEngine.Debug.LogFormat("After {0}: {1}", ((RegressiveEdge)path.Edges.ElementAt(i)).Action.Name, path.Edges.ElementAt(i).TargetNode); // // if(i > 0) // { // DebugUtils.Assert(path.Edges.ElementAt(i - 1).TargetNode == path.Edges.ElementAt(i).SourceNode, "path must be consistent"); // } // } // FIXME: Downcasting to RegressiveNode - may be fixed by adding another generic parameter to IPathfinder. //return new Plan(SortActions(from edge in path.Edges.Reverse() select ((RegressiveEdge)edge).Action, initialWorldState)); return(new Plan(from edge in path.Edges.Reverse() select((RegressiveEdge)edge).Action, goal)); } catch (PathNotFoundException e) { throw new PlanNotFoundException(this, maxPlanLength, goal, e); } }
public Plan FormulatePlan( IKnowledgeProvider knowledgeProvider, HashSet <PlanningAction> availableActions, Goal goal ) { var timer = new StopwatchExecutionTimer(); var allActions = new HashSet <PlanningAction>(); allActions.UnionWith(availableActions); allActions.UnionWith(experienceActions.Where(experienceAction => availableActions.IsSupersetOf(experienceAction.Actions))); var initialWorldState = new RelevantSymbolsPopulator(allActions, goal) .PopulateWorldState(knowledgeProvider); var goalConstraints = new RegressiveStatePopulator().Populate(goal); try { var path = pathfinder.FindPath( RegressiveNode.MakeRegular( goalConstraints, initialWorldState, new RegressiveNodeExpander(allActions) ), RegressiveNode.MakeTarget(initialWorldState) ); if (learning) { var beforeLearning = timer.ElapsedSeconds; Learn(path, initialWorldState); UnityEngine.Debug.Log( $"Learning time: {timer.ElapsedSeconds-beforeLearning}"); } return(new Plan(from edge in path.Edges.Reverse() select((RegressiveEdge)edge).Action, goal)); } catch (PathNotFoundException e) { throw new PlanNotFoundException(this, maxPlanLength, goal, e); } }