mini_kraken 0.2.03 → 0.3.03

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +378 -333
  3. data/CHANGELOG.md +48 -0
  4. data/README.md +29 -21
  5. data/lib/mini_kraken/atomic/all_atomic.rb +5 -0
  6. data/lib/mini_kraken/atomic/atomic_term.rb +96 -0
  7. data/lib/mini_kraken/atomic/k_boolean.rb +42 -0
  8. data/lib/mini_kraken/{core → atomic}/k_integer.rb +2 -5
  9. data/lib/mini_kraken/atomic/k_string.rb +17 -0
  10. data/lib/mini_kraken/{core → atomic}/k_symbol.rb +4 -8
  11. data/lib/mini_kraken/composite/all_composite.rb +4 -0
  12. data/lib/mini_kraken/composite/composite_term.rb +27 -0
  13. data/lib/mini_kraken/composite/cons_cell.rb +301 -0
  14. data/lib/mini_kraken/composite/cons_cell_visitor.rb +50 -0
  15. data/lib/mini_kraken/composite/list.rb +32 -0
  16. data/lib/mini_kraken/core/all_core.rb +8 -0
  17. data/lib/mini_kraken/core/any_value.rb +31 -7
  18. data/lib/mini_kraken/core/arity.rb +69 -0
  19. data/lib/mini_kraken/core/association.rb +29 -4
  20. data/lib/mini_kraken/core/association_copy.rb +50 -0
  21. data/lib/mini_kraken/core/base_term.rb +13 -0
  22. data/lib/mini_kraken/core/blackboard.rb +315 -0
  23. data/lib/mini_kraken/core/bookmark.rb +46 -0
  24. data/lib/mini_kraken/core/context.rb +492 -0
  25. data/lib/mini_kraken/core/duck_fiber.rb +21 -19
  26. data/lib/mini_kraken/core/entry.rb +40 -0
  27. data/lib/mini_kraken/core/fail.rb +20 -18
  28. data/lib/mini_kraken/core/fusion.rb +29 -0
  29. data/lib/mini_kraken/core/goal.rb +20 -29
  30. data/lib/mini_kraken/core/log_var.rb +22 -0
  31. data/lib/mini_kraken/core/log_var_ref.rb +108 -0
  32. data/lib/mini_kraken/core/nullary_relation.rb +2 -9
  33. data/lib/mini_kraken/core/parametrized_term.rb +68 -0
  34. data/lib/mini_kraken/core/relation.rb +14 -28
  35. data/lib/mini_kraken/core/scope.rb +67 -0
  36. data/lib/mini_kraken/core/solver_adapter.rb +58 -0
  37. data/lib/mini_kraken/core/specification.rb +48 -0
  38. data/lib/mini_kraken/core/succeed.rb +21 -17
  39. data/lib/mini_kraken/core/symbol_table.rb +137 -0
  40. data/lib/mini_kraken/core/term.rb +15 -4
  41. data/lib/mini_kraken/glue/dsl.rb +44 -88
  42. data/lib/mini_kraken/glue/run_star_expression.rb +28 -30
  43. data/lib/mini_kraken/rela/all_rela.rb +8 -0
  44. data/lib/mini_kraken/rela/binary_relation.rb +30 -0
  45. data/lib/mini_kraken/rela/conde.rb +143 -0
  46. data/lib/mini_kraken/rela/conj2.rb +65 -0
  47. data/lib/mini_kraken/rela/def_relation.rb +93 -0
  48. data/lib/mini_kraken/rela/disj2.rb +70 -0
  49. data/lib/mini_kraken/rela/fresh.rb +98 -0
  50. data/lib/mini_kraken/{core → rela}/goal_relation.rb +7 -9
  51. data/lib/mini_kraken/rela/unify.rb +265 -0
  52. data/lib/mini_kraken/version.rb +1 -1
  53. data/mini_kraken.gemspec +2 -2
  54. data/spec/.rubocop.yml +1 -1
  55. data/spec/atomic/atomic_term_spec.rb +98 -0
  56. data/spec/{core → atomic}/k_boolean_spec.rb +19 -34
  57. data/spec/{core → atomic}/k_symbol_spec.rb +3 -16
  58. data/spec/composite/cons_cell_spec.rb +225 -0
  59. data/spec/{core → composite}/cons_cell_visitor_spec.rb +36 -20
  60. data/spec/composite/list_spec.rb +50 -0
  61. data/spec/core/any_value_spec.rb +52 -0
  62. data/spec/core/arity_spec.rb +92 -0
  63. data/spec/core/association_copy_spec.rb +69 -0
  64. data/spec/core/association_spec.rb +31 -4
  65. data/spec/core/blackboard_spec.rb +287 -0
  66. data/spec/core/bookmark_spec.rb +40 -0
  67. data/spec/core/context_spec.rb +245 -0
  68. data/spec/core/core_spec.rb +40 -0
  69. data/spec/core/duck_fiber_spec.rb +16 -46
  70. data/spec/core/fail_spec.rb +5 -6
  71. data/spec/core/goal_spec.rb +22 -12
  72. data/spec/core/log_var_ref_spec.rb +105 -0
  73. data/spec/core/log_var_spec.rb +64 -0
  74. data/spec/core/nullary_relation_spec.rb +33 -0
  75. data/spec/core/parametrized_tem_spec.rb +39 -0
  76. data/spec/core/relation_spec.rb +33 -0
  77. data/spec/core/scope_spec.rb +73 -0
  78. data/spec/core/solver_adapter_spec.rb +70 -0
  79. data/spec/core/specification_spec.rb +43 -0
  80. data/spec/core/succeed_spec.rb +5 -5
  81. data/spec/core/symbol_table_spec.rb +142 -0
  82. data/spec/glue/dsl_chap1_spec.rb +88 -144
  83. data/spec/glue/dsl_chap2_spec.rb +454 -19
  84. data/spec/glue/run_star_expression_spec.rb +81 -906
  85. data/spec/rela/conde_spec.rb +153 -0
  86. data/spec/rela/conj2_spec.rb +123 -0
  87. data/spec/rela/def_relation_spec.rb +119 -0
  88. data/spec/rela/disj2_spec.rb +117 -0
  89. data/spec/rela/fresh_spec.rb +147 -0
  90. data/spec/rela/unify_spec.rb +369 -0
  91. data/spec/support/factory_atomic.rb +29 -0
  92. data/spec/support/factory_composite.rb +21 -0
  93. data/spec/support/factory_methods.rb +11 -26
  94. metadata +98 -70
  95. data/lib/mini_kraken/core/association_walker.rb +0 -183
  96. data/lib/mini_kraken/core/atomic_term.rb +0 -67
  97. data/lib/mini_kraken/core/base_arg.rb +0 -10
  98. data/lib/mini_kraken/core/binary_relation.rb +0 -63
  99. data/lib/mini_kraken/core/composite_goal.rb +0 -46
  100. data/lib/mini_kraken/core/composite_term.rb +0 -41
  101. data/lib/mini_kraken/core/conde.rb +0 -143
  102. data/lib/mini_kraken/core/conj2.rb +0 -79
  103. data/lib/mini_kraken/core/cons_cell.rb +0 -82
  104. data/lib/mini_kraken/core/cons_cell_visitor.rb +0 -102
  105. data/lib/mini_kraken/core/def_relation.rb +0 -53
  106. data/lib/mini_kraken/core/designation.rb +0 -55
  107. data/lib/mini_kraken/core/disj2.rb +0 -72
  108. data/lib/mini_kraken/core/environment.rb +0 -73
  109. data/lib/mini_kraken/core/equals.rb +0 -193
  110. data/lib/mini_kraken/core/formal_arg.rb +0 -22
  111. data/lib/mini_kraken/core/formal_ref.rb +0 -25
  112. data/lib/mini_kraken/core/freshness.rb +0 -45
  113. data/lib/mini_kraken/core/goal_arg.rb +0 -12
  114. data/lib/mini_kraken/core/goal_template.rb +0 -102
  115. data/lib/mini_kraken/core/k_boolean.rb +0 -35
  116. data/lib/mini_kraken/core/outcome.rb +0 -63
  117. data/lib/mini_kraken/core/variable.rb +0 -41
  118. data/lib/mini_kraken/core/variable_ref.rb +0 -84
  119. data/lib/mini_kraken/core/vocabulary.rb +0 -446
  120. data/lib/mini_kraken/glue/fresh_env.rb +0 -103
  121. data/lib/mini_kraken/glue/fresh_env_factory.rb +0 -83
  122. data/spec/core/association_walker_spec.rb +0 -192
  123. data/spec/core/conde_spec.rb +0 -147
  124. data/spec/core/conj2_spec.rb +0 -114
  125. data/spec/core/cons_cell_spec.rb +0 -107
  126. data/spec/core/def_relation_spec.rb +0 -97
  127. data/spec/core/disj2_spec.rb +0 -99
  128. data/spec/core/environment_spec.rb +0 -142
  129. data/spec/core/equals_spec.rb +0 -317
  130. data/spec/core/goal_template_spec.rb +0 -74
  131. data/spec/core/outcome_spec.rb +0 -56
  132. data/spec/core/variable_ref_spec.rb +0 -30
  133. data/spec/core/variable_spec.rb +0 -35
  134. data/spec/core/vocabulary_spec.rb +0 -219
  135. data/spec/glue/fresh_env_factory_spec.rb +0 -97
  136. data/spec/glue/fresh_env_spec.rb +0 -62
@@ -1,114 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../spec_helper' # Use the RSpec framework
4
- require_relative '../../lib/mini_kraken/core/k_symbol'
5
- require_relative '../../lib/mini_kraken/core/fail'
6
- require_relative '../../lib/mini_kraken/core/succeed'
7
- require_relative '../../lib/mini_kraken/core/equals'
8
- require_relative '../../lib/mini_kraken/core/environment'
9
- require_relative '../../lib/mini_kraken/core/variable'
10
- require_relative '../../lib/mini_kraken/core/variable_ref'
11
-
12
- # Load the class under test
13
- require_relative '../../lib/mini_kraken/core/conj2'
14
-
15
-
16
- module MiniKraken
17
- module Core
18
- describe Conj2 do
19
- subject { Conj2.instance }
20
-
21
- context 'Initialization:' do
22
- it 'should be initialized without argument' do
23
- expect { Conj2.instance }.not_to raise_error
24
- end
25
-
26
- it 'should know its name' do
27
- expect(subject.name).to eq('conj2')
28
- end
29
- end # context
30
-
31
- context 'Provided services:' do
32
- let(:env) { Environment.new }
33
- let(:pea) { KSymbol.new(:pea) }
34
- let(:corn) { KSymbol.new(:corn) }
35
- let(:meal) { KSymbol.new(:meal) }
36
- let(:fails) { Goal.new(Fail.instance, []) }
37
- let(:succeeds) { Goal.new(Succeed.instance, []) }
38
- let(:var_q) { Variable.new('q') }
39
- let(:ref_q) { VariableRef.new('q') }
40
-
41
- it 'should complain when one of its argument is not a goal' do
42
- err = StandardError
43
- expect { subject.solver_for([succeeds, pea], env) }.to raise_error(err)
44
- expect { subject.solver_for([pea, succeeds], env) }.to raise_error(err)
45
- end
46
-
47
- it 'should yield one failure if one of the goal is fail' do
48
- # Fail as first argument
49
- solver = subject.solver_for([fails, succeeds], env)
50
- expect(solver.resume).not_to be_success
51
- expect(solver.resume).to be_nil
52
-
53
- # Fail as second argument
54
- solver = subject.solver_for([succeeds, fails], env)
55
- expect(solver.resume).not_to be_success
56
- expect(solver.resume).to be_nil
57
- end
58
-
59
- it 'yield success if both arguments are succeed goals' do
60
- # Covers frame 1-50
61
- solver = subject.solver_for([succeeds, succeeds], env)
62
- outcome = solver.resume
63
- expect(outcome).to be_success
64
- expect(outcome.associations).to be_empty
65
- expect(solver.resume).to be_nil
66
- end
67
-
68
- it 'should yield success and set associations' do
69
- # Covers frame 1-51
70
- env.add_var(var_q)
71
- sub_goal = Goal.new(Equals.instance, [corn, ref_q])
72
- solver = subject.solver_for([succeeds, sub_goal], env)
73
- outcome = solver.resume
74
- expect(outcome).to be_success
75
- expect(outcome.associations).not_to be_empty
76
- expect(outcome.associations['q'].first.value).to eq(corn)
77
- end
78
-
79
- it 'should yield fails and set no associations' do
80
- # Covers frame 1-52
81
- env.add_var(var_q)
82
- sub_goal = Goal.new(Equals.instance, [corn, ref_q])
83
- solver = subject.solver_for([fails, sub_goal], env)
84
- outcome = solver.resume
85
- expect(outcome).not_to be_success
86
- expect(outcome.associations).to be_empty
87
- end
88
-
89
- it 'should yield fails when sub-goals are incompatible' do
90
- # Covers frame 1-53
91
- env.add_var(var_q)
92
- sub_goal1 = Goal.new(Equals.instance, [corn, ref_q])
93
- sub_goal2 = Goal.new(Equals.instance, [meal, ref_q])
94
- solver = subject.solver_for([sub_goal1, sub_goal2], env)
95
- outcome = solver.resume
96
- expect(outcome).not_to be_success
97
- expect(outcome.associations).to be_empty
98
- end
99
-
100
- it 'should yield success when sub-goals are same and successful' do
101
- # Covers frame 1-54
102
- env.add_var(var_q)
103
- sub_goal1 = Goal.new(Equals.instance, [corn, ref_q])
104
- sub_goal2 = Goal.new(Equals.instance, [corn, ref_q])
105
- solver = subject.solver_for([sub_goal1, sub_goal2], env)
106
- outcome = solver.resume
107
- expect(outcome).to be_success
108
- expect(outcome.associations).not_to be_empty
109
- expect(outcome.associations['q'].first.value).to eq(corn)
110
- end
111
- end # context
112
- end # describe
113
- end # module
114
- end # module
@@ -1,107 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../spec_helper' # Use the RSpec framework
4
- require_relative '../../lib/mini_kraken/core/k_symbol'
5
-
6
- # Load the class under test
7
- require_relative '../../lib/mini_kraken/core/cons_cell'
8
-
9
- module MiniKraken
10
- module Core
11
- describe ConsCell do
12
- let(:pea) { KSymbol.new(:pea) }
13
- let(:pod) { KSymbol.new(:pod) }
14
- let(:corn) { KSymbol.new(:corn) }
15
- subject { ConsCell.new(pea, pod) }
16
-
17
- context 'Initialization:' do
18
- it 'could be initialized with one argument' do
19
- expect { ConsCell.new(pea) }.not_to raise_error
20
- end
21
-
22
- it 'could be initialized with a second optional argument' do
23
- expect { ConsCell.new(pea, pod) }.not_to raise_error
24
- end
25
-
26
- it 'should know its car child' do
27
- expect(subject.car).to eq(pea)
28
- end
29
-
30
- it 'should know its cdr child' do
31
- expect(subject.cdr).to eq(pod)
32
- end
33
-
34
- it 'should know its children' do
35
- expect(subject.children).to eq([pea, pod])
36
- end
37
-
38
- it 'should know if it is empty (null)' do
39
- expect(subject).not_to be_null
40
- expect(ConsCell.new(nil, nil)).to be_null
41
- expect(NullList).to be_null
42
- end
43
-
44
- it 'simplifies cdr if its referencing a null list' do
45
- instance = ConsCell.new(pea, NullList)
46
- expect(instance.car).to eq(pea)
47
- expect(instance.cdr).to be_nil
48
- end
49
- end # context
50
-
51
- context 'Provided services:' do
52
- it 'should compare to itself' do
53
- expect(subject.eql?(subject)).to be_truthy
54
- synonym = subject
55
- expect(subject == synonym).to be_truthy
56
- end
57
-
58
- it 'should compare to another instance' do
59
- same = ConsCell.new(pea, pod)
60
- expect(subject.eql?(same)).to be_truthy
61
-
62
- different = ConsCell.new(pod, pea)
63
- expect(subject.eql?(different)).to be_falsey
64
-
65
- different = ConsCell.new(pea)
66
- expect(subject.eql?(different)).to be_falsey
67
- end
68
-
69
- it 'should append another cons cell' do
70
- instance = ConsCell.new(pea)
71
- trail = ConsCell.new(pod)
72
- instance.append(trail)
73
- expect(instance.car).to eq(pea)
74
- expect(instance.cdr).to eq(trail)
75
- end
76
-
77
- it 'should provide a list representation of itself' do
78
- # Case of null list
79
- expect(NullList.to_s).to eq '()'
80
-
81
- # Case of one element proper list
82
- cell = ConsCell.new(pea)
83
- expect(cell.to_s).to eq '(:pea)'
84
-
85
- # Case of two elements proper list
86
- cell = ConsCell.new(pea, ConsCell.new(pod))
87
- expect(cell.to_s).to eq '(:pea :pod)'
88
-
89
- # Case of two elements improper list
90
- expect(subject.to_s).to eq '(:pea . :pod)'
91
-
92
- # Case of three elements proper list
93
- cell = ConsCell.new(pea, ConsCell.new(pod, ConsCell.new(corn)))
94
- expect(cell.to_s).to eq '(:pea :pod :corn)'
95
-
96
- # Case of three elements improper list
97
- cell = ConsCell.new(pea, ConsCell.new(pod, corn))
98
- expect(cell.to_s).to eq '(:pea :pod . :corn)'
99
-
100
- # Case of a nested list
101
- cell = ConsCell.new(ConsCell.new(pea), ConsCell.new(pod))
102
- expect(cell.to_s).to eq '((:pea) :pod)'
103
- end
104
- end # context
105
- end # describe
106
- end # module
107
- end # module
@@ -1,97 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../spec_helper' # Use the RSpec framework
4
- require_relative '../../lib/mini_kraken/core/disj2'
5
- require_relative '../../lib/mini_kraken/core/equals'
6
- require_relative '../../lib/mini_kraken/core/formal_arg'
7
- require_relative '../../lib/mini_kraken/core/formal_ref'
8
- require_relative '../../lib/mini_kraken/core/goal'
9
- require_relative '../../lib/mini_kraken/core/goal_template'
10
- require_relative '../../lib/mini_kraken/core/k_symbol'
11
- require_relative '../../lib/mini_kraken/core/variable_ref'
12
- require_relative '../../lib/mini_kraken/core/environment'
13
-
14
- # Load the class under test
15
- require_relative '../../lib/mini_kraken/core/def_relation'
16
-
17
- module MiniKraken
18
- module Core
19
- describe DefRelation do
20
- # (defrel (teao t) (== 'tea t))
21
- let(:tea) { KSymbol.new(:tea) }
22
- let(:formal_t) { FormalArg.new('t') }
23
- let(:t_ref) { FormalRef.new('t') }
24
- let(:equals_tea) { GoalTemplate.new(Equals.instance, [tea, t_ref]) }
25
- subject { DefRelation.new('teao', equals_tea, [formal_t]) }
26
-
27
- context 'Initialization:' do
28
- it 'should be initialized with a name, a goal template, formal args' do
29
- expect { DefRelation.new('teao', equals_tea, [formal_t]) }.not_to raise_error
30
- end
31
-
32
- it 'should know its name' do
33
- expect(subject.name).to eq('teao')
34
- end
35
-
36
- it 'should know its goal template' do
37
- expect(subject.goal_template).to eq(equals_tea)
38
- end
39
-
40
- it 'should know its formals' do
41
- expect(subject.formals).to eq([formal_t])
42
- end
43
- end # context
44
-
45
- context 'Provided services:' do
46
- let(:cup) { KSymbol.new(:cup) }
47
- let(:ref_x) { VariableRef.new('x') }
48
- let(:equals_cup) { GoalTemplate.new(Equals.instance, [cup, t_ref]) }
49
- let(:g_template) { GoalTemplate.new(Disj2.instance, [equals_tea, equals_cup]) }
50
- subject { DefRelation.new('teacup', g_template, [formal_t]) }
51
- let(:env) { Environment.new }
52
-
53
- it 'should provide solver for a single-node goal without var ref' do
54
- defrel = DefRelation.new('teao', equals_tea, [formal_t])
55
- solver = defrel.solver_for([tea], env)
56
- outcome = solver.resume
57
- expect(outcome).to be_success
58
- outcome = solver.resume
59
- expect(outcome).to be_nil
60
-
61
- solver = defrel.solver_for([cup], env)
62
- outcome = solver.resume
63
- expect(outcome).not_to be_success
64
- outcome = solver.resume
65
- expect(outcome).to be_nil
66
- end
67
-
68
- it 'should provide solver for a single-node goal' do
69
- defrel = DefRelation.new('teao', equals_tea, [formal_t])
70
- env.add_var(Variable.new('x'))
71
- solver = defrel.solver_for([ref_x], env)
72
- outcome = solver.resume
73
- expect(outcome).to be_success
74
- expect(ref_x.value(outcome)).to eq(tea)
75
-
76
- outcome = solver.resume
77
- expect(outcome).to be_nil
78
- end
79
-
80
- it 'should provide solver for a single-node goal' do
81
- env.add_var(Variable.new('x'))
82
- solver = subject.solver_for([ref_x], env)
83
- outcome = solver.resume
84
- expect(outcome).to be_success
85
- expect(ref_x.value(outcome)).to eq(tea)
86
-
87
- outcome = solver.resume
88
- expect(outcome).to be_success
89
- expect(ref_x.value(outcome)).to eq(cup)
90
-
91
- outcome = solver.resume
92
- expect(outcome).to be_nil
93
- end
94
- end # context
95
- end # describe
96
- end # module
97
- end # module
@@ -1,99 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../spec_helper' # Use the RSpec framework
4
- require_relative '../../lib/mini_kraken/core/k_symbol'
5
- require_relative '../../lib/mini_kraken/core/fail'
6
- require_relative '../../lib/mini_kraken/core/succeed'
7
- require_relative '../../lib/mini_kraken/core/equals'
8
- require_relative '../../lib/mini_kraken/core/environment'
9
- require_relative '../../lib/mini_kraken/core/variable'
10
- require_relative '../../lib/mini_kraken/core/variable_ref'
11
-
12
- # Load the class under test
13
- require_relative '../../lib/mini_kraken/core/disj2'
14
-
15
- module MiniKraken
16
- module Core
17
- describe Disj2 do
18
- subject { Disj2.instance }
19
-
20
- context 'Initialization:' do
21
- it 'should be initialized without argument' do
22
- expect { Disj2.instance }.not_to raise_error
23
- end
24
-
25
- it 'should know its name' do
26
- expect(subject.name).to eq('disj2')
27
- end
28
- end # context
29
-
30
- context 'Provided services:' do
31
- let(:corn) { KSymbol.new(:corn) }
32
- let(:meal) { KSymbol.new(:meal) }
33
- let(:oil) { KSymbol.new(:oil) }
34
- let(:olive) { KSymbol.new(:olive) }
35
- let(:pea) { KSymbol.new(:pea) }
36
- let(:fails) { Goal.new(Fail.instance, []) }
37
- let(:succeeds) { Goal.new(Succeed.instance, []) }
38
- let(:var_q) { Variable.new('q') }
39
- let(:ref_q) { VariableRef.new('q') }
40
- let(:env) do
41
- e = Environment.new
42
- e.add_var(var_q)
43
- e
44
- end
45
-
46
- it 'should complain when one of its argument is not a goal' do
47
- err = StandardError
48
- expect { subject.solver_for([succeeds, pea], env) }.to raise_error(err)
49
- expect { subject.solver_for([pea, succeeds], env) }.to raise_error(err)
50
- end
51
-
52
- it 'should fails if both arguments fail' do
53
- # Covers frame 1:55
54
- solver = subject.solver_for([fails, fails], env)
55
- expect(solver.resume).not_to be_success
56
- expect(solver.resume).to be_nil
57
- end
58
-
59
- it 'yield success if first argument succeeds' do
60
- # Covers frame 1:56
61
- subgoal = Goal.new(Equals.instance, [olive, ref_q])
62
- solver = subject.solver_for([subgoal, fails], env)
63
- outcome = solver.resume
64
- expect(outcome).to be_success
65
- expect(outcome.associations['q'].first.value).to eq(olive)
66
- expect(solver.resume).to be_nil
67
- end
68
-
69
- it 'yield success if second argument succeeds' do
70
- # Covers frame 1:57
71
- subgoal = Goal.new(Equals.instance, [oil, ref_q])
72
- solver = subject.solver_for([fails, subgoal], env)
73
- outcome = solver.resume
74
- expect(outcome).to be_success
75
- expect(outcome.associations['q'].first.value).to eq(oil)
76
- expect(solver.resume).to be_nil
77
- end
78
-
79
- it 'yield two solutions if both arguments succeed' do
80
- # Covers frame 1:58
81
- subgoal1 = Goal.new(Equals.instance, [olive, ref_q])
82
- subgoal2 = Goal.new(Equals.instance, [oil, ref_q])
83
- solver = subject.solver_for([subgoal1, subgoal2], env)
84
-
85
- # First solution
86
- outcome1 = solver.resume
87
- expect(outcome1).to be_success
88
- expect(outcome1.associations['q'].first.value).to eq(olive)
89
-
90
- # Second solution
91
- outcome2 = solver.resume
92
- expect(outcome2).to be_success
93
- expect(outcome2.associations['q'].first.value).to eq(oil)
94
- expect(solver.resume).to be_nil
95
- end
96
- end # context
97
- end # describe
98
- end # module
99
- end # module
@@ -1,142 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../spec_helper' # Use the RSpec framework
4
- require_relative '../../lib/mini_kraken/core/k_symbol'
5
- require_relative '../../lib/mini_kraken/core/variable'
6
- require_relative '../../lib/mini_kraken/core/variable_ref'
7
- require_relative '../../lib/mini_kraken/core/outcome'
8
-
9
- # Load the class under test
10
- require_relative '../../lib/mini_kraken/core/environment'
11
-
12
- module MiniKraken
13
- module Core
14
- describe Environment do
15
- subject { Environment.new }
16
-
17
- context 'Initialization:' do
18
- it 'should be initialized with an optional parent' do
19
- expect { Environment.new }.not_to raise_error
20
- parent = Environment.new
21
- expect { Environment.new(parent) }.not_to raise_error
22
- end
23
-
24
- it "shouldn't have variable by default" do
25
- expect(subject.vars).to be_empty
26
- end
27
-
28
- it "shouldn't have associations by default" do
29
- expect(subject.associations).to be_empty
30
- end
31
-
32
- it 'shold know its parent (if any)' do
33
- # Case: no parent
34
- expect(subject.parent).to be_nil
35
-
36
- # Case: there is a parent
37
- child = Environment.new(subject)
38
- expect(child.parent).to eq(subject)
39
- end
40
- end # context
41
-
42
- context 'Provided services:' do
43
- let(:var_a) { Variable.new('a') }
44
- let(:var_b) { Variable.new('b') }
45
- let(:var_c) { Variable.new('c') }
46
- let(:var_c_bis) { Variable.new('c') }
47
- let(:pea) { KSymbol.new(:pea) }
48
- let(:pod) { KSymbol.new(:pod) }
49
- let(:pad) { KSymbol.new(:pad) }
50
-
51
- it 'should accept the addition of a variable' do
52
- subject.add_var(var_a)
53
- expect(subject.vars).not_to be_empty
54
- expect(subject.vars['a']).to eq(var_a)
55
- end
56
-
57
- it 'should accept the addition of multiple variables' do
58
- subject.add_var(var_a)
59
- expect(subject.vars).not_to be_empty
60
- subject.add_var(var_b)
61
- expect(subject.vars['a']).to eq(var_a)
62
- expect(subject.vars['b']).to eq(var_b)
63
- end
64
-
65
- it 'should accept the addition of an association' do
66
- subject.add_var(var_a)
67
- assoc = subject.add_assoc('a', pea)
68
- expect(subject.associations.size).to eq(1)
69
- expect(subject.associations['a']).to eq([assoc])
70
- end
71
-
72
- it 'should tell that a newborn variable is fresh' do
73
- subject.add_var(var_a)
74
-
75
- # By default, a variable is fresh...
76
- expect(subject.fresh?(var_a)).to be_truthy
77
- end
78
-
79
- it "should tell variable associated with a literal value isn't fresh" do
80
- subject.add_var(var_a)
81
-
82
- # Let's associate an atomic term...
83
- subject.add_assoc('a', pea)
84
-
85
- expect(subject.fresh?(var_a)).to be_falsey
86
- end
87
-
88
- it 'should cope with a variable associated with another variable' do
89
- subject.add_var(var_a)
90
- subject.add_var(var_b)
91
-
92
- # Let's associate a with (fresh) b
93
- subject.add_assoc(var_a, var_b)
94
- expect(subject.fresh?(var_a)).to be_truthy
95
-
96
- # Now associate b with something ground...
97
- subject.add_assoc(var_b, pea)
98
-
99
- # b is no more fresh, so is ... a
100
- expect(subject.fresh?(var_b)).to be_falsey
101
- expect(subject.fresh?(var_a)).to be_falsey
102
- end
103
-
104
- it 'should remove all associations' do
105
- subject.add_var(var_a)
106
- subject.add_assoc(var_a, pea)
107
-
108
- subject.add_var(var_b)
109
- subject.add_assoc(var_b, pod)
110
-
111
- subject.clear
112
- expect(subject.fresh?(var_a)).to be_truthy
113
- expect(subject.fresh?(var_a)).to be_truthy
114
- end
115
-
116
- it 'should propagate associations up in the environment hierarchy' do
117
- parent = Environment.new
118
- parent.add_var(var_a)
119
- instance = Environment.new(parent)
120
- instance.add_var(var_b)
121
-
122
- outcome = Outcome.new(:"#s", instance)
123
- outcome.add_assoc(var_a, pea)
124
- outcome.add_assoc(var_b, pod)
125
- expect(outcome.associations.size).to eq(2)
126
-
127
- # Propagate: outcome -> .. -> instance
128
- instance.propagate(outcome)
129
- expect(outcome.associations.size).to eq(1)
130
- expect(instance.associations[var_b.name]).not_to be_nil
131
- expect(parent.associations[var_a.name]).to be_nil
132
-
133
- # Propagate: outcome -> .. -> parent
134
- parent.propagate(outcome)
135
- expect(outcome.associations).to be_empty
136
- expect(parent.associations[var_b.name]).to be_nil
137
- expect(parent.associations[var_a.name]).not_to be_nil
138
- end
139
- end # context
140
- end # describe
141
- end # module
142
- end # module