mini_kraken 0.1.12 → 0.2.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +334 -0
  3. data/CHANGELOG.md +54 -0
  4. data/README.md +95 -13
  5. data/lib/mini_kraken.rb +7 -1
  6. data/lib/mini_kraken/core/any_value.rb +5 -1
  7. data/lib/mini_kraken/core/atomic_term.rb +1 -0
  8. data/lib/mini_kraken/core/conde.rb +1 -1
  9. data/lib/mini_kraken/core/conj2.rb +3 -3
  10. data/lib/mini_kraken/core/cons_cell.rb +29 -1
  11. data/lib/mini_kraken/core/cons_cell_visitor.rb +102 -0
  12. data/lib/mini_kraken/core/def_relation.rb +4 -0
  13. data/lib/mini_kraken/core/disj2.rb +2 -2
  14. data/lib/mini_kraken/core/environment.rb +2 -2
  15. data/lib/mini_kraken/core/equals.rb +60 -26
  16. data/lib/mini_kraken/core/formal_ref.rb +2 -1
  17. data/lib/mini_kraken/core/goal.rb +4 -2
  18. data/lib/mini_kraken/core/goal_template.rb +44 -2
  19. data/lib/mini_kraken/core/k_boolean.rb +4 -0
  20. data/lib/mini_kraken/core/k_symbol.rb +11 -0
  21. data/lib/mini_kraken/core/outcome.rb +11 -1
  22. data/lib/mini_kraken/core/variable.rb +10 -4
  23. data/lib/mini_kraken/core/variable_ref.rb +7 -0
  24. data/lib/mini_kraken/core/vocabulary.rb +8 -3
  25. data/lib/mini_kraken/glue/dsl.rb +236 -0
  26. data/lib/mini_kraken/glue/fresh_env.rb +31 -3
  27. data/lib/mini_kraken/glue/fresh_env_factory.rb +83 -0
  28. data/lib/mini_kraken/glue/run_star_expression.rb +3 -5
  29. data/lib/mini_kraken/version.rb +1 -1
  30. data/mini_kraken.gemspec +6 -3
  31. data/spec/.rubocop.yml +13 -0
  32. data/spec/core/conde_spec.rb +10 -10
  33. data/spec/core/conj2_spec.rb +7 -7
  34. data/spec/core/cons_cell_spec.rb +35 -0
  35. data/spec/core/cons_cell_visitor_spec.rb +144 -0
  36. data/spec/core/def_relation_spec.rb +6 -5
  37. data/spec/core/disj2_spec.rb +5 -5
  38. data/spec/core/duck_fiber_spec.rb +2 -2
  39. data/spec/core/equals_spec.rb +34 -21
  40. data/spec/core/goal_spec.rb +2 -2
  41. data/spec/core/k_boolean_spec.rb +6 -0
  42. data/spec/core/k_symbol_spec.rb +4 -0
  43. data/spec/core/outcome_spec.rb +8 -0
  44. data/spec/core/variable_ref_spec.rb +3 -0
  45. data/spec/glue/dsl_chap1_spec.rb +679 -0
  46. data/spec/glue/dsl_chap2_spec.rb +100 -0
  47. data/spec/glue/fresh_env_factory_spec.rb +97 -0
  48. data/spec/glue/run_star_expression_spec.rb +11 -11
  49. metadata +17 -4
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../spec_helper' # Use the RSpec framework
4
+
5
+ # Load the class under test
6
+ require_relative '../../lib/mini_kraken/glue/dsl'
7
+
8
+
9
+ module MiniKraken
10
+ module Glue
11
+ describe 'DSL (Chap 2)' do
12
+ include DSL
13
+
14
+ context 'Chapter 2 examples:' do
15
+ let(:acorn) { cons(:a, cons(:c, cons(:o, cons(:r, cons(:n))))) }
16
+
17
+ it 'accepts caro definition inspired from frame 2:6' do
18
+ # Reasoned S2, frame 2:6
19
+ # (defrel (caro p a)
20
+ # (fresh (d)
21
+ # (== (cons a d) p)))
22
+
23
+ # As 'p' has a special meaning in Ruby, the argument has been remaned to 'r'
24
+ caro_rel = defrel('caro', %w[r a]) do
25
+ fresh('d', equals(cons(a, d), r))
26
+ end
27
+
28
+ expect(caro_rel).to be_kind_of(Core::DefRelation)
29
+ expect(caro_rel.name).to eq('caro')
30
+ expect(caro_rel.arity).to eq(2)
31
+ expect(caro_rel.formals[0].name).to eq('r')
32
+ expect(caro_rel.formals[1].name).to eq('a')
33
+ g_template = caro_rel.goal_template
34
+ expect(g_template).to be_kind_of(FreshEnvFactory)
35
+ expect(g_template.names).to include('d')
36
+ end
37
+
38
+ # In Scheme:
39
+ # (defrel (caro p a)
40
+ # (fresh (d)
41
+ # (== (cons a d) p)))
42
+ # In Ruby, `p`is a stnadard Kernel method => replaced by `r`
43
+ def defrel_caro
44
+ defrel('caro', %w[r a]) { fresh('d', equals(cons(a, d), r)) }
45
+ end
46
+
47
+ it 'passes frame 2:3' do
48
+ defrel_caro
49
+
50
+ # (run* q
51
+ # (caro '(a c o r n) q)) ;; => (a)
52
+ result = run_star('q', caro(acorn, q))
53
+ expect(result.car).to eq(:a)
54
+ end
55
+
56
+ it 'passes frame 2:4' do
57
+ defrel_caro
58
+
59
+ # (run* q
60
+ # (caro '(a c o r n) 'a)) ;; => (_0)
61
+ result = run_star('q', caro(acorn, :a))
62
+ expect(result.car).to eq(:_0)
63
+ end
64
+
65
+ it 'passes frame 2:5' do
66
+ defrel_caro
67
+
68
+ # (run* r
69
+ # (fresh (x y)
70
+ # (caro '(,r ,y) x)
71
+ # (== 'pear x)));; r => (pear)
72
+ result = run_star('r', fresh(%w[x y],
73
+ [caro(cons(r, cons(y)), x),
74
+ equals(:pear, x)]))
75
+ expect(result.car).to eq(:pear)
76
+ end
77
+
78
+ it 'passes frame 2:8' do
79
+ defrel_caro
80
+
81
+ # (run* r
82
+ # (fresh (x y)
83
+ # (caro '(grape raisin pear) x)
84
+ # (caro '((a) (b) (c)) y)
85
+ # (== (cons x y) r))) ;; r => ((grape a))
86
+ fruits = cons(:grape, cons(:raisin, cons(:pear)))
87
+ expect(fruits.to_s).to eq('(:grape :raisin :pear)')
88
+ abc = cons(cons(:a), cons(cons(:b), cons(cons(:c))))
89
+ expect(abc.to_s).to eq('((:a) (:b) (:c))')
90
+
91
+ result = run_star('r', fresh(%w[x y],
92
+ [caro(fruits, x),
93
+ caro(abc, y),
94
+ equals(cons(x, y), r)]))
95
+ expect(result.car).to eq(cons(:grape, cons(:a)))
96
+ end
97
+ end # context
98
+ end # describe
99
+ end # module
100
+ end # module
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../lib/mini_kraken/core/equals'
4
+ require_relative '../../lib/mini_kraken/core/formal_arg'
5
+ require_relative '../../lib/mini_kraken/core/formal_ref'
6
+ require_relative '../../lib/mini_kraken/core/goal_template'
7
+
8
+ require_relative '../support/factory_methods'
9
+
10
+ # Load the class under test
11
+ require_relative '../../lib/mini_kraken/glue/fresh_env_factory'
12
+
13
+
14
+ module MiniKraken
15
+ module Glue
16
+ describe FreshEnvFactory do
17
+ include FactoryMethods
18
+
19
+ # (fresh (d) (== d r))
20
+ let(:r_formal_ref) { Core::FormalRef.new('r') }
21
+ let(:d_ref) { var_ref('d') }
22
+ let(:sample_goal_t) do
23
+ Core::GoalTemplate.new(Core::Equals.instance, [d_ref, r_formal_ref])
24
+ end
25
+ subject { FreshEnvFactory.new(['d'], sample_goal_t) }
26
+
27
+ context 'Initialization:' do
28
+ it 'should be initialized with names and a goal template' do
29
+ expect { FreshEnvFactory.new(['d'], sample_goal_t) }.not_to raise_error
30
+ end
31
+
32
+ it 'should know the variable names' do
33
+ expect(subject.names).to eq(['d'])
34
+ end
35
+
36
+ it 'should know the goal template' do
37
+ expect(subject.goal_template).to eq(sample_goal_t)
38
+ end
39
+ end # context
40
+
41
+ context 'Factory for FreshEnv instances' do
42
+ # (defrel (caro r a)
43
+ # (fresh (d)
44
+ # (== (cons a d) r)))
45
+ # ;; r, a are formal args, they part of caro signature
46
+ # ;; d is a formal ref argument
47
+ let(:pea) { k_symbol(:pea) }
48
+ let(:q_ref) { var_ref('q') }
49
+ let(:r_formal) { Core::FormalRef.new('r') }
50
+ let(:a_formal) { Core::FormalRef.new('a') }
51
+ let(:t_param1) { Core::ConsCell.new(a_formal, d_ref) }
52
+ let(:other_goal_t) do
53
+ Core::GoalTemplate.new(Core::Equals.instance, [t_param1, r_formal])
54
+ end
55
+
56
+ # (fresh (d) (== d r))
57
+ it 'should build FreshEnv instance with simple goal' do
58
+ created = subject.instantiate([r_formal], [pea])
59
+
60
+ # Are variables correctly built?
61
+ expect(created).to be_kind_of(FreshEnv)
62
+ expect(created.vars['d']).to be_kind_of(Core::Variable)
63
+
64
+ # Is the goal correectly built?
65
+ goal = created.goal
66
+ expect(goal.relation).to eq(Core::Equals.instance)
67
+ expect(goal.actuals[0]).to be_kind_of(Core::VariableRef)
68
+ expect(goal.actuals[0].name).to eq('d')
69
+ expect(goal.actuals[1]).to be_kind_of(Core::KSymbol)
70
+ expect(goal.actuals[1]).to eq(:pea)
71
+ end
72
+
73
+ it 'should build FreshEnv instance with goal' do
74
+ instance = FreshEnvFactory.new(['d'], other_goal_t)
75
+ acorn = cons(k_symbol(:a), cons(k_symbol(:c), cons(k_symbol(:o),
76
+ cons(k_symbol(:r), cons(k_symbol(:n))))))
77
+ created = instance.instantiate([r_formal, a_formal], [acorn, q_ref])
78
+
79
+ # Are variables correctly built?
80
+ expect(created).to be_kind_of(FreshEnv)
81
+ expect(created.vars['d']).to be_kind_of(Core::Variable)
82
+
83
+ # Is the goal correctly built?
84
+ goal = created.goal
85
+ expect(goal.relation).to eq(Core::Equals.instance)
86
+ expect(goal.actuals[0]).to be_kind_of(Core::ConsCell)
87
+ expect(goal.actuals[0].car).to be_kind_of(Core::VariableRef)
88
+ expect(goal.actuals[0].car.name).to eq('q')
89
+ expect(goal.actuals[0].cdr).to be_kind_of(Core::VariableRef)
90
+ expect(goal.actuals[0].cdr.name).to eq('d')
91
+ expect(goal.actuals[1]).to be_kind_of(Core::ConsCell)
92
+ expect(goal.actuals[1].to_s).to eq('(:a :c :o :r :n)')
93
+ end
94
+ end # context
95
+ end # describe
96
+ end # module
97
+ end # module
@@ -23,6 +23,7 @@ module MiniKraken
23
23
  module Glue
24
24
  describe RunStarExpression do
25
25
  include FactoryMethods
26
+
26
27
  let(:pea) { k_symbol(:pea) }
27
28
  let(:pod) { k_symbol(:pod) }
28
29
  let(:sample_goal) { equals_goal(pea, pod) }
@@ -126,6 +127,7 @@ module MiniKraken
126
127
 
127
128
  it 'should return a null list with the succeed goal' do
128
129
  instance = RunStarExpression.new('q', succeeds)
130
+ expect(instance.env.vars).to be_include('q')
129
131
 
130
132
  # (display (run* q succeed)) ;; => (_0)
131
133
  # Reasoned S2, frame 1:16
@@ -243,7 +245,7 @@ module MiniKraken
243
245
  instance = RunStarExpression.new('q', goal)
244
246
 
245
247
  # Reasoned S2, frame 1:34
246
- # (run* q (== '(((,q)) pod) `(((pea)) pod))) ;; => ('pod)
248
+ # (run* q (== '(((,q)) pod) `(((pea)) pod))) ;; => ('pea)
247
249
  result = instance.run
248
250
  expect(result.car).to eq(pea)
249
251
  end
@@ -264,8 +266,8 @@ module MiniKraken
264
266
  it 'should unify complex equality expressions (IV)' do
265
267
  # Reasoned S2, frame 1:36
266
268
  # (run* q (fresh (x) (== '(((,q)) (,x)) `(((,x)) pod)))) ;; => ('pod)
267
- expr1 = cons(cons(cons(ref_q)), ref_x)
268
- expr2 = cons(cons(cons(ref_x)), pod)
269
+ expr1 = cons(cons(cons(ref_q)), cons(ref_x))
270
+ expr2 = cons(cons(cons(ref_x)), cons(pod))
269
271
  goal = equals_goal(expr1, expr2)
270
272
  fresh_env = FreshEnv.new(['x'], goal)
271
273
  instance = RunStarExpression.new('q', fresh_env)
@@ -362,7 +364,6 @@ module MiniKraken
362
364
  expect(result.car).to eq(any_value(0))
363
365
  end
364
366
 
365
- # TODO: fix erratic RSpec failure
366
367
  it 'should support conjunction of one succeed and a successful goal' do
367
368
  subgoal = equals_goal(corn, ref_q)
368
369
  goal = conj2_goal(succeeds, subgoal)
@@ -480,7 +481,7 @@ module MiniKraken
480
481
  # Reasoned S2, frame 1:62
481
482
  # (run* x (disj2
482
483
  # (conj2 (== 'olive x) fail)
483
- # ('oil x))) ;; => (oil)
484
+ # (== 'oil x))) ;; => (oil)
484
485
  result = instance.run
485
486
  expect(result.car).to eq(oil)
486
487
  end
@@ -510,7 +511,7 @@ module MiniKraken
510
511
 
511
512
  # Reasoned S2, frame 1:64
512
513
  # (run* x (disj2
513
- # ('oil x)
514
+ # (== 'oil x)
514
515
  # (conj2 (== 'olive x) succeed))) ;; => (oil olive)
515
516
  result = instance.run
516
517
  expect(result.car).to eq(oil)
@@ -529,11 +530,11 @@ module MiniKraken
529
530
 
530
531
  # Reasoned S2, frame 1:65
531
532
  # (run* x (disj2
532
- # (conj2(== 'virgin x) fails)
533
+ # (conj2(== 'virgin x) fail)
533
534
  # (disj2
534
535
  # (== 'olive x)
535
536
  # (dis2
536
- # succeeds
537
+ # succeed
537
538
  # (== 'oil x))))) ;; => (olive _0 oil)
538
539
  result = instance.run
539
540
  expect(result.car).to eq(olive)
@@ -648,7 +649,7 @@ module MiniKraken
648
649
  expect(result.car.cdr.cdr.cdr).to be_nil
649
650
  end
650
651
 
651
- it 'should allow simplication of expressions' do
652
+ it 'should allow simplification of expressions' do
652
653
  expr1 = equals_goal(split, ref_x)
653
654
  expr2 = equals_goal(pea, ref_y)
654
655
  goal = conj2_goal(expr1, expr2)
@@ -968,8 +969,7 @@ module MiniKraken
968
969
  # ((== x y)))) ;; => ((_0 _1)(_0 _0))
969
970
  result = instance.run
970
971
  expect(result.car).to eq(cons(any_value(0), cons(any_value(1))))
971
- # Bug: next line fails
972
- # expect(result.cdr.car).to eq(cons(any_value(0), cons(any_value(0))))
972
+ expect(result.cdr.car).to eq(cons(any_value(0), cons(any_value(0))))
973
973
  end
974
974
 
975
975
  it 'accepts conde with more than two condition lines' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_kraken
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.12
4
+ version: 0.2.03
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-29 00:00:00.000000000 Z
11
+ date: 2020-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -61,6 +61,7 @@ extra_rdoc_files:
61
61
  - README.md
62
62
  files:
63
63
  - ".rspec"
64
+ - ".rubocop.yml"
64
65
  - ".travis.yml"
65
66
  - CHANGELOG.md
66
67
  - Gemfile
@@ -79,6 +80,7 @@ files:
79
80
  - lib/mini_kraken/core/conde.rb
80
81
  - lib/mini_kraken/core/conj2.rb
81
82
  - lib/mini_kraken/core/cons_cell.rb
83
+ - lib/mini_kraken/core/cons_cell_visitor.rb
82
84
  - lib/mini_kraken/core/def_relation.rb
83
85
  - lib/mini_kraken/core/designation.rb
84
86
  - lib/mini_kraken/core/disj2.rb
@@ -104,15 +106,19 @@ files:
104
106
  - lib/mini_kraken/core/variable.rb
105
107
  - lib/mini_kraken/core/variable_ref.rb
106
108
  - lib/mini_kraken/core/vocabulary.rb
109
+ - lib/mini_kraken/glue/dsl.rb
107
110
  - lib/mini_kraken/glue/fresh_env.rb
111
+ - lib/mini_kraken/glue/fresh_env_factory.rb
108
112
  - lib/mini_kraken/glue/run_star_expression.rb
109
113
  - lib/mini_kraken/version.rb
110
114
  - mini_kraken.gemspec
115
+ - spec/.rubocop.yml
111
116
  - spec/core/association_spec.rb
112
117
  - spec/core/association_walker_spec.rb
113
118
  - spec/core/conde_spec.rb
114
119
  - spec/core/conj2_spec.rb
115
120
  - spec/core/cons_cell_spec.rb
121
+ - spec/core/cons_cell_visitor_spec.rb
116
122
  - spec/core/def_relation_spec.rb
117
123
  - spec/core/disj2_spec.rb
118
124
  - spec/core/duck_fiber_spec.rb
@@ -128,6 +134,9 @@ files:
128
134
  - spec/core/variable_ref_spec.rb
129
135
  - spec/core/variable_spec.rb
130
136
  - spec/core/vocabulary_spec.rb
137
+ - spec/glue/dsl_chap1_spec.rb
138
+ - spec/glue/dsl_chap2_spec.rb
139
+ - spec/glue/fresh_env_factory_spec.rb
131
140
  - spec/glue/fresh_env_spec.rb
132
141
  - spec/glue/run_star_expression_spec.rb
133
142
  - spec/mini_kraken_spec.rb
@@ -144,9 +153,9 @@ require_paths:
144
153
  - lib
145
154
  required_ruby_version: !ruby/object:Gem::Requirement
146
155
  requirements:
147
- - - ">="
156
+ - - "~>"
148
157
  - !ruby/object:Gem::Version
149
- version: '0'
158
+ version: '2.4'
150
159
  required_rubygems_version: !ruby/object:Gem::Requirement
151
160
  requirements:
152
161
  - - ">="
@@ -163,6 +172,7 @@ test_files:
163
172
  - spec/core/conde_spec.rb
164
173
  - spec/core/conj2_spec.rb
165
174
  - spec/core/cons_cell_spec.rb
175
+ - spec/core/cons_cell_visitor_spec.rb
166
176
  - spec/core/def_relation_spec.rb
167
177
  - spec/core/disj2_spec.rb
168
178
  - spec/core/duck_fiber_spec.rb
@@ -178,6 +188,9 @@ test_files:
178
188
  - spec/core/variable_ref_spec.rb
179
189
  - spec/core/variable_spec.rb
180
190
  - spec/core/vocabulary_spec.rb
191
+ - spec/glue/dsl_chap1_spec.rb
192
+ - spec/glue/dsl_chap2_spec.rb
193
+ - spec/glue/fresh_env_factory_spec.rb
181
194
  - spec/glue/fresh_env_spec.rb
182
195
  - spec/glue/run_star_expression_spec.rb
183
196
  - spec/mini_kraken_spec.rb