mini_kraken 0.2.04 → 0.3.00
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +16 -16
- data/lib/mini_kraken/atomic/all_atomic.rb +1 -0
- data/lib/mini_kraken/atomic/atomic_term.rb +32 -17
- data/lib/mini_kraken/atomic/k_integer.rb +0 -4
- data/lib/mini_kraken/atomic/k_string.rb +17 -0
- data/lib/mini_kraken/atomic/k_symbol.rb +0 -6
- data/lib/mini_kraken/composite/all_composite.rb +4 -0
- data/lib/mini_kraken/composite/composite_term.rb +2 -18
- data/lib/mini_kraken/composite/cons_cell.rb +178 -11
- data/lib/mini_kraken/composite/cons_cell_visitor.rb +12 -64
- data/lib/mini_kraken/composite/list.rb +32 -0
- data/lib/mini_kraken/core/all_core.rb +8 -0
- data/lib/mini_kraken/core/any_value.rb +31 -7
- data/lib/mini_kraken/core/arity.rb +69 -0
- data/lib/mini_kraken/core/association.rb +29 -4
- data/lib/mini_kraken/core/association_copy.rb +50 -0
- data/lib/mini_kraken/core/base_term.rb +13 -0
- data/lib/mini_kraken/core/blackboard.rb +315 -0
- data/lib/mini_kraken/core/bookmark.rb +46 -0
- data/lib/mini_kraken/core/context.rb +624 -0
- data/lib/mini_kraken/core/duck_fiber.rb +21 -19
- data/lib/mini_kraken/core/entry.rb +40 -0
- data/lib/mini_kraken/core/fail.rb +20 -18
- data/lib/mini_kraken/core/fusion.rb +29 -0
- data/lib/mini_kraken/core/goal.rb +20 -29
- data/lib/mini_kraken/core/log_var.rb +4 -30
- data/lib/mini_kraken/core/log_var_ref.rb +72 -48
- data/lib/mini_kraken/core/nullary_relation.rb +2 -9
- data/lib/mini_kraken/core/parametrized_term.rb +61 -0
- data/lib/mini_kraken/core/relation.rb +14 -28
- data/lib/mini_kraken/core/scope.rb +67 -0
- data/lib/mini_kraken/core/solver_adapter.rb +58 -0
- data/lib/mini_kraken/core/specification.rb +48 -0
- data/lib/mini_kraken/core/succeed.rb +21 -17
- data/lib/mini_kraken/core/symbol_table.rb +137 -0
- data/lib/mini_kraken/core/term.rb +15 -4
- data/lib/mini_kraken/glue/dsl.rb +35 -69
- data/lib/mini_kraken/glue/run_star_expression.rb +28 -30
- data/lib/mini_kraken/rela/all_rela.rb +8 -0
- data/lib/mini_kraken/rela/binary_relation.rb +30 -0
- data/lib/mini_kraken/rela/conde.rb +146 -0
- data/lib/mini_kraken/rela/conj2.rb +65 -0
- data/lib/mini_kraken/rela/def_relation.rb +64 -0
- data/lib/mini_kraken/rela/disj2.rb +70 -0
- data/lib/mini_kraken/rela/fresh.rb +98 -0
- data/lib/mini_kraken/{core → rela}/goal_relation.rb +6 -8
- data/lib/mini_kraken/rela/unify.rb +258 -0
- data/lib/mini_kraken/version.rb +1 -1
- data/spec/atomic/atomic_term_spec.rb +23 -20
- data/spec/atomic/k_symbol_spec.rb +0 -5
- data/spec/composite/cons_cell_spec.rb +116 -0
- data/spec/composite/cons_cell_visitor_spec.rb +16 -3
- data/spec/composite/list_spec.rb +50 -0
- data/spec/core/any_value_spec.rb +52 -0
- data/spec/core/arity_spec.rb +91 -0
- data/spec/core/association_copy_spec.rb +69 -0
- data/spec/core/association_spec.rb +25 -0
- data/spec/core/blackboard_spec.rb +287 -0
- data/spec/core/bookmark_spec.rb +40 -0
- data/spec/core/context_spec.rb +221 -0
- data/spec/core/core_spec.rb +40 -0
- data/spec/core/duck_fiber_spec.rb +22 -46
- data/spec/core/fail_spec.rb +5 -6
- data/spec/core/goal_spec.rb +20 -11
- data/spec/core/log_var_ref_spec.rb +80 -5
- data/spec/core/log_var_spec.rb +35 -6
- data/spec/core/nullary_relation_spec.rb +33 -0
- data/spec/core/parametrized_tem_spec.rb +39 -0
- data/spec/core/relation_spec.rb +33 -0
- data/spec/core/scope_spec.rb +73 -0
- data/spec/core/solver_adapter_spec.rb +70 -0
- data/spec/core/specification_spec.rb +43 -0
- data/spec/core/succeed_spec.rb +5 -5
- data/spec/core/symbol_table_spec.rb +142 -0
- data/spec/glue/dsl_chap1_spec.rb +88 -99
- data/spec/glue/dsl_chap2_spec.rb +59 -41
- data/spec/glue/run_star_expression_spec.rb +69 -896
- data/spec/{core → rela}/conde_spec.rb +50 -46
- data/spec/rela/conj2_spec.rb +123 -0
- data/spec/rela/def_relation_spec.rb +119 -0
- data/spec/rela/disj2_spec.rb +117 -0
- data/spec/rela/fresh_spec.rb +147 -0
- data/spec/rela/unify_spec.rb +369 -0
- data/spec/support/factory_atomic.rb +7 -0
- data/spec/support/factory_composite.rb +21 -0
- metadata +71 -48
- data/lib/mini_kraken/core/association_walker.rb +0 -183
- data/lib/mini_kraken/core/base_arg.rb +0 -10
- data/lib/mini_kraken/core/binary_relation.rb +0 -63
- data/lib/mini_kraken/core/composite_goal.rb +0 -46
- data/lib/mini_kraken/core/conde.rb +0 -143
- data/lib/mini_kraken/core/conj2.rb +0 -79
- data/lib/mini_kraken/core/def_relation.rb +0 -53
- data/lib/mini_kraken/core/designation.rb +0 -55
- data/lib/mini_kraken/core/disj2.rb +0 -72
- data/lib/mini_kraken/core/environment.rb +0 -73
- data/lib/mini_kraken/core/equals.rb +0 -191
- data/lib/mini_kraken/core/formal_arg.rb +0 -22
- data/lib/mini_kraken/core/formal_ref.rb +0 -25
- data/lib/mini_kraken/core/freshness.rb +0 -45
- data/lib/mini_kraken/core/goal_arg.rb +0 -12
- data/lib/mini_kraken/core/goal_template.rb +0 -102
- data/lib/mini_kraken/core/outcome.rb +0 -63
- data/lib/mini_kraken/core/tap.rb +0 -46
- data/lib/mini_kraken/core/vocabulary.rb +0 -446
- data/lib/mini_kraken/glue/fresh_env.rb +0 -108
- data/lib/mini_kraken/glue/fresh_env_factory.rb +0 -83
- data/spec/core/association_walker_spec.rb +0 -194
- data/spec/core/conj2_spec.rb +0 -116
- data/spec/core/def_relation_spec.rb +0 -99
- data/spec/core/disj2_spec.rb +0 -100
- data/spec/core/environment_spec.rb +0 -144
- data/spec/core/equals_spec.rb +0 -319
- data/spec/core/goal_template_spec.rb +0 -74
- data/spec/core/outcome_spec.rb +0 -56
- data/spec/core/vocabulary_spec.rb +0 -220
- data/spec/glue/fresh_env_factory_spec.rb +0 -99
- data/spec/glue/fresh_env_spec.rb +0 -62
@@ -1,73 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'set'
|
4
|
-
require_relative 'vocabulary'
|
5
|
-
|
6
|
-
module MiniKraken
|
7
|
-
module Core
|
8
|
-
class Environment
|
9
|
-
include Vocabulary # Use mix-in module
|
10
|
-
|
11
|
-
# Mapping from user-defined name to Variable instance
|
12
|
-
# @return [Hash] Pairs of the kind {String => Variable}
|
13
|
-
attr_reader :vars
|
14
|
-
|
15
|
-
# Mapping from internal name to user-defined name(s)
|
16
|
-
# @return [Hash] Pairs of the kind {String => Set<String>}
|
17
|
-
attr_reader :ivars
|
18
|
-
|
19
|
-
# @param aParent [Environment, NilClass] Parent environment to this one.
|
20
|
-
def initialize(aParent = nil)
|
21
|
-
init_vocabulary(aParent)
|
22
|
-
@vars = {}
|
23
|
-
@ivars = {}
|
24
|
-
end
|
25
|
-
|
26
|
-
# @param aVariable [Variable]
|
27
|
-
def add_var(aVariable)
|
28
|
-
name = aVariable.name
|
29
|
-
if vars.include?(name)
|
30
|
-
err_msg = "Variable with name '#{name}' already exists."
|
31
|
-
raise StandardError, err_msg
|
32
|
-
end
|
33
|
-
vars[name] = aVariable
|
34
|
-
i_name = aVariable.i_name
|
35
|
-
if ivars.include?(i_name)
|
36
|
-
set = ivars[i_name]
|
37
|
-
set.add(name)
|
38
|
-
else
|
39
|
-
ivars[i_name] = Set.new([i_name])
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# Handler for the event: an outcome has been produced.
|
44
|
-
# Can be overridden in other to propagate associations from child
|
45
|
-
# @param descendent [Outcome]
|
46
|
-
def propagate(descendent)
|
47
|
-
# Rollout associations from hierarchy
|
48
|
-
walker = descendent.ancestor_walker
|
49
|
-
begin
|
50
|
-
env = walker.next
|
51
|
-
break if env.nil?
|
52
|
-
|
53
|
-
env.do_propagate(descendent) if env.kind_of?(Environment)
|
54
|
-
end until env.equal?(self)
|
55
|
-
end
|
56
|
-
|
57
|
-
# Roll up associations from descendent outcome object
|
58
|
-
# @param descendent [Outcome]
|
59
|
-
def do_propagate(descendent)
|
60
|
-
return unless descendent.success?
|
61
|
-
|
62
|
-
vars.each_key do |var_name|
|
63
|
-
# assocs = descendent[var_name]
|
64
|
-
move_assocs(var_name, descendent)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def merge_vars(descendent)
|
69
|
-
descendent.vars.each_value { |vr| add_var(vr) }
|
70
|
-
end
|
71
|
-
end # class
|
72
|
-
end # module
|
73
|
-
end # module
|
@@ -1,191 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'singleton'
|
4
|
-
require_relative 'binary_relation'
|
5
|
-
require_relative '../composite/cons_cell_visitor'
|
6
|
-
require_relative 'duck_fiber'
|
7
|
-
require_relative 'log_var'
|
8
|
-
require_relative 'log_var_ref'
|
9
|
-
|
10
|
-
module MiniKraken
|
11
|
-
module Core
|
12
|
-
# equals tries to unify two terms
|
13
|
-
class Equals < BinaryRelation
|
14
|
-
include Singleton
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
super('equals', '==')
|
18
|
-
end
|
19
|
-
|
20
|
-
# @param actuals [Array<Term>] A two-elements array
|
21
|
-
# @param anEnv [Vocabulary] A vocabulary object
|
22
|
-
# @return [Fiber<Outcome>] A Fiber(-like) instance that yields Outcomes
|
23
|
-
def solver_for(actuals, anEnv)
|
24
|
-
arg1, arg2 = *actuals
|
25
|
-
DuckFiber.new(:custom) do
|
26
|
-
outcome = unification(arg1, arg2, anEnv)
|
27
|
-
outcome.prune!
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def unification(arg1, arg2, anEnv)
|
32
|
-
arg1_nil = arg1.nil?
|
33
|
-
arg2_nil = arg2.nil?
|
34
|
-
if arg1_nil || arg2_nil
|
35
|
-
if arg1_nil && arg2_nil
|
36
|
-
result = Outcome.success(anEnv)
|
37
|
-
else
|
38
|
-
result = Outcome.failure(anEnv)
|
39
|
-
end
|
40
|
-
return result
|
41
|
-
end
|
42
|
-
new_arg1, new_arg2 = commute_cond(arg1, arg2, anEnv)
|
43
|
-
do_unification(new_arg1, new_arg2, anEnv)
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
|
49
|
-
# table: Unification
|
50
|
-
# | arg1 | arg2 | Criterion || Unification |
|
51
|
-
# | isa? Atomic | isa? Atomic | arg1.eq? arg2 is true || { "s", [] } |
|
52
|
-
# | isa? Atomic | isa? Atomic | arg1.eq? arg2 is false || { "u", [] } |
|
53
|
-
# | isa? CompositeTerm | isa? Atomic | dont_care || { "u", [] } |
|
54
|
-
# | isa? CompositeTerm | isa? CompositeTerm | unification(arg1.car, arg2.car) => "s" || { "s", [bindings*] } |
|
55
|
-
# | isa? CompositeTerm | isa? CompositeTerm | unification(arg1.cdr, arg2.cdr) => "u" || { "u", [] ) | |
|
56
|
-
# | isa? LogVarRef | isa? Atomic | arg1.fresh? is true || { "s", [arg2] } |
|
57
|
-
# | isa? LogVarRef | isa? Atomic | arg1.fresh? is false || |
|
58
|
-
# | | unification(arg1.value, arg2) => "s" || { "s", [bindings*] } |
|
59
|
-
# | | unification(arg1.value, arg2) => "u" || { "u", [] } |
|
60
|
-
# | isa? LogVarRef | isa? CompositeTerm | arg1.fresh? is true || { "s", [arg2] } | # What if arg1 occurs in arg2?
|
61
|
-
# | isa? LogVarRef | isa? CompositeTerm | arg1.fresh? is false || |
|
62
|
-
# | | unification(arg1.value, arg2) => "s" || { "s", [bindings*] } |
|
63
|
-
# | | unification(arg1.value, arg2) => "u" || { "u", [] } |
|
64
|
-
# | isa? LogVarRef | isa? LogVarRef | arg1.fresh?, arg2.fresh? => [true, true] || { "s", [arg1 <=> arg2] } |
|
65
|
-
# | isa? LogVarRef | isa? LogVarRef | arg1.fresh?, arg2.fresh? => [true, false] || |
|
66
|
-
# | | unification(arg1, arg2.value) => "s" || { "s", [bindings*] } |
|
67
|
-
# | | unification(arg1, arg2.value) => "u" || { "u", [] } |
|
68
|
-
# | isa? LogVarRef | isa? LogVarRef | arg1.fresh?, arg2.fresh? => [false, false]|| |
|
69
|
-
# | | unification(arg1, arg2.value) => "s" || { "s", [bindings*] } |
|
70
|
-
# | | unification(arg1, arg2.value) => "u" || { "u", [] }
|
71
|
-
def do_unification(arg1, arg2, anEnv)
|
72
|
-
# require 'debug'
|
73
|
-
return Outcome.success(anEnv) if arg1.equal?(arg2)
|
74
|
-
|
75
|
-
result = Outcome.failure(anEnv) # default case
|
76
|
-
|
77
|
-
if arg1.kind_of?(Atomic::AtomicTerm)
|
78
|
-
result = Outcome.success(anEnv) if arg1.eql?(arg2)
|
79
|
-
elsif arg1.kind_of?(Composite::CompositeTerm)
|
80
|
-
if arg2.kind_of?(Composite::CompositeTerm) # Atomic::AtomicTerm is default case => fail
|
81
|
-
result = unify_composite_terms(arg1, arg2, anEnv)
|
82
|
-
end
|
83
|
-
elsif arg1.kind_of?(LogVarRef)
|
84
|
-
arg1_freshness = arg1.freshness(anEnv)
|
85
|
-
if arg2.kind_of?(Atomic::AtomicTerm)
|
86
|
-
if arg1_freshness.degree == :fresh
|
87
|
-
result = Outcome.success(anEnv)
|
88
|
-
arg1.associate(arg2, result)
|
89
|
-
else
|
90
|
-
result = Outcome.success(anEnv) if arg1.value(anEnv).eql?(arg2)
|
91
|
-
end
|
92
|
-
elsif arg2.kind_of?(Composite::CompositeTerm)
|
93
|
-
if arg1_freshness.degree == :fresh
|
94
|
-
result = Outcome.success(anEnv)
|
95
|
-
arg1.associate(arg2, result)
|
96
|
-
else
|
97
|
-
# Ground case...
|
98
|
-
arg1_associated = arg1_freshness.associated
|
99
|
-
unless arg1_associated.kind_of?(Atomic::AtomicTerm)
|
100
|
-
result = unify_composite_terms(arg1_associated, arg2, anEnv)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
elsif arg2.kind_of?(LogVarRef)
|
104
|
-
freshness = [arg1.fresh?(anEnv), arg2.fresh?(anEnv)]
|
105
|
-
case freshness
|
106
|
-
when [false, false] # TODO: confirm this...
|
107
|
-
result = unification(arg1.value(anEnv), arg2.value(anEnv), anEnv)
|
108
|
-
when [true, true]
|
109
|
-
result = Outcome.success(anEnv)
|
110
|
-
if arg1.var_name != arg2.var_name
|
111
|
-
arg1.associate(arg2, result)
|
112
|
-
arg2.associate(arg1, result)
|
113
|
-
end
|
114
|
-
when [true, false]
|
115
|
-
result = Outcome.success(anEnv)
|
116
|
-
arg1.associate(arg2, result)
|
117
|
-
else
|
118
|
-
raise StandardError, "Unsupported freshness combination #{freshness}"
|
119
|
-
end
|
120
|
-
else
|
121
|
-
arg_kinds = [arg1.class, arg2.class]
|
122
|
-
raise StandardError, "Unsupported combination #{arg_kinds}"
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
result
|
127
|
-
end
|
128
|
-
|
129
|
-
# @param arg1 [Composite::ConsCell]
|
130
|
-
# @param arg2 [Composite::ConsCell]
|
131
|
-
# @return [Outcome]
|
132
|
-
def unify_composite_terms(arg1, arg2, anEnv)
|
133
|
-
# require 'debug'
|
134
|
-
result = Outcome.success(anEnv)
|
135
|
-
# We'll do parallel iteration
|
136
|
-
visitor1 = Composite::ConsCellVisitor.df_visitor(arg1)
|
137
|
-
visitor2 = Composite::ConsCellVisitor.df_visitor(arg2)
|
138
|
-
skip_children1 = false
|
139
|
-
skip_children2 = false
|
140
|
-
|
141
|
-
loop do
|
142
|
-
side1, cell1 = visitor1.resume(skip_children1)
|
143
|
-
side2, cell2 = visitor2.resume(skip_children2)
|
144
|
-
if side1 != side2
|
145
|
-
result = Outcome.failure(anEnv)
|
146
|
-
elsif side1 == :stop
|
147
|
-
break
|
148
|
-
else
|
149
|
-
case [cell1.class, cell2.class] # nil, Atomic::AtomicTerm, Composite::ConsCell, LogVarRef
|
150
|
-
when [Composite::ConsCell, Composite::ConsCell]
|
151
|
-
skip_children1 = false
|
152
|
-
skip_children2 = false
|
153
|
-
when [Composite::ConsCell, LogVarRef]
|
154
|
-
skip_children1 = true
|
155
|
-
skip_children2 = false
|
156
|
-
sub_result = unification(cell1, cell2, anEnv)
|
157
|
-
result = merge_results(result, sub_result)
|
158
|
-
when [LogVarRef, Composite::ConsCell]
|
159
|
-
skip_children1 = false
|
160
|
-
skip_children2 = true
|
161
|
-
sub_result = do_unification(cell1, cell2, anEnv)
|
162
|
-
result = merge_results(result, sub_result)
|
163
|
-
else
|
164
|
-
skip_children1 = false
|
165
|
-
skip_children2 = false
|
166
|
-
sub_result = unification(cell1, cell2, anEnv)
|
167
|
-
result = merge_results(result, sub_result)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
break if result.failure?
|
172
|
-
end
|
173
|
-
|
174
|
-
result
|
175
|
-
end
|
176
|
-
|
177
|
-
def merge_results(result1, result2)
|
178
|
-
raise StandardError if result2.kind_of?(Hash)
|
179
|
-
|
180
|
-
if result2.success?
|
181
|
-
result1.merge(result2)
|
182
|
-
result1
|
183
|
-
else
|
184
|
-
result2
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end # class
|
188
|
-
|
189
|
-
Equals.instance.freeze
|
190
|
-
end # module
|
191
|
-
end # module
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MiniKraken
|
4
|
-
module Core
|
5
|
-
# The generalization of any iem that can be
|
6
|
-
# passed as arugement to a goal.
|
7
|
-
class FormalArg
|
8
|
-
# @return [String]
|
9
|
-
attr_reader :name
|
10
|
-
|
11
|
-
def initialize(aName)
|
12
|
-
@name = validated_name(aName)
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
def validated_name(aName)
|
18
|
-
aName
|
19
|
-
end
|
20
|
-
end # class
|
21
|
-
end # module
|
22
|
-
end # module
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'base_arg'
|
4
|
-
|
5
|
-
module MiniKraken
|
6
|
-
module Core
|
7
|
-
# A formal reference represents the occurrence of a formal argument name in a
|
8
|
-
# goal template argument list.
|
9
|
-
class FormalRef < BaseArg
|
10
|
-
# @return [String] The name of a formal argument.
|
11
|
-
attr_reader :name
|
12
|
-
|
13
|
-
def initialize(aName)
|
14
|
-
super()
|
15
|
-
@name = validated_name(aName)
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def validated_name(aName)
|
21
|
-
aName
|
22
|
-
end
|
23
|
-
end # class
|
24
|
-
end # module
|
25
|
-
end # module
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MiniKraken
|
4
|
-
module Core
|
5
|
-
# Freshness: fresh, bound, ground
|
6
|
-
# fresh: no association at all
|
7
|
-
# bound: associated to something that is itself not ground.
|
8
|
-
# ground: associated to something that is either an atomic, a composite with ground members,
|
9
|
-
# a variable reference to something that is itself ground.
|
10
|
-
# RS fresh == fresh or bound
|
11
|
-
# RS not fresh == ground
|
12
|
-
# RS result == fresh => any or bound => expr(any)
|
13
|
-
Freshness = Struct.new(:degree, :associated) do
|
14
|
-
def initialize(aDegree, anAssociated)
|
15
|
-
super(aDegree, valid_associated(anAssociated))
|
16
|
-
end
|
17
|
-
|
18
|
-
def fresh?
|
19
|
-
degree == :fresh
|
20
|
-
end
|
21
|
-
|
22
|
-
def bound?
|
23
|
-
degree == :bound
|
24
|
-
end
|
25
|
-
|
26
|
-
def ground?
|
27
|
-
degree == :ground
|
28
|
-
end
|
29
|
-
|
30
|
-
# Does this instance represent something fresh according to
|
31
|
-
# "Reasoned Schemer" book ?
|
32
|
-
def rs_fresh?
|
33
|
-
degree != ground
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def valid_associated(anAssociated)
|
39
|
-
raise StandardError, 'Wrong argument' if anAssociated.kind_of?(self.class)
|
40
|
-
|
41
|
-
anAssociated
|
42
|
-
end
|
43
|
-
end # struct
|
44
|
-
end # module
|
45
|
-
end # module
|
@@ -1,12 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'base_arg'
|
4
|
-
|
5
|
-
module MiniKraken
|
6
|
-
module Core
|
7
|
-
# The generalization of any item that can be
|
8
|
-
# passed as arugement to a goal object
|
9
|
-
class GoalArg < BaseArg
|
10
|
-
end # class
|
11
|
-
end # module
|
12
|
-
end # module
|
@@ -1,102 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'base_arg'
|
4
|
-
require_relative '../composite/cons_cell_visitor'
|
5
|
-
|
6
|
-
module MiniKraken
|
7
|
-
module Core
|
8
|
-
# A meta-goal that is parametrized with generic formal arguments.
|
9
|
-
# The individual goals are instantiated when the formal arguments
|
10
|
-
# are bound to goal arguments.
|
11
|
-
class GoalTemplate < BaseArg
|
12
|
-
# @return [Array<BaseArg>] Arguments of goal template.
|
13
|
-
attr_reader :args
|
14
|
-
|
15
|
-
# @return [Relation] Main relation for the goal template
|
16
|
-
attr_reader :relation
|
17
|
-
|
18
|
-
# @param aRelation [Core::Rzlation] the relation
|
19
|
-
# @param theArgs [Array<Core::BaseArg>] Arguments of goal template.
|
20
|
-
def initialize(aRelation, theArgs)
|
21
|
-
super()
|
22
|
-
@relation = validated_relation(aRelation)
|
23
|
-
@args = validated_args(theArgs)
|
24
|
-
args.freeze
|
25
|
-
end
|
26
|
-
|
27
|
-
# Factory method: Create a goal object.
|
28
|
-
# @param formals [Array<FormalArg>] Array of formal arguments
|
29
|
-
# @param actuals [Array<GoalArg>] Array of actual arguments
|
30
|
-
# @return [Goal] instantiate a goal object given the actuals and environment
|
31
|
-
def instantiate(formals, actuals)
|
32
|
-
formals2actuals = {}
|
33
|
-
formals.each_with_index do |frml, i|
|
34
|
-
formals2actuals[frml.name] = actuals[i]
|
35
|
-
end
|
36
|
-
|
37
|
-
do_instantiate(formals2actuals)
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def validated_relation(aRelation)
|
43
|
-
aRelation
|
44
|
-
end
|
45
|
-
|
46
|
-
def validated_args(theArgs)
|
47
|
-
theArgs
|
48
|
-
end
|
49
|
-
|
50
|
-
def do_instantiate(formals2actuals)
|
51
|
-
goal_args = []
|
52
|
-
args.each do |arg|
|
53
|
-
if arg.kind_of?(FormalRef)
|
54
|
-
goal_args << formals2actuals[arg.name]
|
55
|
-
elsif arg.kind_of?(GoalTemplate)
|
56
|
-
goal_args << arg.send(:do_instantiate, formals2actuals)
|
57
|
-
elsif arg.kind_of?(Composite::ConsCell)
|
58
|
-
# if list contains a formal_ref it must be replaced by the actual
|
59
|
-
goal_args << transform(arg, formals2actuals)
|
60
|
-
else
|
61
|
-
goal_args << arg
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
Goal.new(relation, goal_args)
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
|
70
|
-
def transform(aConsCell, formals2actuals)
|
71
|
-
return aConsCell if aConsCell.null?
|
72
|
-
|
73
|
-
member = { car: :@car, cdr: :@cdr }
|
74
|
-
visitor = Composite::ConsCellVisitor.df_visitor(aConsCell)
|
75
|
-
side, cell = visitor.resume
|
76
|
-
result = Composite::ConsCell.new(nil, nil)
|
77
|
-
node = result
|
78
|
-
|
79
|
-
loop do
|
80
|
-
side, cell = visitor.resume
|
81
|
-
break if side == :stop
|
82
|
-
|
83
|
-
converted = nil
|
84
|
-
case cell
|
85
|
-
when FormalRef
|
86
|
-
converted = formals2actuals[cell.name]
|
87
|
-
when Composite::ConsCell
|
88
|
-
converted = Composite::ConsCell.new(nil, nil)
|
89
|
-
when GoalTemplate
|
90
|
-
converted = cell.send(:do_instantiate, formals2actuals)
|
91
|
-
else
|
92
|
-
converted = cell
|
93
|
-
end
|
94
|
-
node.instance_variable_set(member[side], converted)
|
95
|
-
node = converted if converted.kind_of?(Composite::ConsCell)
|
96
|
-
end
|
97
|
-
|
98
|
-
result
|
99
|
-
end
|
100
|
-
end # class
|
101
|
-
end # module
|
102
|
-
end # module
|