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. try { var path = this.pathfinder.FindPath( ForwardNode.MakeRegularNode(initialWorldState, new ForwardNodeExpander(availableActions)), ForwardNode.MakeGoalNode(goal) ); // FIXME: Downcasting to ForwardEdge - may be fixed by adding another generic parameter to IPathfinder. return(new Plan(from edge in path.Edges select((ForwardEdge)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); try { var path = pathfinder.FindPath( ForwardNode.MakeRegularNode(initialWorldState, new ForwardNodeExpander(allActions)), ForwardNode.MakeGoalNode(goal) ); if (learning) { var beforeLearning = timer.ElapsedSeconds; Learn(path); UnityEngine.Debug.Log( $"Learning time: {timer.ElapsedSeconds-beforeLearning}"); } return(new Plan(from edge in path.Edges select((ForwardEdge)edge).Action, goal)); } catch (PathNotFoundException e) { throw new PlanNotFoundException(this, maxPlanLength, goal, e); } }