mini_kraken 0.2.03 → 0.2.04
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 +9 -0
- data/lib/mini_kraken/atomic/all_atomic.rb +4 -0
- data/lib/mini_kraken/{core → atomic}/atomic_term.rb +23 -9
- data/lib/mini_kraken/atomic/k_boolean.rb +42 -0
- data/lib/mini_kraken/{core → atomic}/k_integer.rb +2 -1
- data/lib/mini_kraken/{core → atomic}/k_symbol.rb +5 -3
- data/lib/mini_kraken/{core → composite}/composite_term.rb +6 -4
- data/lib/mini_kraken/composite/cons_cell.rb +132 -0
- data/lib/mini_kraken/{core → composite}/cons_cell_visitor.rb +1 -1
- data/lib/mini_kraken/core/association_walker.rb +14 -14
- data/lib/mini_kraken/core/binary_relation.rb +10 -10
- data/lib/mini_kraken/core/equals.rb +159 -161
- data/lib/mini_kraken/core/goal_relation.rb +2 -2
- data/lib/mini_kraken/core/goal_template.rb +7 -7
- data/lib/mini_kraken/core/{variable.rb → log_var.rb} +10 -3
- data/lib/mini_kraken/core/{variable_ref.rb → log_var_ref.rb} +3 -3
- data/lib/mini_kraken/core/tap.rb +46 -0
- data/lib/mini_kraken/core/vocabulary.rb +8 -8
- data/lib/mini_kraken/glue/dsl.rb +21 -17
- data/lib/mini_kraken/glue/fresh_env.rb +7 -2
- data/lib/mini_kraken/glue/fresh_env_factory.rb +1 -1
- data/lib/mini_kraken/glue/run_star_expression.rb +2 -2
- data/lib/mini_kraken/version.rb +1 -1
- data/spec/.rubocop.yml +1 -1
- data/spec/atomic/atomic_term_spec.rb +94 -0
- data/spec/{core → atomic}/k_boolean_spec.rb +19 -34
- data/spec/{core → atomic}/k_symbol_spec.rb +3 -11
- data/spec/{core → composite}/cons_cell_spec.rb +10 -8
- data/spec/{core → composite}/cons_cell_visitor_spec.rb +11 -10
- data/spec/core/association_spec.rb +6 -4
- data/spec/core/association_walker_spec.rb +8 -6
- data/spec/core/conde_spec.rb +19 -17
- data/spec/core/conj2_spec.rb +10 -8
- data/spec/core/def_relation_spec.rb +9 -7
- data/spec/core/disj2_spec.rb +11 -10
- data/spec/core/environment_spec.rb +12 -10
- data/spec/core/equals_spec.rb +12 -10
- data/spec/core/goal_spec.rb +6 -5
- data/spec/core/goal_template_spec.rb +5 -5
- data/spec/core/{variable_ref_spec.rb → log_var_ref_spec.rb} +4 -4
- data/spec/core/{variable_spec.rb → log_var_spec.rb} +4 -4
- data/spec/core/vocabulary_spec.rb +12 -11
- data/spec/glue/dsl_chap1_spec.rb +0 -45
- data/spec/glue/dsl_chap2_spec.rb +115 -7
- data/spec/glue/fresh_env_factory_spec.rb +11 -9
- data/spec/glue/fresh_env_spec.rb +3 -3
- data/spec/glue/run_star_expression_spec.rb +13 -11
- data/spec/support/factory_atomic.rb +22 -0
- data/spec/support/factory_methods.rb +11 -26
- metadata +28 -23
- data/lib/mini_kraken/core/cons_cell.rb +0 -82
- data/lib/mini_kraken/core/k_boolean.rb +0 -35
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
require_relative 'duck_fiber'
|
5
|
+
require_relative 'goal'
|
6
|
+
require_relative 'goal_relation'
|
7
|
+
require_relative 'outcome'
|
8
|
+
|
9
|
+
module MiniKraken
|
10
|
+
module Core
|
11
|
+
class Tap < GoalRelation
|
12
|
+
include Singleton
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
super('tap', nil)
|
16
|
+
end
|
17
|
+
|
18
|
+
def arity
|
19
|
+
1
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param actuals [Array<Term>] A two-elements array
|
23
|
+
# @param anEnv [Vocabulary] A vocabulary object
|
24
|
+
# @return [Fiber<Outcome>] A Fiber that yields Outcomes objects
|
25
|
+
def solver_for(actuals, anEnv)
|
26
|
+
args = *validated_args(actuals)
|
27
|
+
DuckFiber.new(:custom) do
|
28
|
+
outcome = tap(args.first, anEnv)
|
29
|
+
# outcome.prune!
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def tap(aGoal, anEnv)
|
34
|
+
require 'debug'
|
35
|
+
f1 = aGoal.attain(anEnv)
|
36
|
+
outcome1 = f1.resume
|
37
|
+
# key = outcome1.associations.keys.first
|
38
|
+
# outcome1.associations['x'] = outcome1.associations[key]
|
39
|
+
# outcome1.associations.delete(key)
|
40
|
+
outcome1
|
41
|
+
end
|
42
|
+
end # class
|
43
|
+
|
44
|
+
Tap.instance.freeze
|
45
|
+
end # module
|
46
|
+
end # module
|
@@ -138,12 +138,12 @@ module MiniKraken
|
|
138
138
|
# Check that the provided variable must be fused with the argument.
|
139
139
|
# @return [Array<Variable>]
|
140
140
|
def detect_fuse(aVariable, aTerm)
|
141
|
-
return [] unless aTerm.kind_of?(
|
141
|
+
return [] unless aTerm.kind_of?(LogVarRef)
|
142
142
|
|
143
143
|
assocs = self[aTerm.var_name]
|
144
144
|
# Simplified implementation: cope with binary cycles only...
|
145
145
|
# TODO: Extend to n-ary (n > 2) cycles
|
146
|
-
assoc_refs = assocs.select { |a| a.value.kind_of?(
|
146
|
+
assoc_refs = assocs.select { |a| a.value.kind_of?(LogVarRef) }
|
147
147
|
return [] if assoc_refs.empty? # No relevant association...
|
148
148
|
|
149
149
|
visitees = Set.new
|
@@ -159,7 +159,7 @@ module MiniKraken
|
|
159
159
|
to_fuse << assc.i_name unless assc.i_name == aVariable.i_name
|
160
160
|
end
|
161
161
|
other_assocs = self[ref.var_name]
|
162
|
-
other_assoc_refs = other_assocs.select { |a| a.value.kind_of?(
|
162
|
+
other_assoc_refs = other_assocs.select { |a| a.value.kind_of?(LogVarRef) }
|
163
163
|
other_assoc_refs.each do |a|
|
164
164
|
to_visit << a unless visitess.include?(a)
|
165
165
|
end
|
@@ -192,7 +192,7 @@ module MiniKraken
|
|
192
192
|
if voc.associations.include?(old_i_name)
|
193
193
|
assocs = voc.associations[old_i_name]
|
194
194
|
keep_assocs = assocs.reject do |assc|
|
195
|
-
assc.value.kind_of?(
|
195
|
+
assc.value.kind_of?(LogVarRef) && old_names.include?(assc.value.var_name)
|
196
196
|
end
|
197
197
|
unless keep_assocs.empty?
|
198
198
|
keep_assocs.each { |assc| assc.i_name = new_i_name }
|
@@ -224,14 +224,14 @@ module MiniKraken
|
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
227
|
-
# @param var [Variable,
|
227
|
+
# @param var [Variable, LogVarRef] the variable to check.
|
228
228
|
# @return [Boolean]
|
229
229
|
def fresh?(var)
|
230
230
|
ground_term = ground_value(var)
|
231
231
|
ground_term.nil? ? true : false
|
232
232
|
end
|
233
233
|
|
234
|
-
# @param var [Variable,
|
234
|
+
# @param var [Variable, LogVarRef] variable for which the value to retrieve
|
235
235
|
# @return [Term, NilClass]
|
236
236
|
def ground_value(var)
|
237
237
|
name = var.respond_to?(:var_name) ? var.var_name : var.name
|
@@ -260,14 +260,14 @@ module MiniKraken
|
|
260
260
|
end
|
261
261
|
|
262
262
|
# Determine whether the reference points to a fresh, bound or ground term.
|
263
|
-
# @param aVariableRef [
|
263
|
+
# @param aVariableRef [LogVarRef]
|
264
264
|
# @return [Freshness]
|
265
265
|
def freshness_ref(aVariableRef)
|
266
266
|
walker = AssociationWalker.new
|
267
267
|
walker.determine_freshness(aVariableRef, self)
|
268
268
|
end
|
269
269
|
|
270
|
-
# @param aVariableRef [
|
270
|
+
# @param aVariableRef [LogVarRef]
|
271
271
|
# @return [Term, NilClass]
|
272
272
|
def quote_ref(aVariableRef)
|
273
273
|
walker = AssociationWalker.new
|
data/lib/mini_kraken/glue/dsl.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'set'
|
4
|
+
require_relative '../atomic/all_atomic'
|
4
5
|
require_relative '../core/any_value'
|
5
6
|
require_relative '../core/conde'
|
6
7
|
require_relative '../core/conj2'
|
7
|
-
require_relative '../
|
8
|
+
require_relative '../composite/cons_cell'
|
8
9
|
require_relative '../core/def_relation'
|
9
10
|
require_relative '../core/disj2'
|
10
11
|
require_relative '../core/equals'
|
@@ -14,10 +15,9 @@ require_relative '../core/formal_ref'
|
|
14
15
|
require_relative '../glue/fresh_env'
|
15
16
|
require_relative '../glue/fresh_env_factory'
|
16
17
|
require_relative '../core/goal_template'
|
17
|
-
require_relative '../core/k_boolean'
|
18
|
-
require_relative '../core/k_symbol'
|
19
18
|
require_relative '../core/succeed'
|
20
|
-
require_relative '../core/
|
19
|
+
require_relative '../core/tap'
|
20
|
+
require_relative '../core/log_var_ref'
|
21
21
|
require_relative 'fresh_env'
|
22
22
|
require_relative 'run_star_expression'
|
23
23
|
|
@@ -30,7 +30,7 @@ module MiniKraken
|
|
30
30
|
module DSL
|
31
31
|
# A run* expression tries to find all the solutions
|
32
32
|
# that meet the given goal.
|
33
|
-
# @return [
|
33
|
+
# @return [Composite::ConsCell] A list of solutions
|
34
34
|
def run_star(var_names, goal)
|
35
35
|
program = RunStarExpression.new(var_names, goal)
|
36
36
|
program.run
|
@@ -61,7 +61,7 @@ module MiniKraken
|
|
61
61
|
|
62
62
|
def cons(car_item, cdr_item = nil)
|
63
63
|
tail = cdr_item.nil? ? cdr_item : convert(cdr_item)
|
64
|
-
|
64
|
+
Composite::ConsCell.new(convert(car_item), tail)
|
65
65
|
end
|
66
66
|
|
67
67
|
def defrel(relationName, theFormals, &aGoalTemplateExpr)
|
@@ -107,7 +107,7 @@ module MiniKraken
|
|
107
107
|
end
|
108
108
|
FreshEnvFactory.new(vars, goal)
|
109
109
|
else
|
110
|
-
if var_names.kind_of?(String) || var_names.kind_of?(Core::
|
110
|
+
if var_names.kind_of?(String) || var_names.kind_of?(Core::LogVarRef)
|
111
111
|
vars = [var_names]
|
112
112
|
else
|
113
113
|
vars = var_names
|
@@ -121,14 +121,14 @@ module MiniKraken
|
|
121
121
|
return null if members.empty?
|
122
122
|
|
123
123
|
head = nil
|
124
|
-
members.reverse_each { |elem| head =
|
124
|
+
members.reverse_each { |elem| head = Composite::ConsCell.new(convert(elem), head) }
|
125
125
|
|
126
126
|
head
|
127
127
|
end
|
128
128
|
|
129
129
|
# @return [ConsCell] Returns an empty list, that is, a pair whose members are nil.
|
130
130
|
def null
|
131
|
-
|
131
|
+
Composite::ConsCell.new(nil, nil)
|
132
132
|
end
|
133
133
|
|
134
134
|
# @return [Core::Succeed] A goal that unconditionally succeeds.
|
@@ -136,6 +136,10 @@ module MiniKraken
|
|
136
136
|
goal_class.new(Core::Succeed.instance, [])
|
137
137
|
end
|
138
138
|
|
139
|
+
def tap(arg1)
|
140
|
+
goal_class.new(Core::Tap.instance, [convert(arg1)])
|
141
|
+
end
|
142
|
+
|
139
143
|
private
|
140
144
|
|
141
145
|
def convert(anArgument)
|
@@ -149,20 +153,20 @@ module MiniKraken
|
|
149
153
|
any_val.instance_variable_set(:@rank, rank)
|
150
154
|
converted = any_val
|
151
155
|
elsif anArgument.id2name =~ /^"#[ft]"$/
|
152
|
-
converted =
|
156
|
+
converted = Atomic::KBoolean.new(anArgument)
|
153
157
|
else
|
154
|
-
converted =
|
158
|
+
converted = Atomic::KSymbol.new(anArgument)
|
155
159
|
end
|
156
160
|
when String
|
157
161
|
if anArgument =~ /^#[ft]$/
|
158
|
-
converted =
|
162
|
+
converted = Atomic::KBoolean.new(anArgument)
|
159
163
|
else
|
160
164
|
msg = "Internal error: undefined conversion for #{anArgument.class}"
|
161
165
|
raise StandardError, msg
|
162
166
|
end
|
163
167
|
when false, true
|
164
|
-
converted =
|
165
|
-
when
|
168
|
+
converted = Atomic::KBoolean.new(anArgument)
|
169
|
+
when Atomic::KBoolean, Atomic::KSymbol
|
166
170
|
converted = anArgument
|
167
171
|
when Core::FormalRef
|
168
172
|
converted = anArgument
|
@@ -172,9 +176,9 @@ module MiniKraken
|
|
172
176
|
converted = anArgument
|
173
177
|
when Core::GoalTemplate
|
174
178
|
converted = anArgument
|
175
|
-
when Core::
|
179
|
+
when Core::LogVarRef
|
176
180
|
converted = anArgument
|
177
|
-
when
|
181
|
+
when Composite::ConsCell
|
178
182
|
converted = anArgument
|
179
183
|
else
|
180
184
|
msg = "Internal error: undefined conversion for #{anArgument.class}"
|
@@ -224,7 +228,7 @@ module MiniKraken
|
|
224
228
|
if @dsl_mode == :defrel && @defrel_formals.include?(name)
|
225
229
|
result = Core::FormalRef.new(name)
|
226
230
|
else
|
227
|
-
result = Core::
|
231
|
+
result = Core::LogVarRef.new(name)
|
228
232
|
end
|
229
233
|
end
|
230
234
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative '../core/environment'
|
4
4
|
require_relative '../core/conj2'
|
5
5
|
require_relative '../core/goal_template'
|
6
|
-
require_relative '../core/
|
6
|
+
require_relative '../core/log_var'
|
7
7
|
|
8
8
|
module MiniKraken
|
9
9
|
module Glue
|
@@ -27,12 +27,17 @@ module MiniKraken
|
|
27
27
|
super()
|
28
28
|
@goal = valid_goal(aGoal)
|
29
29
|
theNames.each do |nm|
|
30
|
-
var = Core::
|
30
|
+
var = Core::LogVar.new(nm)
|
31
31
|
add_var(var)
|
32
32
|
end
|
33
33
|
@persistent = persistence
|
34
34
|
end
|
35
35
|
|
36
|
+
# @return [Relation] The relation associated with the main goal.
|
37
|
+
def relation
|
38
|
+
goal.relation
|
39
|
+
end
|
40
|
+
|
36
41
|
# Attempt to achieve the goal given this environment
|
37
42
|
# @param aParent [Environment]
|
38
43
|
# @return [Fiber<Outcome>] A Fiber object that will generate the results.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../core/any_value'
|
4
|
-
require_relative '../
|
4
|
+
require_relative '../composite/cons_cell'
|
5
5
|
require_relative 'fresh_env'
|
6
6
|
|
7
7
|
module MiniKraken
|
@@ -59,7 +59,7 @@ module MiniKraken
|
|
59
59
|
|
60
60
|
new_tail = nil
|
61
61
|
anArray.reverse_each do |elem|
|
62
|
-
new_tail =
|
62
|
+
new_tail = Composite::ConsCell.new(elem, new_tail)
|
63
63
|
end
|
64
64
|
|
65
65
|
new_tail
|
data/lib/mini_kraken/version.rb
CHANGED
data/spec/.rubocop.yml
CHANGED
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
# Load the class under test
|
7
|
+
require_relative '../../lib/mini_kraken/atomic/atomic_term'
|
8
|
+
|
9
|
+
module MiniKraken
|
10
|
+
module Atomic
|
11
|
+
describe AtomicTerm do
|
12
|
+
let(:a_value) { :serenity }
|
13
|
+
let(:other_value) { :fuzziness }
|
14
|
+
subject { AtomicTerm.new(a_value) }
|
15
|
+
|
16
|
+
context 'Initialization:' do
|
17
|
+
it 'should be created with a Ruby datatype instance' do
|
18
|
+
expect { AtomicTerm.new(a_value) }.not_to raise_error
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'knows its value' do
|
22
|
+
expect(subject.value).to eq(a_value)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'freezes its value' do
|
26
|
+
expect(subject.value).to be_frozen
|
27
|
+
end
|
28
|
+
end # context
|
29
|
+
|
30
|
+
context 'Provided services:' do
|
31
|
+
it 'should know that it is a ground term' do
|
32
|
+
env = double('mock-env')
|
33
|
+
expect(subject.ground?(env)).to be_truthy
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should know that it is not a fresh term' do
|
37
|
+
env = double('mock-env')
|
38
|
+
expect(subject.fresh?(env)).to be_falsy
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should know its freshness' do
|
42
|
+
env = double('mock-env')
|
43
|
+
expect(subject.freshness(env).degree).to eq(:ground)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'performs data value comparison' do
|
47
|
+
expect(subject == subject).to be_truthy
|
48
|
+
expect(subject == subject.value).to be_truthy
|
49
|
+
|
50
|
+
expect(subject == other_value).to be_falsy
|
51
|
+
expect(subject == AtomicTerm.new(other_value)).to be_falsy
|
52
|
+
|
53
|
+
# Same duck type, same value
|
54
|
+
yet_another = OpenStruct.new(value: a_value)
|
55
|
+
expect(subject == yet_another).to be_truthy
|
56
|
+
|
57
|
+
# Same duck type, different value
|
58
|
+
still_another = OpenStruct.new(value: other_value)
|
59
|
+
expect(subject == still_another).to be_falsy
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'performs type and data value comparison' do
|
63
|
+
expect(subject).to be_eql(subject)
|
64
|
+
|
65
|
+
# Same type, same value
|
66
|
+
other = AtomicTerm.new(a_value)
|
67
|
+
expect(subject).to be_eql(other)
|
68
|
+
|
69
|
+
# Same type, other value
|
70
|
+
another = AtomicTerm.new(other_value)
|
71
|
+
expect(subject).not_to be_eql(another)
|
72
|
+
|
73
|
+
# Different type, same value
|
74
|
+
yet_another = OpenStruct.new(value: other_value)
|
75
|
+
expect(subject).not_to be_eql(yet_another)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'returns itself when receiving quote message' do
|
79
|
+
env = double('mock-env')
|
80
|
+
expect(subject.quote(env)).to eq(subject)
|
81
|
+
end
|
82
|
+
end # context
|
83
|
+
=begin
|
84
|
+
# An atomic term is by definition a ground term: since it doesn't contain
|
85
|
+
# any bound variable (in Prolog sense).
|
86
|
+
# @param _env [Vocabulary]
|
87
|
+
# @return [Freshness]
|
88
|
+
def freshness(_env)
|
89
|
+
Freshness.new(:ground, self)
|
90
|
+
end
|
91
|
+
=end
|
92
|
+
end # describe
|
93
|
+
end # module
|
94
|
+
end # module
|
@@ -4,10 +4,10 @@ require_relative '../spec_helper' # Use the RSpec framework
|
|
4
4
|
require 'ostruct'
|
5
5
|
|
6
6
|
# Load the class under test
|
7
|
-
require_relative '../../lib/mini_kraken/
|
7
|
+
require_relative '../../lib/mini_kraken/atomic/k_boolean'
|
8
8
|
|
9
9
|
module MiniKraken
|
10
|
-
module
|
10
|
+
module Atomic
|
11
11
|
describe KBoolean do
|
12
12
|
subject { KBoolean.new('#t') }
|
13
13
|
|
@@ -28,12 +28,23 @@ module MiniKraken
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'should know its value' do
|
31
|
-
|
32
|
-
|
31
|
+
other = KBoolean.new(true)
|
32
|
+
expect(other.value).to eq(true)
|
33
|
+
|
34
|
+
other = KBoolean.new('#t')
|
35
|
+
expect(other.value).to eq(true)
|
36
|
+
|
37
|
+
other = KBoolean.new(:"#t")
|
38
|
+
expect(other.value).to eq(true)
|
39
|
+
|
40
|
+
other = KBoolean.new(false)
|
41
|
+
expect(other.value).to eq(false)
|
42
|
+
|
43
|
+
other = KBoolean.new('#f')
|
44
|
+
expect(other.value).to eq(false)
|
33
45
|
|
34
|
-
|
35
|
-
|
36
|
-
expect(subject.ground?(env)).to be_truthy
|
46
|
+
other = KBoolean.new(:"#f")
|
47
|
+
expect(other.value).to eq(false)
|
37
48
|
end
|
38
49
|
end # context
|
39
50
|
|
@@ -43,27 +54,13 @@ module MiniKraken
|
|
43
54
|
other = KBoolean.new(true)
|
44
55
|
expect(subject).to be_eql(other)
|
45
56
|
|
46
|
-
other = KBoolean.new(:"#t")
|
47
|
-
expect(subject).to be_eql(other)
|
48
|
-
|
49
|
-
other = KBoolean.new('#t')
|
50
|
-
expect(subject).to be_eql(other)
|
51
|
-
|
52
57
|
# Same type, other value
|
53
58
|
another = KBoolean.new(false)
|
54
59
|
expect(subject).not_to be_eql(another)
|
55
60
|
|
56
|
-
# Same type, other value
|
57
|
-
another = KBoolean.new(:"#f")
|
58
|
-
expect(subject).not_to be_eql(another)
|
59
|
-
|
60
61
|
# Same type, other value
|
61
62
|
another = KBoolean.new('#f')
|
62
63
|
expect(subject).not_to be_eql(another)
|
63
|
-
|
64
|
-
# Different type, same value
|
65
|
-
yet_another = OpenStruct.new(value: true)
|
66
|
-
expect(subject).not_to be_eql(yet_another)
|
67
64
|
end
|
68
65
|
|
69
66
|
it 'should know whether it has same value than other object' do
|
@@ -71,27 +68,15 @@ module MiniKraken
|
|
71
68
|
other = KBoolean.new(true)
|
72
69
|
expect(subject == other).to be_truthy
|
73
70
|
|
74
|
-
other = KBoolean.new(:"#t")
|
75
|
-
expect(subject == other).to be_truthy
|
76
|
-
|
77
|
-
other = KBoolean.new('#t')
|
78
|
-
expect(subject == other).to be_truthy
|
79
|
-
|
80
71
|
# Same type, other value
|
81
72
|
another = KBoolean.new(false)
|
82
73
|
expect(subject == another).to be_falsy
|
83
74
|
|
84
|
-
another = KBoolean.new(:"#f")
|
85
|
-
expect(subject == another).to be_falsy
|
86
|
-
|
87
|
-
another = KBoolean.new('#f')
|
88
|
-
expect(subject == another).to be_falsy
|
89
|
-
|
90
75
|
# Same duck type, same value
|
91
76
|
yet_another = OpenStruct.new(value: true)
|
92
77
|
expect(subject == yet_another).to be_truthy
|
93
78
|
|
94
|
-
#
|
79
|
+
# Same duck type, different value
|
95
80
|
still_another = OpenStruct.new(value: false)
|
96
81
|
expect(subject == still_another).to be_falsy
|
97
82
|
|