lib/sfplanner/planner.rb in sfplanner-0.1.2 vs lib/sfplanner/planner.rb in sfplanner-0.1.3

- old
+ new

@@ -37,10 +37,11 @@ # @param :sas_plan : if true then return a raw SAS plan # @param :parallel : if true then return a parallel (partial-order) plan, # if false or nil then return a sequential plan # @param :json : if true then return the plan in JSON # @param :pretty_json : if true then return in pretty JSON + # @param :bsig : if true then return the solution plan as a BSig model # def solve(params={}) if params[:string].is_a?(String) @parser.parse(string) elsif params[:sfp].is_a?(Hash) @@ -73,10 +74,11 @@ # def to_bsig(params={}) raise Exception, "Conformant task is not supported yet" if @parser.conformant bsig = (params[:parallel] ? self.to_parallel_bsig : self.to_sequential_bsig) + return (params[:json] ? JSON.generate(bsig) : (params[:pretty_json] ? JSON.pretty_generate(bsig) : bsig)) end # @param :json : if true then return in JSON @@ -105,11 +107,12 @@ sfp_task.accept(Sfp::Visitor::ParentEliminator.new) File.open('/tmp/planning.json', 'w') { |f| f.write(JSON.pretty_generate(sfp_task)) } end def solve_conformant_task(params={}) - # TODO + raise Exception, "Conformant task is not supported yet" if params[:bsig] + # 1) generate all possible initial states # remove states that do not satisfy the global constraint def get_possible_partial_initial_states(init) def combinators(variables, var_values, index=0, result={}, bucket=[]) if index >= variables.length @@ -169,53 +172,78 @@ def solve_classical_task(params={}) @plan, @sas_task = self.solve_sas(@parser, params) return @plan if params[:sas_plan] + return to_bsig(params) if params[:bsig] + plan = (params[:parallel] ? self.get_parallel_plan : self.get_sequential_plan) return (params[:json] ? JSON.generate(plan) : (params[:pretty_json] ? JSON.pretty_generate(plan) : plan)) end def bsig_template - return {'version' => 1, 'operators' => [], 'id' => Time.now.getutc.to_i, 'goal' => []} + return {'version' => 1, 'operators' => [], 'id' => Time.now.getutc.to_i, 'goal' => {}, 'goal_operator' => {}} end def to_sequential_bsig bsig = self.bsig_template return bsig if @plan.length <= 0 + plan = self.get_sequential_plan bsig['operators'] = workflow = plan['workflow'] + (workflow.length-1).downto(1) do |i| op = workflow[i] prev_op = workflow[i-1] prev_op['effect'].each { |k,v| op['condition'][k] = v } end bsig['goal'], _ = self.bsig_goal_operator(workflow) + return bsig end def to_parallel_bsig + def set_priority_index(operator, operators) + pi = 1 + operator['successors'].each { |i| + set_priority_index(operators[i], operators) + pi = operators[i]['pi'] + 1 if pi <= operators[i]['pi'] + } + operator['pi'] = pi + end + return nil if @plan.nil? + bsig = self.bsig_template return bsig if @plan.length <= 0 + + # generate parallel plan plan = self.get_parallel_plan - # foreach operator's predecessors, add its effects to operator's conditions - bsig['operators'] = workflow = plan['workflow'] - workflow.each do |op| + + # set BSig operators + bsig['operators'] = operators = plan['workflow'] + + # set priority index + operators.each { |op| set_priority_index(op, operators) if op['predecessors'].length <= 0 } + + # foreach operator + # - for each operator's predecessors, add its effects to operator's conditions + # - remove unnecessary data + operators.each do |op| op['predecessors'].each do |pred| - pred_op = workflow[pred] + pred_op = operators[pred] pred_op['effect'].each { |k,v| op['condition'][k] = v } end - end - # remove unnecessary information - workflow.each do |op| op.delete('id') op.delete('predecessors') op.delete('successors') end - bsig['goal'], bsig['goal_operator'] = self.bsig_goal_operator(workflow) + + # set goals + bsig['goal'], bsig['goal_operator'] = self.bsig_goal_operator(operators) + return bsig end def bsig_goal_operator(workflow) goal_op = {} @@ -253,10 +281,16 @@ return json end def get_parallel_plan json = {'type'=>'parallel', 'workflow'=>nil, 'init'=>nil, 'version'=>'1', 'total'=>0} - return json if @plan == nil + if @plan.nil? + return json + elsif @plan.length <= 0 + json['workflow'] = [] + return json + end + json['workflow'], json['init'], json['total'] = @sas_task.get_partial_order_workflow(@parser) return json end def extract_sas_plan(sas_plan, parser)