mini_kraken 0.1.04 → 0.1.05
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/Gemfile +3 -1
- data/README.md +6 -6
- data/Rakefile +5 -3
- data/lib/mini_kraken/core/any_value.rb +9 -7
- data/lib/mini_kraken/core/association.rb +20 -7
- data/lib/mini_kraken/core/association_walker.rb +5 -1
- data/lib/mini_kraken/core/atomic_term.rb +5 -3
- data/lib/mini_kraken/core/binary_relation.rb +8 -6
- data/lib/mini_kraken/core/composite_term.rb +5 -20
- data/lib/mini_kraken/core/cons_cell.rb +7 -3
- data/lib/mini_kraken/core/duck_fiber.rb +3 -1
- data/lib/mini_kraken/core/environment.rb +24 -10
- data/lib/mini_kraken/core/equals.rb +106 -165
- data/lib/mini_kraken/core/fail.rb +3 -1
- data/lib/mini_kraken/core/freshness.rb +11 -8
- data/lib/mini_kraken/core/goal.rb +4 -2
- data/lib/mini_kraken/core/k_integer.rb +4 -3
- data/lib/mini_kraken/core/k_symbol.rb +4 -3
- data/lib/mini_kraken/core/nullary_relation.rb +3 -1
- data/lib/mini_kraken/core/outcome.rb +5 -3
- data/lib/mini_kraken/core/relation.rb +4 -18
- data/lib/mini_kraken/core/succeed.rb +4 -2
- data/lib/mini_kraken/core/term.rb +2 -0
- data/lib/mini_kraken/core/variable.rb +13 -3
- data/lib/mini_kraken/core/variable_ref.rb +10 -32
- data/lib/mini_kraken/core/vocabulary.rb +250 -35
- data/lib/mini_kraken/glue/fresh_env.rb +5 -3
- data/lib/mini_kraken/glue/run_star_expression.rb +10 -9
- data/lib/mini_kraken/version.rb +3 -1
- data/lib/mini_kraken.rb +3 -1
- data/mini_kraken.gemspec +15 -13
- data/spec/core/association_spec.rb +4 -4
- data/spec/core/association_walker_spec.rb +25 -24
- data/spec/core/cons_cell_spec.rb +4 -3
- data/spec/core/duck_fiber_spec.rb +10 -11
- data/spec/core/environment_spec.rb +16 -28
- data/spec/core/equals_spec.rb +7 -7
- data/spec/core/fail_spec.rb +7 -7
- data/spec/core/goal_spec.rb +10 -10
- data/spec/core/k_symbol_spec.rb +5 -6
- data/spec/core/succeed_spec.rb +4 -4
- data/spec/core/variable_ref_spec.rb +0 -4
- data/spec/core/vocabulary_spec.rb +28 -22
- data/spec/glue/fresh_env_spec.rb +1 -1
- data/spec/glue/run_star_expression_spec.rb +13 -8
- data/spec/mini_kraken_spec.rb +2 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/support/factory_methods.rb +4 -2
- 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: e4ce5f0f43f5e84f377cf90e2ed49d6ff54de93b66641655fb41dd6b8feef277
|
4
|
+
data.tar.gz: 2081e486f8beba0b0073461464c632fa63af83cec27a48fb3d84c1a972b821f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea0580c9219f1a1fd586d024f06e11cf6dd1f979182c6f5a15473c65b78fa7244ba01ca9191f31e73de78b20d7aa88c60d86afa1207dbaab246c64c6650f0d1f
|
7
|
+
data.tar.gz: 9af43ee21606cac23d2512002491d0264fcbc7a74b9974edbd70c23f4bcbf25c7cc7010845aad88dee2d507a1f6d070dd402cd9a6f2abe0234999617b3ae7b68
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## [0.1.05] - 2020-05-09
|
2
|
+
- Changed implementation of fused variables
|
3
|
+
- Magic comments for frozen string literal
|
4
|
+
- Code re-styling to please Rubocop 0.82
|
5
|
+
|
6
|
+
### Changed
|
7
|
+
- File `README.md` Added "What is mini_kraken" text.
|
8
|
+
- File `README.md` Added badges (CI Travis build status, Gem version, license)
|
9
|
+
|
1
10
|
## [0.1.04] - 2020-05-02
|
2
11
|
### Changed
|
3
12
|
- File `README.md` Added "What is mini_kraken" text.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -11,14 +11,14 @@ Daniel P. Friedman, William E. Byrd, Oleg Kiselyov, and Jason Hemann: "The Reaso
|
|
11
11
|
ISBN: 9780262535519, (2018), MIT Press.
|
12
12
|
|
13
13
|
### Features
|
14
|
-
[X] ==
|
15
|
-
[X] run\*
|
16
|
-
[X] fresh
|
14
|
+
- [X] ==
|
15
|
+
- [X] run\*
|
16
|
+
- [X] fresh
|
17
17
|
|
18
18
|
### TODO
|
19
|
-
[
|
20
|
-
[
|
21
|
-
[
|
19
|
+
- [ ] disj2
|
20
|
+
- [ ] conj2
|
21
|
+
- [ ] conde
|
22
22
|
|
23
23
|
## Installation
|
24
24
|
|
data/Rakefile
CHANGED
@@ -1,31 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MiniKraken
|
2
4
|
module Core
|
3
5
|
class AnyValue
|
4
6
|
attr_reader :rank
|
5
|
-
|
7
|
+
|
6
8
|
# @param aName [String]
|
7
9
|
# @param anEnv [Vocabulary]
|
8
10
|
def initialize(aName, anEnv, alternate_names = [])
|
9
11
|
@rank = anEnv.get_rank(aName, alternate_names)
|
10
12
|
end
|
11
|
-
|
13
|
+
|
12
14
|
def ==(other)
|
13
15
|
rank == other.rank
|
14
16
|
end
|
15
|
-
|
17
|
+
|
16
18
|
# Use same text representation as in Reasoned Schemer.
|
17
19
|
def to_s
|
18
20
|
"_#{rank}"
|
19
21
|
end
|
20
|
-
|
22
|
+
|
21
23
|
def ground?(_env)
|
22
24
|
false
|
23
25
|
end
|
24
|
-
|
26
|
+
|
25
27
|
# @return [AnyValue]
|
26
28
|
def quote(_env)
|
27
29
|
self
|
28
|
-
end
|
30
|
+
end
|
29
31
|
end # class
|
30
32
|
end # module
|
31
|
-
end # module
|
33
|
+
end # module
|
@@ -1,21 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MiniKraken
|
2
4
|
module Core
|
3
5
|
# A record that a given vairable is associated with a value.
|
4
6
|
class Association
|
5
|
-
# @return [String] name of
|
6
|
-
|
7
|
-
|
7
|
+
# @return [String] internal name of variable being associated the value.
|
8
|
+
attr_accessor :i_name
|
9
|
+
|
8
10
|
# @return [Term] the MiniKraken value associated with the variable
|
9
11
|
attr_reader :value
|
10
|
-
|
11
|
-
|
12
|
+
|
13
|
+
|
12
14
|
# @param aVariable [Variable, String] A variable or its name.
|
13
15
|
# @param aValue [Term] value being associated to the variable.
|
14
16
|
def initialize(aVariable, aValue)
|
15
|
-
|
17
|
+
a_name = aVariable.respond_to?(:name) ? aVariable.i_name : aVariable
|
18
|
+
@i_name = validated_name(a_name)
|
16
19
|
@value = aValue
|
17
20
|
end
|
18
|
-
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def validated_name(aName)
|
25
|
+
raise StandardError, 'Name cannot be nil' if aName.nil?
|
26
|
+
|
27
|
+
cleaned = aName.strip
|
28
|
+
raise StandardError, 'Name cannot be empty or consists of spaces' if cleaned.empty?
|
29
|
+
|
30
|
+
cleaned
|
31
|
+
end
|
19
32
|
end # class
|
20
33
|
end # module
|
21
34
|
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'set'
|
2
4
|
require_relative 'atomic_term'
|
3
5
|
require_relative 'composite_term'
|
@@ -23,6 +25,7 @@ module MiniKraken
|
|
23
25
|
def walk_assocs(assocs, anEnv)
|
24
26
|
# Treat easy cases first...
|
25
27
|
return nil if assocs.empty?
|
28
|
+
|
26
29
|
assoc_atomic = assocs.find { |assc| assc.value.kind_of?(AtomicTerm) }
|
27
30
|
return assoc_atomic.value if assoc_atomic
|
28
31
|
|
@@ -43,6 +46,7 @@ module MiniKraken
|
|
43
46
|
|
44
47
|
def walk_value(aTerm, anEnv)
|
45
48
|
return aTerm if aTerm.kind_of?(AtomicTerm) || aTerm.kind_of?(AnyValue)
|
49
|
+
|
46
50
|
result = nil
|
47
51
|
|
48
52
|
if aTerm.kind_of?(CompositeTerm)
|
@@ -176,4 +180,4 @@ module MiniKraken
|
|
176
180
|
end
|
177
181
|
end # class
|
178
182
|
end # module
|
179
|
-
end # module
|
183
|
+
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'term'
|
2
4
|
require_relative 'freshness'
|
3
5
|
|
@@ -22,14 +24,14 @@ module MiniKraken
|
|
22
24
|
def freshness(_env)
|
23
25
|
Freshness.new(:ground, self)
|
24
26
|
end
|
25
|
-
|
27
|
+
|
26
28
|
# An atomic term is a ground term: by definition it doesn't contain
|
27
29
|
# any fresh variable.
|
28
30
|
# @param _env [Vocabulary]
|
29
31
|
# @return [FalseClass]
|
30
32
|
def fresh?(_env)
|
31
33
|
false
|
32
|
-
end
|
34
|
+
end
|
33
35
|
|
34
36
|
# An atomic term is a ground term: by definition it doesn't contain
|
35
37
|
# any fresh variable.
|
@@ -61,4 +63,4 @@ module MiniKraken
|
|
61
63
|
end
|
62
64
|
end # class
|
63
65
|
end # module
|
64
|
-
end # module
|
66
|
+
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'relation'
|
2
4
|
require_relative 'composite_term'
|
3
5
|
|
@@ -5,20 +7,20 @@ module MiniKraken
|
|
5
7
|
module Core
|
6
8
|
class BinaryRelation < Relation
|
7
9
|
# @param aName [String] Name of the relation.
|
8
|
-
# @param alternateName [String, NilClass] Alternative name (optional).
|
10
|
+
# @param alternateName [String, NilClass] Alternative name (optional).
|
9
11
|
def initialize(aName, alternateName = nil)
|
10
12
|
super(aName, alternateName)
|
11
13
|
freeze
|
12
14
|
end
|
13
|
-
|
15
|
+
|
14
16
|
# Number of arguments for the relation.
|
15
17
|
# @return [Integer]
|
16
18
|
def arity
|
17
19
|
2
|
18
20
|
end
|
19
|
-
|
21
|
+
|
20
22
|
protected
|
21
|
-
|
23
|
+
|
22
24
|
# table: Commute
|
23
25
|
# |arg1 | arg2 | arg2.ground? || Commute |
|
24
26
|
# | isa? Atomic | isa? Atomic | dont_care || Yes |
|
@@ -55,7 +57,7 @@ module MiniKraken
|
|
55
57
|
else
|
56
58
|
[arg1, arg2]
|
57
59
|
end
|
58
|
-
end
|
60
|
+
end
|
59
61
|
end # class
|
60
62
|
end # module
|
61
|
-
end # module
|
63
|
+
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'term'
|
2
4
|
require_relative 'freshness'
|
3
5
|
|
@@ -6,17 +8,16 @@ module MiniKraken
|
|
6
8
|
# An composite term is an Minikraken term that can be
|
7
9
|
# decomposed into simpler MiniKraken data value(s).
|
8
10
|
class CompositeTerm < Term
|
9
|
-
|
10
11
|
def children
|
11
12
|
raise NotImplementedError, 'This method must re-defined in subclass(es).'
|
12
13
|
end
|
13
14
|
|
14
15
|
# A composite term is fresh when all its members are nil or all non-nil members
|
15
16
|
# are all fresh
|
16
|
-
# A composite term is bound when it is not fresh and not ground
|
17
|
+
# A composite term is bound when it is not fresh and not ground
|
17
18
|
# A composite term is a ground term when all its non-nil members are ground.
|
18
19
|
# @param _env [Vocabulary]
|
19
|
-
# @return [Freshness]
|
20
|
+
# @return [Freshness]
|
20
21
|
def freshness(_env)
|
21
22
|
env.freshness_composite(self)
|
22
23
|
end
|
@@ -33,22 +34,6 @@ module MiniKraken
|
|
33
34
|
child.nil? || child.ground?(anEnv)
|
34
35
|
end
|
35
36
|
end
|
36
|
-
|
37
|
-
# # Data equality testing
|
38
|
-
# # @return [Boolean]
|
39
|
-
# def ==(other)
|
40
|
-
# if other.respond_to?(:value)
|
41
|
-
# value == other.value
|
42
|
-
# else
|
43
|
-
# value == other
|
44
|
-
# end
|
45
|
-
# end
|
46
|
-
|
47
|
-
# # Type and data equality testing
|
48
|
-
# # @return [Boolean]
|
49
|
-
# def eql?(other)
|
50
|
-
# (self.class == other.class) && value.eql?(other.value)
|
51
|
-
# end
|
52
37
|
end # class
|
53
38
|
end # module
|
54
|
-
end # module
|
39
|
+
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'composite_term'
|
2
4
|
|
3
5
|
module MiniKraken
|
@@ -23,17 +25,19 @@ module MiniKraken
|
|
23
25
|
|
24
26
|
def ==(other)
|
25
27
|
return false unless other.respond_to?(:car)
|
28
|
+
|
26
29
|
(car == other.car) && (cdr == other.cdr)
|
27
30
|
end
|
28
31
|
|
29
32
|
def eql?(other)
|
30
33
|
(self.class == other.class) && car.eql?(other.car) && cdr.eql?(other.cdr)
|
31
34
|
end
|
32
|
-
|
35
|
+
|
33
36
|
def quote(anEnv)
|
34
37
|
return self if null?
|
38
|
+
|
35
39
|
new_car = car.nil? ? nil : car.quote(anEnv)
|
36
|
-
new_cdr = cdr.nil? ? nil : cdr.quote(anEnv)
|
40
|
+
new_cdr = cdr.nil? ? nil : cdr.quote(anEnv)
|
37
41
|
ConsCell.new(new_car, new_cdr)
|
38
42
|
end
|
39
43
|
end # class
|
@@ -41,4 +45,4 @@ module MiniKraken
|
|
41
45
|
# Constant representing the null (empty) list.
|
42
46
|
NullList = ConsCell.new(nil, nil).freeze
|
43
47
|
end # module
|
44
|
-
end # module
|
48
|
+
end # module
|
@@ -1,17 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
1
4
|
require_relative 'vocabulary'
|
2
5
|
|
3
6
|
module MiniKraken
|
4
7
|
module Core
|
5
8
|
class Environment
|
6
|
-
include Vocabulary
|
9
|
+
include Vocabulary # Use mix-in module
|
7
10
|
|
11
|
+
# Mapping from user-defined name to Variable instance
|
8
12
|
# @return [Hash] Pairs of the kind {String => Variable}
|
9
13
|
attr_reader :vars
|
10
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
|
+
|
11
19
|
# @param aParent [Environment, NilClass] Parent environment to this one.
|
12
20
|
def initialize(aParent = nil)
|
13
21
|
init_vocabulary(aParent)
|
14
22
|
@vars = {}
|
23
|
+
@ivars = {}
|
15
24
|
end
|
16
25
|
|
17
26
|
# @param aVariable [Variable]
|
@@ -22,6 +31,13 @@ module MiniKraken
|
|
22
31
|
raise StandardError, err_msg
|
23
32
|
end
|
24
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
|
25
41
|
end
|
26
42
|
|
27
43
|
# Handler for the event: an outcome has been produced.
|
@@ -33,21 +49,19 @@ module MiniKraken
|
|
33
49
|
begin
|
34
50
|
env = walker.resume
|
35
51
|
break if env.nil?
|
36
|
-
|
52
|
+
|
53
|
+
env.do_propagate(descendent) if env.kind_of?(Environment)
|
37
54
|
end until env.equal?(self)
|
38
55
|
end
|
39
56
|
|
40
|
-
#
|
57
|
+
# Roll up associations from descendent outcome object
|
58
|
+
# @param descendent [Outcome]
|
41
59
|
def do_propagate(descendent)
|
42
|
-
return unless descendent.successful?
|
60
|
+
return unless descendent.successful?
|
43
61
|
|
44
62
|
vars.each_key do |var_name|
|
45
63
|
assocs = descendent[var_name]
|
46
|
-
|
47
|
-
own = self[var_name]
|
48
|
-
add_assoc(assoc) unless assoc.equal?(own)
|
49
|
-
end
|
50
|
-
descendent.associations.delete(var_name) unless assocs.empty?
|
64
|
+
move_assocs(var_name, descendent)
|
51
65
|
end
|
52
66
|
end
|
53
67
|
|
@@ -56,4 +70,4 @@ module MiniKraken
|
|
56
70
|
end
|
57
71
|
end # class
|
58
72
|
end # module
|
59
|
-
end # module
|
73
|
+
end # module
|