mini_kraken 0.1.08 → 0.1.09
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/mini_kraken/core/conj2.rb +2 -3
- data/lib/mini_kraken/core/equals.rb +2 -2
- data/lib/mini_kraken/glue/fresh_env.rb +39 -3
- data/lib/mini_kraken/glue/run_star_expression.rb +42 -26
- data/lib/mini_kraken/version.rb +1 -1
- data/spec/glue/fresh_env_spec.rb +27 -1
- data/spec/glue/run_star_expression_spec.rb +165 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10a0607b5621effb10eab26d64ff7f52228f93e9c7907b91488613c1d72469aa
|
4
|
+
data.tar.gz: 9b43c9b0d729f2c7944be72f6599decae48d977ea0be5257a365111508473ef9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32c14d82b93ddf21d2b369745b1e556faf1736b53fd7f1782809370777e059c498e1d8347806dc2135aab3bedf429c8d2b93b5f9be4b9b361f86926edb1be20f
|
7
|
+
data.tar.gz: 9b82b3afd53af4da54042f8a8852367250bc8225c1229b31486b4e8223ca533d55f3dcc6250c4de4c03d0d84b77a5e5cf737a6c151f734d7a08334ac442fa330
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## [0.1.09] - 2020-06-06
|
2
|
+
- Supports frames from "The Reasoned Scheme" book up to frame [1:76]
|
3
|
+
|
4
|
+
### CHANGED
|
5
|
+
- Method `FreshEnv#initialize`accepts an array of goals as second argument. This array is transformed into a conjunction of goals.
|
6
|
+
- Method `RunStarExpression#initialize` accepts multiple multiple variable names and goals.
|
7
|
+
- Method `RunStarExpression#run` can handle solutions with multiple variables.
|
8
|
+
|
1
9
|
## [0.1.08] - 2020-05-30
|
2
10
|
- Fix of nasty bug (object aliasing) that caused flaky failures in specs.
|
3
11
|
|
@@ -31,12 +31,11 @@ unless MiniKraken::Core.constants(false).include? :Conj2
|
|
31
31
|
# @param g2 [Goal] Second goal argument
|
32
32
|
# @param voc [Vocabulary] A vocabulary object
|
33
33
|
def conjunction(g1, g2, voc)
|
34
|
-
# require 'debug'
|
35
|
-
outcome1 = nil
|
36
|
-
outcome2 = nil
|
37
34
|
if g1.relation.kind_of?(Fail) || g2.relation.kind_of?(Fail)
|
38
35
|
Fiber.yield Outcome.new(:"#u", voc)
|
39
36
|
else
|
37
|
+
outcome1 = nil
|
38
|
+
outcome2 = nil
|
40
39
|
f1 = g1.attain(voc)
|
41
40
|
loop do
|
42
41
|
outcome1 = f1.resume
|
@@ -1,10 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../core/environment'
|
4
|
+
require_relative '../core/conj2'
|
4
5
|
require_relative '../core/variable'
|
5
6
|
|
6
7
|
module MiniKraken
|
7
8
|
module Glue
|
9
|
+
# A combination of an Environment (= a scope for one or more variables)
|
10
|
+
# and a goal. It quacks like a Goal object: when receiving the attain message,
|
11
|
+
# it attempt to achieve its given goal.
|
8
12
|
# (fresh (x) (== 'pea q))
|
9
13
|
# Introduces the new variable 'x'
|
10
14
|
# Takes a list of names and a goal-like object
|
@@ -13,11 +17,11 @@ module MiniKraken
|
|
13
17
|
# @return [Goal]
|
14
18
|
attr_reader :goal
|
15
19
|
|
16
|
-
# @param theNames [Array<String>]
|
17
|
-
# @param aGoal [Goal]
|
20
|
+
# @param theNames [Array<String>] The variable names
|
21
|
+
# @param aGoal [Goal, Array<Goal>] The goal to achieve or the conjunction of them.
|
18
22
|
def initialize(theNames, aGoal)
|
19
23
|
super()
|
20
|
-
@goal = aGoal
|
24
|
+
@goal = valid_goal(aGoal)
|
21
25
|
theNames.each { |nm| add_var(Core::Variable.new(nm)) }
|
22
26
|
end
|
23
27
|
|
@@ -28,6 +32,38 @@ module MiniKraken
|
|
28
32
|
self.parent = aParent
|
29
33
|
goal.attain(self)
|
30
34
|
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def valid_goal(aGoal)
|
39
|
+
result = nil
|
40
|
+
|
41
|
+
case aGoal
|
42
|
+
when Core::Goal
|
43
|
+
result = aGoal
|
44
|
+
when FreshEnv
|
45
|
+
result = aGoal
|
46
|
+
when Array # an Array of Goal?..
|
47
|
+
goal_array = aGoal
|
48
|
+
loop do
|
49
|
+
conjunctions = []
|
50
|
+
goal_array.each_slice(2) do |uno_duo|
|
51
|
+
if uno_duo.size == 2
|
52
|
+
conjunctions << Core::Goal.new(Core::Conj2.instance, uno_duo)
|
53
|
+
else
|
54
|
+
conjunctions << uno_duo[0]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
if conjunctions.size == 1
|
58
|
+
result = conjunctions[0]
|
59
|
+
break
|
60
|
+
end
|
61
|
+
goal_array = conjunctions
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
result
|
66
|
+
end
|
31
67
|
end # class
|
32
68
|
end # module
|
33
69
|
end # module
|
@@ -9,19 +9,15 @@ module MiniKraken
|
|
9
9
|
class RunStarExpression
|
10
10
|
attr_reader :env
|
11
11
|
|
12
|
-
# @param
|
13
|
-
# @param goal [Core::Goal]
|
14
|
-
def initialize(
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
def var
|
19
|
-
env.vars.values.first
|
12
|
+
# @param var_names [String, Array<String>] One variable name or an array of names
|
13
|
+
# @param goal [Core::Goal, Array<Core::Goal>] A single goal or an array of goals to conjunct
|
14
|
+
def initialize(var_names, goal)
|
15
|
+
vnames = var_names.kind_of?(String) ? [var_names] : var_names
|
16
|
+
@env = FreshEnv.new(vnames, goal)
|
20
17
|
end
|
21
18
|
|
22
19
|
def run
|
23
|
-
result =
|
24
|
-
next_result = nil
|
20
|
+
result = []
|
25
21
|
solver = env.goal.attain(env)
|
26
22
|
# require 'debug'
|
27
23
|
loop do
|
@@ -30,24 +26,44 @@ module MiniKraken
|
|
30
26
|
outcome = solver.resume
|
31
27
|
break if outcome.nil?
|
32
28
|
|
33
|
-
if result
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
29
|
+
env.propagate(outcome) if result.empty? && outcome.successful?
|
30
|
+
result << build_solution(outcome)
|
31
|
+
end
|
32
|
+
|
33
|
+
format_solutions(result)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# @return [Array] A vector of assignment for each variable
|
39
|
+
def build_solution(outcome)
|
40
|
+
sol = env.vars.values.map do |var|
|
41
|
+
outcome.successful? ? var.quote(outcome) : nil
|
42
|
+
end
|
43
|
+
|
44
|
+
sol
|
45
|
+
end
|
46
|
+
|
47
|
+
# Transform the solutions into sequence of conscells.
|
48
|
+
# @param solutions [Array<Array>] An array of solution.
|
49
|
+
# A solution is in itself an array of bindings (one per variable)
|
50
|
+
def format_solutions(solutions)
|
51
|
+
solutions_as_list = solutions.map { |sol| arr2list(sol, true) }
|
52
|
+
arr2list(solutions_as_list, false)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Utility method. Transform an array into a ConsCell-based list.
|
56
|
+
# @param anArray [Array]
|
57
|
+
# @param simplify [Boolean]
|
58
|
+
def arr2list(anArray, simplify)
|
59
|
+
return anArray[0] if anArray.size == 1 && simplify
|
60
|
+
|
61
|
+
new_tail = nil
|
62
|
+
anArray.reverse_each do |elem|
|
63
|
+
new_tail = Core::ConsCell.new(elem, new_tail)
|
48
64
|
end
|
49
65
|
|
50
|
-
|
66
|
+
new_tail
|
51
67
|
end
|
52
68
|
end # class
|
53
69
|
end # module
|
data/lib/mini_kraken/version.rb
CHANGED
data/spec/glue/fresh_env_spec.rb
CHANGED
@@ -3,7 +3,9 @@
|
|
3
3
|
require_relative '../spec_helper' # Use the RSpec framework
|
4
4
|
require_relative '../../lib/mini_kraken/core/goal'
|
5
5
|
require_relative '../../lib/mini_kraken/core/equals'
|
6
|
+
require_relative '../../lib/mini_kraken/core/fail'
|
6
7
|
require_relative '../../lib/mini_kraken/core/k_symbol'
|
8
|
+
require_relative '../../lib/mini_kraken/core/succeed'
|
7
9
|
|
8
10
|
# Load the class under test
|
9
11
|
require_relative '../../lib/mini_kraken/glue/fresh_env'
|
@@ -17,15 +19,39 @@ module MiniKraken
|
|
17
19
|
let(:sample_goal) do
|
18
20
|
Core::Goal.new(Core::Equals.instance, [pea, pod])
|
19
21
|
end
|
22
|
+
let(:pea_goal) do
|
23
|
+
Core::Goal.new(Core::Equals.instance, [pea, pea])
|
24
|
+
end
|
25
|
+
let(:goal_succeeds) { Core::Goal.new(Core::Succeed.instance, []) }
|
26
|
+
let(:goal_fails) { Core::Goal.new(Core::Fail.instance, []) }
|
20
27
|
subject { FreshEnv.new(['q'], sample_goal) }
|
21
28
|
|
22
29
|
context 'Initialization:' do
|
23
|
-
it '
|
30
|
+
it 'could be initialized with names and a goal' do
|
24
31
|
expect { FreshEnv.new(['q'], sample_goal) }.not_to raise_error
|
25
32
|
end
|
26
33
|
|
34
|
+
it 'could be initialized with names and goals' do
|
35
|
+
expect { FreshEnv.new(%w[x y], [pea_goal, goal_succeeds]) }.not_to raise_error
|
36
|
+
end
|
37
|
+
|
27
38
|
it 'should know its variables' do
|
28
39
|
expect(subject.vars['q']).not_to be_nil
|
40
|
+
|
41
|
+
instance = FreshEnv.new(%w[x y], sample_goal)
|
42
|
+
expect(instance.vars['x']).not_to be_nil
|
43
|
+
expect(instance.vars['y']).not_to be_nil
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should know its goal' do
|
47
|
+
# Single goal at initialization
|
48
|
+
expect(subject.goal).to eq(sample_goal)
|
49
|
+
|
50
|
+
# Multiple goals at initialization
|
51
|
+
instance = FreshEnv.new(['q'], [pea_goal, goal_succeeds])
|
52
|
+
expect(instance.goal.relation.name).to eq('conj2')
|
53
|
+
expect(instance.goal.actuals[0]).to eq(pea_goal)
|
54
|
+
expect(instance.goal.actuals[1]).to eq(goal_succeeds)
|
29
55
|
end
|
30
56
|
end # context
|
31
57
|
|
@@ -21,16 +21,26 @@ module MiniKraken
|
|
21
21
|
let(:pea) { k_symbol(:pea) }
|
22
22
|
let(:pod) { k_symbol(:pod) }
|
23
23
|
let(:sample_goal) { equals_goal(pea, pod) }
|
24
|
+
let(:fails) { Core::Goal.new(Core::Fail.instance, []) }
|
25
|
+
let(:succeeds) { Core::Goal.new(Core::Succeed.instance, []) }
|
24
26
|
subject { RunStarExpression.new('q', sample_goal) }
|
25
27
|
|
26
28
|
context 'Initialization:' do
|
27
|
-
it '
|
29
|
+
it 'could be initialized with a name and a goal' do
|
28
30
|
expect { RunStarExpression.new('q', sample_goal) }.not_to raise_error
|
29
31
|
end
|
30
32
|
|
33
|
+
it 'could be initialized with multiple names and a goal' do
|
34
|
+
expect { RunStarExpression.new(%w[r x y], sample_goal) }.not_to raise_error
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'could be initialized with multiple names and goals' do
|
38
|
+
expect { RunStarExpression.new(%w[r x y], [succeeds, succeeds]) }.not_to raise_error
|
39
|
+
end
|
40
|
+
|
31
41
|
it 'should know its variables' do
|
32
42
|
expect(subject.env.vars['q']).not_to be_nil
|
33
|
-
expect(subject.
|
43
|
+
expect(subject.env.vars.values[0].name).to eq('q')
|
34
44
|
end
|
35
45
|
|
36
46
|
it 'should know its goal' do
|
@@ -39,19 +49,22 @@ module MiniKraken
|
|
39
49
|
end # context
|
40
50
|
|
41
51
|
context 'Provided services:' do
|
52
|
+
let(:bean) { k_symbol(:bean) }
|
42
53
|
let(:corn) { k_symbol(:corn) }
|
43
54
|
let(:meal) { k_symbol(:meal) }
|
44
55
|
let(:oil) { k_symbol(:oil) }
|
45
56
|
let(:olive) { k_symbol(:olive) }
|
57
|
+
let(:red) { k_symbol(:red) }
|
58
|
+
let(:soup) { k_symbol(:soup) }
|
59
|
+
let(:split) { k_symbol(:split) }
|
46
60
|
let(:virgin) { k_symbol(:virgin) }
|
47
61
|
let(:ref_q) { Core::VariableRef.new('q') }
|
62
|
+
let(:ref_r) { Core::VariableRef.new('r') }
|
48
63
|
let(:ref_x) { Core::VariableRef.new('x') }
|
49
64
|
let(:ref_y) { Core::VariableRef.new('y') }
|
50
65
|
let(:ref_s) { Core::VariableRef.new('s') }
|
51
66
|
let(:ref_t) { Core::VariableRef.new('t') }
|
52
67
|
let(:ref_u) { Core::VariableRef.new('u') }
|
53
|
-
let(:fails) { Core::Goal.new(Core::Fail.instance, []) }
|
54
|
-
let(:succeeds) { Core::Goal.new(Core::Succeed.instance, []) }
|
55
68
|
|
56
69
|
it 'should return a null list with the fail goal' do
|
57
70
|
# Reasoned S2, frame 1:7
|
@@ -386,7 +399,7 @@ module MiniKraken
|
|
386
399
|
instance = RunStarExpression.new('q', goal)
|
387
400
|
|
388
401
|
# Reasoned S2, frame 1:56
|
389
|
-
# (run* q (disj2 (
|
402
|
+
# (run* q (disj2 (== 'olive q) fail)) ;; => ('olive)
|
390
403
|
result = instance.run
|
391
404
|
expect(result.car).to eq(olive)
|
392
405
|
end
|
@@ -397,7 +410,7 @@ module MiniKraken
|
|
397
410
|
instance = RunStarExpression.new('q', goal)
|
398
411
|
|
399
412
|
# Reasoned S2, frame 1:57
|
400
|
-
# (run* q (disj2 fail (
|
413
|
+
# (run* q (disj2 fail (== 'oil q))) ;; => (oil)
|
401
414
|
result = instance.run
|
402
415
|
expect(result.car).to eq(oil)
|
403
416
|
end
|
@@ -409,7 +422,7 @@ module MiniKraken
|
|
409
422
|
instance = RunStarExpression.new('q', goal)
|
410
423
|
|
411
424
|
# Reasoned S2, frame 1:58
|
412
|
-
# (run* q (disj2 (
|
425
|
+
# (run* q (disj2 (== 'olive q) (== 'oil q))) ;; => (olive oil)
|
413
426
|
result = instance.run
|
414
427
|
expect(result.car).to eq(olive)
|
415
428
|
expect(result.cdr.car).to eq(oil)
|
@@ -504,6 +517,151 @@ module MiniKraken
|
|
504
517
|
expect(result.cdr.car).to eq(any_value(0))
|
505
518
|
expect(result.cdr.cdr.car).to eq(oil)
|
506
519
|
end
|
520
|
+
|
521
|
+
it 'should accept nesting fresh, disj2 and conj2 expressions (I)' do
|
522
|
+
subgoal1 = equals_goal(split, ref_x)
|
523
|
+
expr1 = equals_goal(pea, ref_y)
|
524
|
+
expr2 = equals_goal(cons(ref_x, cons(ref_y)), ref_r)
|
525
|
+
subgoal2 = conj2_goal(expr1, expr2)
|
526
|
+
goal = conj2_goal(subgoal1, subgoal2)
|
527
|
+
fresh_env_y = FreshEnv.new(['y'], goal)
|
528
|
+
fresh_env_x = FreshEnv.new(['x'], fresh_env_y)
|
529
|
+
instance = RunStarExpression.new('r', fresh_env_x)
|
530
|
+
|
531
|
+
# Reasoned S2, frame 1:67
|
532
|
+
# (run* r
|
533
|
+
# (fresh x
|
534
|
+
# (fresh y
|
535
|
+
# (conj2
|
536
|
+
# (== 'split x)
|
537
|
+
# (conj2
|
538
|
+
# (== 'pea y)
|
539
|
+
# (== '(,x ,y) r)))))) ;; => ((split pea))
|
540
|
+
result = instance.run
|
541
|
+
expect(result.car.car).to eq(split)
|
542
|
+
expect(result.car.cdr.car).to eq(pea)
|
543
|
+
end
|
544
|
+
|
545
|
+
it 'should accept nesting fresh, disj2 and conj2 expressions (II)' do
|
546
|
+
expr1 = equals_goal(split, ref_x)
|
547
|
+
expr2 = equals_goal(pea, ref_y)
|
548
|
+
subgoal1 = conj2_goal(expr1, expr2)
|
549
|
+
subgoal2 = equals_goal(cons(ref_x, cons(ref_y)), ref_r)
|
550
|
+
goal = conj2_goal(subgoal1, subgoal2)
|
551
|
+
fresh_env_y = FreshEnv.new(['y'], goal)
|
552
|
+
fresh_env_x = FreshEnv.new(['x'], fresh_env_y)
|
553
|
+
instance = RunStarExpression.new('r', fresh_env_x)
|
554
|
+
|
555
|
+
# Reasoned S2, frame 1:68
|
556
|
+
# (run* r
|
557
|
+
# (fresh x
|
558
|
+
# (fresh y
|
559
|
+
# (conj2
|
560
|
+
# (conj2
|
561
|
+
# (== 'split x)
|
562
|
+
# (== 'pea y)
|
563
|
+
# (== '(,x ,y) r)))))) ;; => ((split pea))
|
564
|
+
result = instance.run
|
565
|
+
expect(result.car.car).to eq(split)
|
566
|
+
expect(result.car.cdr.car).to eq(pea)
|
567
|
+
end
|
568
|
+
|
569
|
+
it 'should accept fresh with multiple variables' do
|
570
|
+
expr1 = equals_goal(split, ref_x)
|
571
|
+
expr2 = equals_goal(pea, ref_y)
|
572
|
+
subgoal1 = conj2_goal(expr1, expr2)
|
573
|
+
subgoal2 = equals_goal(cons(ref_x, cons(ref_y)), ref_r)
|
574
|
+
goal = conj2_goal(subgoal1, subgoal2)
|
575
|
+
fresh_env = FreshEnv.new(%w[x y], goal)
|
576
|
+
instance = RunStarExpression.new('r', fresh_env)
|
577
|
+
|
578
|
+
# Reasoned S2, frame 1:70
|
579
|
+
# (run* r
|
580
|
+
# (fresh (x y)
|
581
|
+
# (conj2
|
582
|
+
# (conj2
|
583
|
+
# (== 'split x)
|
584
|
+
# (== 'pea y)
|
585
|
+
# (== '(,x ,y) r))))) ;; => ((split pea))
|
586
|
+
result = instance.run
|
587
|
+
expect(result.car.car).to eq(split)
|
588
|
+
expect(result.car.cdr.car).to eq(pea)
|
589
|
+
end
|
590
|
+
|
591
|
+
it 'should accept multiple variables' do
|
592
|
+
expr1 = equals_goal(split, ref_x)
|
593
|
+
expr2 = equals_goal(pea, ref_y)
|
594
|
+
subgoal1 = conj2_goal(expr1, expr2)
|
595
|
+
subgoal2 = equals_goal(cons(ref_x, cons(ref_y)), ref_r)
|
596
|
+
goal = conj2_goal(subgoal1, subgoal2)
|
597
|
+
instance = RunStarExpression.new(%w[r x y], goal)
|
598
|
+
|
599
|
+
# Reasoned S2, frame 1:72
|
600
|
+
# (run* (r x y)
|
601
|
+
# (conj2
|
602
|
+
# (conj2
|
603
|
+
# (== 'split x)
|
604
|
+
# (== 'pea y))
|
605
|
+
# (== '(,x ,y) r))) ;; => (((split pea) split pea))
|
606
|
+
# o
|
607
|
+
# / \
|
608
|
+
# o nil
|
609
|
+
# / \
|
610
|
+
# / \
|
611
|
+
# / \
|
612
|
+
# / \
|
613
|
+
# / \
|
614
|
+
# o o
|
615
|
+
# / \ / \
|
616
|
+
# split o split o
|
617
|
+
# / \ / \
|
618
|
+
# pea nil pea nil
|
619
|
+
result = instance.run
|
620
|
+
expect(result.car.car.car).to eq(split)
|
621
|
+
expect(result.car.car.cdr.car).to eq(pea)
|
622
|
+
expect(result.car.car.cdr.cdr).to be_nil
|
623
|
+
expect(result.car.cdr.car).to eq(split)
|
624
|
+
expect(result.car.cdr.cdr.car).to eq(pea)
|
625
|
+
expect(result.car.cdr.cdr.cdr).to be_nil
|
626
|
+
end
|
627
|
+
|
628
|
+
it 'should allow simplication of expressions' do
|
629
|
+
expr1 = equals_goal(split, ref_x)
|
630
|
+
expr2 = equals_goal(pea, ref_y)
|
631
|
+
goal = conj2_goal(expr1, expr2)
|
632
|
+
instance = RunStarExpression.new(%w[x y], goal)
|
633
|
+
|
634
|
+
# Reasoned S2, frame 1:75
|
635
|
+
# (run* (x y)
|
636
|
+
# (conj2
|
637
|
+
# (== 'split x)
|
638
|
+
# (== 'pea y))) ;; => ((split pea))
|
639
|
+
result = instance.run
|
640
|
+
expect(result.car.car).to eq(split)
|
641
|
+
expect(result.car.cdr.car).to eq(pea)
|
642
|
+
end
|
643
|
+
|
644
|
+
it 'should allow simplication of expressions' do
|
645
|
+
expr1 = equals_goal(split, ref_x)
|
646
|
+
expr2 = equals_goal(pea, ref_y)
|
647
|
+
subgoal1 = conj2_goal(expr1, expr2)
|
648
|
+
expr3 = equals_goal(red, ref_x)
|
649
|
+
expr4 = equals_goal(bean, ref_y)
|
650
|
+
subgoal2 = conj2_goal(expr3, expr4)
|
651
|
+
goal = disj2_goal(subgoal1, subgoal2)
|
652
|
+
instance = RunStarExpression.new(%w[x y], goal)
|
653
|
+
|
654
|
+
# Reasoned S2, frame 1:76
|
655
|
+
# (run* (x y)
|
656
|
+
# (disj2
|
657
|
+
# (conj2 (== 'split x) (== 'pea y))
|
658
|
+
# (conj2 (== 'red x) (== 'bean y)))) ;; => ((split pea)(red bean))
|
659
|
+
result = instance.run
|
660
|
+
expect(result.car.car).to eq(split)
|
661
|
+
expect(result.car.cdr.car).to eq(pea)
|
662
|
+
expect(result.cdr.car.car).to eq(red)
|
663
|
+
expect(result.cdr.car.cdr.car).to eq(bean)
|
664
|
+
end
|
507
665
|
end # context
|
508
666
|
end # describe
|
509
667
|
end # module
|
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.
|
4
|
+
version: 0.1.09
|
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-
|
11
|
+
date: 2020-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|