moory 1.1.0 → 1.1.2
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/Gemfile.lock +1 -1
- data/examples/inductive.rb +66 -10
- data/lib/moory/decoder.rb +0 -5
- data/lib/moory/logistic.rb +4 -2
- data/lib/moory/machine.rb +0 -9
- data/lib/moory/recogniser.rb +0 -5
- data/lib/moory/repertoire.rb +0 -15
- data/lib/moory/transitions.rb +0 -29
- data/lib/moory/version.rb +1 -1
- 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: e1e1b029fd85b751396919e05fa902cbbf1e2198fcd20d44f614325dd8b556ad
|
|
4
|
+
data.tar.gz: b8056903c89db21097d1678f93c05b60689dcfbf666e82cda2fdd2874f4a4f98
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6aeab425171302916915af4ada63d24a6d0dadccd6030cdc7342dcaf5f8a61812002575ffee751b1cfe897012f64462945e1c59ed068fb6e5d48a22d0d716bdb
|
|
7
|
+
data.tar.gz: f1647149a2dccd90e9245c789a3e788855989d04530c709c4ae4ba322bc0bd7db0349a61cce2f6b5d9ec4b4be7ab5b0570cb831e6837a2b43dc2bd3e5fc79f2e
|
data/Gemfile.lock
CHANGED
data/examples/inductive.rb
CHANGED
|
@@ -1,29 +1,85 @@
|
|
|
1
1
|
require 'moory'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
pipcv_config = {
|
|
4
4
|
basis: 'basis',
|
|
5
5
|
specs: {
|
|
6
6
|
'basis' => {
|
|
7
|
-
initial: 'ε',
|
|
8
7
|
rules: """
|
|
9
|
-
|
|
8
|
+
^ : constant : $
|
|
9
|
+
|
|
10
|
+
^ : variable : $
|
|
11
|
+
|
|
12
|
+
^ : prefix / open / defer : Δ
|
|
13
|
+
|
|
14
|
+
^ : ( / parenthetical / defer : Δ
|
|
15
|
+
|
|
16
|
+
$ : infix / open / defer : Δ
|
|
17
|
+
|
|
18
|
+
Δ : term : $
|
|
19
|
+
""",
|
|
20
|
+
},
|
|
21
|
+
'open' => {
|
|
22
|
+
rules: """
|
|
23
|
+
^ : constant / term / reconvene : $
|
|
24
|
+
|
|
25
|
+
^ : variable / term / reconvene : $
|
|
26
|
+
|
|
27
|
+
^ : prefix / open / defer : Δ
|
|
28
|
+
|
|
29
|
+
^ : ( / parenthetical / defer : Δ
|
|
30
|
+
|
|
31
|
+
$ : infix / open / defer : Δ
|
|
32
|
+
|
|
33
|
+
Δ : term / term / reconvene : $
|
|
10
34
|
""",
|
|
11
35
|
},
|
|
12
36
|
'parenthetical' => {
|
|
13
|
-
initial: 'ε',
|
|
14
37
|
rules: """
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
38
|
+
^ : constant : C
|
|
39
|
+
|
|
40
|
+
^ : variable : C
|
|
41
|
+
|
|
42
|
+
^ : prefix / open / defer : Δ
|
|
43
|
+
|
|
44
|
+
^ : ( / parenthetical / defer : Δ
|
|
45
|
+
|
|
46
|
+
^ : ) / void / reconvene : $
|
|
47
|
+
|
|
48
|
+
C : infix / open / defer : Δ
|
|
49
|
+
|
|
50
|
+
C : ) / term / reconvene : $
|
|
51
|
+
|
|
52
|
+
Δ : term : C
|
|
18
53
|
"""
|
|
19
54
|
}
|
|
20
55
|
}
|
|
21
56
|
}
|
|
22
57
|
|
|
23
|
-
logistic = Moory::Logistic::Controller.new(
|
|
58
|
+
logistic = Moory::Logistic::Controller.new(pipcv_config)
|
|
24
59
|
|
|
25
|
-
|
|
26
|
-
|
|
60
|
+
%w{
|
|
61
|
+
(
|
|
62
|
+
(
|
|
63
|
+
prefix
|
|
64
|
+
constant
|
|
65
|
+
infix
|
|
66
|
+
prefix
|
|
67
|
+
(
|
|
68
|
+
variable
|
|
69
|
+
infix
|
|
70
|
+
prefix
|
|
71
|
+
(
|
|
72
|
+
variable
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
infix
|
|
78
|
+
}.each do |w|
|
|
79
|
+
logistic.issue(w)
|
|
27
80
|
end
|
|
28
81
|
|
|
82
|
+
pp logistic.deferrals
|
|
83
|
+
|
|
29
84
|
pp logistic.done?
|
|
85
|
+
|
data/lib/moory/decoder.rb
CHANGED
|
@@ -9,11 +9,6 @@ module Moory
|
|
|
9
9
|
configure(rules)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
# Decode a string according to the rules. Writes the decoded string to the output
|
|
13
|
-
# stream configured at initialisation (which is $stdout, by default). Characters
|
|
14
|
-
# not belonging to the alphabet will be dropped.
|
|
15
|
-
#
|
|
16
|
-
# @param string [String] the string you wish to decode
|
|
17
12
|
def decode(string)
|
|
18
13
|
string.each_char { |c| issue(c) }
|
|
19
14
|
end
|
data/lib/moory/logistic.rb
CHANGED
|
@@ -3,7 +3,7 @@ module Moory
|
|
|
3
3
|
class Unit
|
|
4
4
|
include Moory::Efferent
|
|
5
5
|
|
|
6
|
-
def initialize(rules:, initial:)
|
|
6
|
+
def initialize(rules:, initial:'^')
|
|
7
7
|
@initial = initial
|
|
8
8
|
configure(rules)
|
|
9
9
|
end
|
|
@@ -90,13 +90,15 @@ module Moory
|
|
|
90
90
|
active_unit.prime
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
def reconvene
|
|
93
|
+
def reconvene(stimulus=nil)
|
|
94
94
|
raise "Cannot reconvene without prior deferral" if deferrals.empty?
|
|
95
95
|
|
|
96
96
|
deferrals.pop.tap do |last_deferral|
|
|
97
97
|
focus_on(last_deferral[:name])
|
|
98
98
|
active_unit.state = last_deferral[:state]
|
|
99
99
|
end
|
|
100
|
+
|
|
101
|
+
active_unit.issue(stimulus) if stimulus
|
|
100
102
|
end
|
|
101
103
|
end
|
|
102
104
|
end
|
data/lib/moory/machine.rb
CHANGED
|
@@ -12,25 +12,16 @@ module Moory
|
|
|
12
12
|
@transitions ||= Moory::Transition::Storage.new
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
# Issue a stimulus to the machine.
|
|
16
|
-
#
|
|
17
|
-
# @return will either be the new `settlement`, or `nil` if the stimulus is not understood.
|
|
18
15
|
def issue(stimulus)
|
|
19
16
|
if response = transitions.response(origin: state, stimulus: stimulus)
|
|
20
17
|
honour(response)
|
|
21
18
|
end
|
|
22
19
|
end
|
|
23
20
|
|
|
24
|
-
# Reveals the stimuli to which the machine may respond in its current state.
|
|
25
|
-
#
|
|
26
|
-
# @return [Set]
|
|
27
21
|
def awaits
|
|
28
22
|
transitions.egresses(state:state)
|
|
29
23
|
end
|
|
30
24
|
|
|
31
|
-
# Answers whether a machine can respond to the given stimlus in its current state.
|
|
32
|
-
#
|
|
33
|
-
# @return [Boolean]
|
|
34
25
|
def understand?(stimulus)
|
|
35
26
|
awaits.include?(stimulus)
|
|
36
27
|
end
|
data/lib/moory/recogniser.rb
CHANGED
|
@@ -8,11 +8,6 @@ module Moory
|
|
|
8
8
|
Loader.load(rules: rules, machine: self)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
# Answers whether the given string is accepted; that is, does it belong to
|
|
12
|
-
# the language described by the rules?
|
|
13
|
-
#
|
|
14
|
-
# @param string [String] the candidate string.
|
|
15
|
-
# @return [Boolean] true if the string is accepted; false, otherwise.
|
|
16
11
|
def accepts?(string)
|
|
17
12
|
reset
|
|
18
13
|
|
data/lib/moory/repertoire.rb
CHANGED
|
@@ -6,9 +6,6 @@ module Moory
|
|
|
6
6
|
attr_reader :fallback
|
|
7
7
|
attr_reader :always
|
|
8
8
|
|
|
9
|
-
# Create a repertoire from a Hash mapping names to callable objects.
|
|
10
|
-
#
|
|
11
|
-
# @return [Repertoire]
|
|
12
9
|
def Repertoire.from_hash(hash={})
|
|
13
10
|
new.tap { |r| r.cram(hash) }
|
|
14
11
|
end
|
|
@@ -19,28 +16,16 @@ module Moory
|
|
|
19
16
|
@knowledge = {}
|
|
20
17
|
end
|
|
21
18
|
|
|
22
|
-
# Learn multiple items of knowledge.
|
|
23
19
|
def cram(hash={})
|
|
24
20
|
hash.each { |k,v| learn(name: k, item: v) }
|
|
25
21
|
end
|
|
26
22
|
|
|
27
|
-
# Associate a name with a callable object. The item will not be stored unless it is callable;
|
|
28
|
-
# that is, it must respond to `:call`.
|
|
29
|
-
#
|
|
30
|
-
# @param item the callable object you want to store.
|
|
31
|
-
# @param name the name you will use to identify the `item`.
|
|
32
23
|
def learn(item:,name:)
|
|
33
24
|
@knowledge.store(name, item) if (
|
|
34
25
|
appropriate?(item) && name
|
|
35
26
|
)
|
|
36
27
|
end
|
|
37
28
|
|
|
38
|
-
# Recall a callable object by name.
|
|
39
|
-
#
|
|
40
|
-
# @param the name identifying the object you want to retrieve.
|
|
41
|
-
# @return if the given value represents knowledge, then that which has been learned is returned.
|
|
42
|
-
# If the name does not represent an item of knowledge, then the `fallback` is returned. You will
|
|
43
|
-
# always get something callable when you call this method.
|
|
44
29
|
def recall(name)
|
|
45
30
|
name ?
|
|
46
31
|
knowledge.fetch(name, fallback) :
|
data/lib/moory/transitions.rb
CHANGED
|
@@ -2,46 +2,27 @@ require 'set'
|
|
|
2
2
|
|
|
3
3
|
module Moory
|
|
4
4
|
module Transition
|
|
5
|
-
# Serves as a transition relation.
|
|
6
5
|
class Storage
|
|
7
6
|
def count
|
|
8
7
|
storage.size
|
|
9
8
|
end
|
|
10
9
|
|
|
11
|
-
# Store a transition described by a hash
|
|
12
|
-
#
|
|
13
|
-
# @param params [Hash] a hash describing a transition. At a minimum,
|
|
14
|
-
# it should include `:origin`, `:stimulus`, and `:settlement`.
|
|
15
|
-
# It may also include `:output` and `:effector`.
|
|
16
10
|
def store(params)
|
|
17
11
|
storage.merge!(Hasher.new(params)) do |key, oldval, newval|
|
|
18
12
|
oldval.merge!(newval)
|
|
19
13
|
end
|
|
20
14
|
end
|
|
21
15
|
|
|
22
|
-
# Retrieve the unique response to a stimulus from a given origin.
|
|
23
|
-
#
|
|
24
|
-
# @return [Hash, nil] if the given parameters represent a transition, a Hash is returned
|
|
25
|
-
# including at least a `:settlement`, and maybe one/both of `:output` and `:effector`.
|
|
26
|
-
# If the paremeters do not correspond to a uniqu transition, `nil` is returned.
|
|
27
16
|
def response(origin:, stimulus:)
|
|
28
17
|
storage.dig(origin, stimulus)
|
|
29
18
|
end
|
|
30
19
|
|
|
31
|
-
# Retrieve the states represented by the transition relation.
|
|
32
|
-
#
|
|
33
|
-
# @return [Set]
|
|
34
20
|
def states
|
|
35
21
|
storage
|
|
36
22
|
.keys
|
|
37
23
|
.to_set
|
|
38
24
|
end
|
|
39
25
|
|
|
40
|
-
# Retrieve the alphabet
|
|
41
|
-
#
|
|
42
|
-
# @param restrict retricts the alphabet to that subset applicable to the state named by
|
|
43
|
-
# the given value.
|
|
44
|
-
# @return [Set]
|
|
45
26
|
def alphabet(restrict:nil)
|
|
46
27
|
storage
|
|
47
28
|
.select { |k| restrict ? k == restrict : true }
|
|
@@ -51,25 +32,15 @@ module Moory
|
|
|
51
32
|
.to_set
|
|
52
33
|
end
|
|
53
34
|
|
|
54
|
-
# Retrieve the egresses for the given state.
|
|
55
|
-
#
|
|
56
|
-
# @param state identifies the state for which egresses are being sought.
|
|
57
|
-
# @return [Set]
|
|
58
35
|
def egresses(state:)
|
|
59
36
|
alphabet(restrict: state)
|
|
60
37
|
end
|
|
61
38
|
|
|
62
|
-
# Returns the transition relation.
|
|
63
|
-
#
|
|
64
|
-
# @return [Hash] represents the transition relation as a mapping from
|
|
65
|
-
# (state, stimulus) to (settlement, output, effector).
|
|
66
39
|
def storage
|
|
67
40
|
@storage ||= {}
|
|
68
41
|
end
|
|
69
42
|
end
|
|
70
43
|
|
|
71
|
-
# Helps expand a flat-hash description of a transition into a form
|
|
72
|
-
# amenable to storage.
|
|
73
44
|
Hasher = Struct.new(
|
|
74
45
|
:origin,
|
|
75
46
|
:stimulus,
|
data/lib/moory/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moory
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Adam W. Grant
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-
|
|
11
|
+
date: 2018-08-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|