sfplanner 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  SFP Planner for Ruby
2
2
  ====================
3
3
  - Author: Herry (herry13@gmail.com)
4
- - Version: 0.1.0
4
+ - Version: 0.1.1
5
5
  - License: [BSD License](https://github.com/herry13/sfp-ruby/blob/master/LICENSE)
6
6
 
7
7
  A Ruby gem that provides a Ruby API to SFP planner that solves a planning task written in [SFP language](https://github.com/herry13/nuri/wiki/SFP-language).
data/bin/sfplanner CHANGED
@@ -4,7 +4,7 @@ libdir = File.expand_path(File.dirname(__FILE__))
4
4
  require "#{libdir}/../lib/sfplanner"
5
5
 
6
6
  opts = Trollop::options do
7
- version "sfplanner 0.0.2 (c) 2013 Herry"
7
+ version "sfplanner 0.1.1 (c) 2013 Herry"
8
8
  banner <<-EOS
9
9
  Solve a planning task specified in SFP language, and print the plan (if found) in JSON format.
10
10
 
@@ -30,10 +30,15 @@ filepath = ARGV[0].to_s
30
30
 
31
31
  if filepath != ''
32
32
  planner = Sfp::Planner.new
33
+ options = {:file => ARGV[0],
34
+ :json => !opts[:pretty],
35
+ :pretty_json => opts[:pretty],
36
+ :parallel => opts[:parallel]}
33
37
  if opts[:json_input]
34
- puts 'Option "--json-input" is not supported yet.'
38
+ options[:input_json] = true
39
+ puts planner.solve(options)
35
40
  else
36
- puts planner.solve({:file => ARGV[0], :pretty_json => opts[:pretty], :parallel => opts[:parallel]})
41
+ puts planner.solve(options)
37
42
  end
38
43
  else
39
44
  Trollop::help
@@ -2,6 +2,7 @@ module Sfp
2
2
  class Planner
3
3
  Heuristic = 'mixed' # lmcut, cg, cea, ff, mixed ([cg|cea|ff]=>lmcut)
4
4
  Debug = false
5
+ TranslatorBenchmarkFile = 'sas_translator.benchmarks'
5
6
 
6
7
  class Config
7
8
  # The timeout for the solver in seconds (default 60s/1mins)
@@ -44,8 +45,12 @@ module Sfp
44
45
  @parser.root = params[:sfp]
45
46
  elsif params[:file].is_a?(String)
46
47
  raise Exception, "File not found: #{params[:file]}" if not File.exist?(params[:file])
47
- @parser.home_dir = File.expand_path(File.dirname(params[:file]))
48
- @parser.parse(File.read(params[:file]))
48
+ if params[:input_json]
49
+ @parser.root = json_to_sfp(JSON[File.read(params[:file])])
50
+ else
51
+ @parser.home_dir = File.expand_path(File.dirname(params[:file]))
52
+ @parser.parse(File.read(params[:file]))
53
+ end
49
54
  end
50
55
 
51
56
  @debug = true if params[:debug]
@@ -83,6 +88,16 @@ module Sfp
83
88
  end
84
89
 
85
90
  protected
91
+ def json_to_sfp(json)
92
+ json.accept(Sfp::Visitor::SfpGenerator.new(json))
93
+ json.each do |key,val|
94
+ next if key[0,1] == '_'
95
+ if val.is_a?(Hash) and val['_context'] == 'state'
96
+ #val.each { |k,v| v.delete('_parent') if k[0,1] != '_' and v.is_a?(Hash) and v.has_key?('_parent') }
97
+ end
98
+ end
99
+ end
100
+
86
101
  def save_sfp_task
87
102
  sfp_task = Sfp::Helper.deep_clone(@parser.root)
88
103
  sfp_task.accept(Sfp::Visitor::ParentEliminator.new)
@@ -266,14 +281,21 @@ module Sfp
266
281
 
267
282
  tmp_dir = '/tmp/nuri_' + (rand * 100000).to_i.abs.to_s
268
283
  begin
269
- parser.compile_step_1
270
- p[:sas_post_processor].sas_post_processor(parser) if p[:sas_post_processor]
271
- parser.compile_step_2
284
+ compile_time = Benchmark.measure do
285
+ parser.compile_step_1
286
+ p[:sas_post_processor].sas_post_processor(parser) if p[:sas_post_processor]
287
+ parser.compile_step_2
288
+ end
272
289
 
273
290
  while File.exist?(tmp_dir)
274
291
  tmp_dir = '/tmp/nuri_' + (rand * 100000).to_i.abs.to_s
275
292
  end
276
293
  Dir.mkdir(tmp_dir)
294
+
295
+ benchmarks = parser.benchmarks
296
+ benchmarks['compile time'] = compile_time
297
+ File.open(tmp_dir + '/' + TranslatorBenchmarkFile, 'w') { |f| f.write(JSON.pretty_generate(benchmarks)) }
298
+
277
299
  sas_file = tmp_dir + '/problem.sas'
278
300
  plan_file = tmp_dir + '/out.plan'
279
301
  File.open(sas_file, 'w') do |f|
@@ -347,27 +369,18 @@ module Sfp
347
369
  when 'cg' then '--search "lazy_greedy(cg(cost_type=2))"'
348
370
  when 'cea' then '--search "lazy_greedy(cea(cost_type=2))"'
349
371
  when 'mad' then '--search "lazy_greedy(mad())"'
350
- when 'lama2011' then ' \
351
- --heuristic "hlm1,hff1=lm_ff_syn(lm_rhw(
352
- reasonable_orders=true,lm_cost_type=1,cost_type=1))" \
353
- --heuristic "hlm2,hff2=lm_ff_syn(lm_rhw(
354
- reasonable_orders=true,lm_cost_type=2,cost_type=2))" \
355
- --search "iterated([
356
- lazy_greedy([hff1,hlm1],preferred=[hff1,hlm1],
357
- cost_type=1,reopen_closed=false),
358
- lazy_greedy([hff2,hlm2],preferred=[hff2,hlm2],
359
- reopen_closed=false),
360
- lazy_wastar([hff2,hlm2],preferred=[hff2,hlm2],w=5),
361
- lazy_wastar([hff2,hlm2],preferred=[hff2,hlm2],w=3),
362
- lazy_wastar([hff2,hlm2],preferred=[hff2,hlm2],w=2),
363
- lazy_wastar([hff2,hlm2],preferred=[hff2,hlm2],w=1)],
364
- repeat_last=true,continue_on_fail=true)"'
365
- when 'autotune' then ' \
372
+ when 'cea2' then ' --heuristic "hCea=cea(cost_type=2)" \
373
+ --search "ehc(hCea, preferred=hCea,preferred_usage=0,cost_type=0)"'
374
+ when 'ff2' then ' --heuristic "hFF=ff(cost_type=1)" \
375
+ --search "lazy(alt([single(sum([g(),weight(hFF, 10)])),
376
+ single(sum([g(),weight(hFF, 10)]),pref_only=true)],
377
+ boost=2000),
378
+ preferred=hFF,reopen_closed=false,cost_type=1)"'
379
+ when 'autotune22' then ' \
366
380
  --heuristic "hCea=cea(cost_type=2)" \
367
381
  --heuristic "hCg=cg(cost_type=1)" \
368
382
  --heuristic "hGoalCount=goalcount(cost_type=2)" \
369
383
  --heuristic "hFF=ff(cost_type=0)" \
370
- --heuristic "hMad=mad()" \
371
384
  --search "lazy(alt([single(sum([weight(g(), 2),weight(hFF, 3)])),
372
385
  single(sum([weight(g(), 2),weight(hFF, 3)]),pref_only=true),
373
386
  single(sum([weight(g(), 2),weight(hCg, 3)])),
@@ -375,11 +388,26 @@ module Sfp
375
388
  single(sum([weight(g(), 2),weight(hCea, 3)])),
376
389
  single(sum([weight(g(), 2),weight(hCea, 3)]),pref_only=true),
377
390
  single(sum([weight(g(), 2),weight(hGoalCount, 3)])),
378
- single(sum([weight(g(), 2),weight(hGoalCount, 3)]),pref_only=true),
379
- single(sum([weight(g(), 2),weight(hMad, 3)])),
380
- single(sum([weight(g(), 2),weight(hMad, 3)]),pref_only=true)],
391
+ single(sum([weight(g(), 2),weight(hGoalCount, 3)]),pref_only=true)],
381
392
  boost=200),
382
393
  preferred=[hCea,hGoalCount],reopen_closed=false,cost_type=1)"'
394
+ when 'autotune12' then ' \
395
+ --heuristic "hFF=ff(cost_type=1)" \
396
+ --heuristic "hCea=cea(cost_type=0)" \
397
+ --heuristic "hCg=cg(cost_type=2)" \
398
+ --heuristic "hGoalCount=goalcount(cost_type=0)" \
399
+ --heuristic "hAdd=add(cost_type=0)" \
400
+ --search "lazy(alt([single(sum([g(),weight(hAdd, 7)])),
401
+ single(sum([g(),weight(hAdd, 7)]),pref_only=true),
402
+ single(sum([g(),weight(hCg, 7)])),
403
+ single(sum([g(),weight(hCg, 7)]),pref_only=true),
404
+ single(sum([g(),weight(hCea, 7)])),
405
+ single(sum([g(),weight(hCea, 7)]),pref_only=true),
406
+ single(sum([g(),weight(hGoalCount, 7)])),
407
+ single(sum([g(),weight(hGoalCount, 7)]),pref_only=true)],
408
+ boost=1000),
409
+ preferred=[hCea,hGoalCount],
410
+ reopen_closed=false,cost_type=1)"'
383
411
  else '--search "lazy_greedy(ff(cost_type=0))"'
384
412
  end
385
413
  end
@@ -431,24 +459,26 @@ module Sfp
431
459
  end
432
460
 
433
461
  def solve
434
- use_admissible = false
435
-
436
- # 1a) solve with autotune (see fd-autotune-2)
437
- planner = Sfp::Planner.getcommand(@dir, @sas_file, @plan_file, 'autotune')
438
- Kernel.system(planner)
462
+ optimize = true
439
463
 
440
- # 1b) if not found, try mad
441
464
  if not File.exist?(@plan_file)
442
- planner = Sfp::Planner.getcommand(@dir, @sas_file, @plan_file, 'mad')
465
+ #autotune12 (see fd-autotune-1)
466
+ planner = Sfp::Planner.getcommand(@dir, @sas_file, @plan_file, 'autotune12')
467
+ Kernel.system(planner)
468
+ end
469
+ if not File.exist?(@plan_file)
470
+ #autotune22 (see fd-autotune-2)
471
+ planner = Sfp::Planner.getcommand(@dir, @sas_file, @plan_file, 'autotune22')
472
+ Kernel.system(planner)
473
+ end
474
+ if not File.exists?(@plan_file)
475
+ # solve with cea2 (EHC+CEA: see fd-autotune-2)
476
+ planner = Sfp::Planner.getcommand(@dir, @sas_file, @plan_file, 'cea2')
443
477
  Kernel.system(planner)
444
478
  end
445
- # if not File.exist?(@plan_file)
446
- # planner = Sfp::Planner.getcommand(@dir, @sas_file, @plan_file, 'ff')
447
- # Kernel.system(planner)
448
- # end
449
- # 1c) if not found, try CEA
450
479
  if not File.exists?(@plan_file)
451
- planner = Sfp::Planner.getcommand(@dir, @sas_file, @plan_file, 'cea')
480
+ # solve with ff2 (FF with boost: see fd-autotune-1)
481
+ planner = Sfp::Planner.getcommand(@dir, @sas_file, @plan_file, 'ff2')
452
482
  Kernel.system(planner)
453
483
  end
454
484
 
@@ -460,12 +490,12 @@ module Sfp
460
490
  #end
461
491
 
462
492
  return false if not File.exist?(@plan_file)
463
- optimise_plan if not use_admissible
493
+ optimize_plan if optimize
464
494
 
465
495
  true
466
496
  end
467
497
 
468
- def optimise_plan
498
+ def optimize_plan
469
499
  # 2) remove unselected operators
470
500
  new_sas = @sas_file + '.2'
471
501
  new_plan = @plan_file + '.2'
@@ -489,6 +519,7 @@ module Sfp
489
519
  line.strip!
490
520
  line = line[1, line.length-2]
491
521
  selected << line.split(' ', 2)[0]
522
+ #'$.' + line[1, line.length-2].split(' ', 2)[0].split('$.')[1]
492
523
  end
493
524
 
494
525
  # remove unselected operators
data/lib/sfplanner.rb CHANGED
@@ -1,11 +1,10 @@
1
1
  # external dependencies
2
2
  require 'rubygems'
3
3
  require 'json'
4
- #require 'sfp'
4
+ require 'sfp'
5
5
 
6
6
  # internal dependencies
7
7
  libdir = File.expand_path(File.dirname(__FILE__))
8
8
 
9
- require libdir + '/../../sfp-ruby/lib/sfp.rb'
10
9
  require libdir + '/sfplanner/sas'
11
10
  require libdir + '/sfplanner/planner'
data/sfplanner.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'sfplanner'
3
- s.version = '0.1.0'
4
- s.date = '2013-08-05'
3
+ s.version = '0.1.1'
4
+ s.date = '2013-08-13'
5
5
  s.summary = 'SFPlanner'
6
6
  s.description = 'A Ruby gem that provides a Ruby API and a script to the SFP planner. This planner can automatically generate a plan that solves a planning problem written in SFP language.'
7
7
  s.authors = ['Herry']
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sfplanner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-05 00:00:00.000000000 Z
12
+ date: 2013-08-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sfp
16
- requirement: !ruby/object:Gem::Requirement
16
+ requirement: &21369160 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,12 +21,7 @@ dependencies:
21
21
  version: 0.3.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- version: 0.3.6
24
+ version_requirements: *21369160
30
25
  description: A Ruby gem that provides a Ruby API and a script to the SFP planner.
31
26
  This planner can automatically generate a plan that solves a planning problem written
32
27
  in SFP language.
@@ -70,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
65
  version: '0'
71
66
  requirements: []
72
67
  rubyforge_project: sfplanner
73
- rubygems_version: 1.8.23
68
+ rubygems_version: 1.8.11
74
69
  signing_key:
75
70
  specification_version: 3
76
71
  summary: SFPlanner