rlsm 0.2.4 → 0.4.0
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.
- data/History.txt +0 -0
- data/Manifest.txt +3 -28
- data/README.txt +0 -0
- data/Rakefile +0 -0
- data/bin/smon +1 -3
- data/lib/data/monoids.db +0 -0
- data/lib/dfa.rb +656 -0
- data/lib/monoid.rb +778 -0
- data/lib/re.rb +492 -0
- data/lib/rlsm.rb +57 -36
- metadata +5 -30
- data/lib/rlsm/dfa.rb +0 -705
- data/lib/rlsm/exceptions.rb +0 -39
- data/lib/rlsm/mgen.rb +0 -138
- data/lib/rlsm/monkey_patching.rb +0 -126
- data/lib/rlsm/monoid.rb +0 -552
- data/lib/rlsm/monoid_db.rb +0 -123
- data/lib/rlsm/regexp.rb +0 -229
- data/lib/rlsm/regexp_nodes/concat.rb +0 -112
- data/lib/rlsm/regexp_nodes/primexp.rb +0 -49
- data/lib/rlsm/regexp_nodes/renodes.rb +0 -95
- data/lib/rlsm/regexp_nodes/star.rb +0 -50
- data/lib/rlsm/regexp_nodes/union.rb +0 -85
- data/lib/smon/commands/db_find.rb +0 -37
- data/lib/smon/commands/db_stat.rb +0 -20
- data/lib/smon/commands/exit.rb +0 -9
- data/lib/smon/commands/help.rb +0 -31
- data/lib/smon/commands/intro.rb +0 -32
- data/lib/smon/commands/monoid.rb +0 -27
- data/lib/smon/commands/quit.rb +0 -10
- data/lib/smon/commands/regexp.rb +0 -20
- data/lib/smon/commands/reload.rb +0 -22
- data/lib/smon/commands/show.rb +0 -21
- data/lib/smon/presenter.rb +0 -18
- data/lib/smon/presenter/txt_presenter.rb +0 -157
- data/lib/smon/smon.rb +0 -79
- data/test/dfa_spec.rb +0 -99
- data/test/monoid_spec.rb +0 -270
- data/test/regexp_spec.rb +0 -25
data/lib/smon/commands/quit.rb
DELETED
data/lib/smon/commands/regexp.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
#category RLSM
|
2
|
-
=begin help
|
3
|
-
Creates a new Regular Expression.
|
4
|
-
|
5
|
-
Usage: regexp "desc"
|
6
|
-
|
7
|
-
+desc+ is here a description of the regexp.
|
8
|
-
A regexp may consist of
|
9
|
-
- normal characters like a,b,c, 1,2, ...
|
10
|
-
- Special characters are
|
11
|
-
- & : the emmpty word
|
12
|
-
- | : Union
|
13
|
-
- ( ) : Grouping of expressions
|
14
|
-
- * : Kleene star
|
15
|
-
|
16
|
-
=end
|
17
|
-
|
18
|
-
def regexp(desc)
|
19
|
-
RLSM::RegExp.new desc
|
20
|
-
end
|
data/lib/smon/commands/reload.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
#category base
|
2
|
-
=begin help
|
3
|
-
Reloads a command.
|
4
|
-
|
5
|
-
Usage: reload "cmd"
|
6
|
-
|
7
|
-
Unloads the command +cmd+ if it exists, then tries to reload it.
|
8
|
-
For reloading, the program searches for an file "cmd.rb" in the load path.
|
9
|
-
=end
|
10
|
-
|
11
|
-
def reload(cmd)
|
12
|
-
return false unless Commands.include? cmd
|
13
|
-
|
14
|
-
#Removes the help entries and the command
|
15
|
-
Commands.delete cmd
|
16
|
-
CmdHelp.delete cmd
|
17
|
-
Categories.each do |cat|
|
18
|
-
cat.delete cmd
|
19
|
-
end
|
20
|
-
|
21
|
-
load(File.join(LoadPath, cmd + '.rb'))
|
22
|
-
end
|
data/lib/smon/commands/show.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
#category RLSM
|
2
|
-
=begin help
|
3
|
-
Shows a monoid or a regexp.
|
4
|
-
|
5
|
-
Usage: show obj
|
6
|
-
|
7
|
-
+obj+ is either a regexp or a monoid. If regexp a string representation is shown
|
8
|
-
if monoid, the binary operation is shown as a table.
|
9
|
-
Example: show monoid("0")
|
10
|
-
Not working: show "0" !
|
11
|
-
=end
|
12
|
-
|
13
|
-
def show(obj)
|
14
|
-
if obj.class == Array
|
15
|
-
obj.each { |o| puts Presenter.to_txt o }
|
16
|
-
puts
|
17
|
-
else
|
18
|
-
puts Presenter.to_txt obj
|
19
|
-
puts
|
20
|
-
end
|
21
|
-
end
|
data/lib/smon/presenter.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'presenter', 'txt_presenter')
|
2
|
-
|
3
|
-
class Presenter
|
4
|
-
#Returns a LaTeX representation of the given object as a string.
|
5
|
-
def self.to_tex(obj, opts = {})
|
6
|
-
puts "Not yet implemented"
|
7
|
-
end
|
8
|
-
|
9
|
-
#Returns an ASCII representation of the given object as a string.
|
10
|
-
def self.to_txt(obj)
|
11
|
-
TxtPresenter.new.output obj
|
12
|
-
end
|
13
|
-
|
14
|
-
#Creates a pdf document in the tmp directory.
|
15
|
-
def self.to_pdf(obj, opts = {})
|
16
|
-
puts "Not yet implemented"
|
17
|
-
end
|
18
|
-
end
|
@@ -1,157 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '..', '..', 'rlsm')
|
2
|
-
|
3
|
-
class TxtPresenter
|
4
|
-
#Returns a string with a txt representation of the given object.
|
5
|
-
def output(obj)
|
6
|
-
self.send obj.class.to_s[(6..-1)].downcase.to_sym, obj
|
7
|
-
end
|
8
|
-
|
9
|
-
private
|
10
|
-
def monoid(m, with_syntactic_stuff = true)
|
11
|
-
out = "Monoid '#{m.hash}':\n"
|
12
|
-
|
13
|
-
#The binary operation:
|
14
|
-
out += binop_to_txt(m)
|
15
|
-
|
16
|
-
#The properties
|
17
|
-
out += basic_props(m)
|
18
|
-
out += submonoids_to_txt(m)
|
19
|
-
out += classes_to_txt(m)
|
20
|
-
out += special_elements(m)
|
21
|
-
|
22
|
-
out += syntactic_stuff(m) if with_syntactic_stuff and m.syntactic?
|
23
|
-
|
24
|
-
out
|
25
|
-
end
|
26
|
-
|
27
|
-
def regexp(re)
|
28
|
-
out = "RegExp: #{re.to_s}\n\n"
|
29
|
-
out += "Corresponding DFA:\n"
|
30
|
-
dfa = re.to_dfa
|
31
|
-
out += dfa.to_s + "\n\n"
|
32
|
-
out += "Corresponding syntactic monoid:\n"
|
33
|
-
out + monoid(dfa.syntactic_monoid, false)
|
34
|
-
end
|
35
|
-
|
36
|
-
def dfa(dfa)
|
37
|
-
min = dfa.minimal?
|
38
|
-
|
39
|
-
out = "DFA"
|
40
|
-
if min
|
41
|
-
out += " (is minimal):\n"
|
42
|
-
else
|
43
|
-
out += " (not minimal):\n"
|
44
|
-
end
|
45
|
-
|
46
|
-
out += dfa.to_s
|
47
|
-
out += "\nCorresponding RegExp: #{dfa.to_regexp}\n\n"
|
48
|
-
|
49
|
-
if min
|
50
|
-
out += "Transition monoid:\n"
|
51
|
-
out += monoid(dfa.syntactic_monoid, false)
|
52
|
-
else
|
53
|
-
out += "Transition monoid:\n"
|
54
|
-
out += binop_to_txt(dfa.transition_monoid)
|
55
|
-
out += "\n\nSyntactic Monoid (the transition monoid of the minimal DFA):\n"
|
56
|
-
out += monoid(dfa.syntactic_monoid, false)
|
57
|
-
end
|
58
|
-
|
59
|
-
out
|
60
|
-
end
|
61
|
-
|
62
|
-
def set_to_list(set, names)
|
63
|
-
set.map {|x| names[x]}.join(', ')
|
64
|
-
end
|
65
|
-
|
66
|
-
def translate_binop(m)
|
67
|
-
m.binary_operation.flatten.map { |c| m.elements[c] } / m.order
|
68
|
-
end
|
69
|
-
|
70
|
-
def binop_to_txt(m)
|
71
|
-
table = translate_binop(m)
|
72
|
-
col_width = (0...m.order).to_a.map { |i| table.map { |r| r[i].length }.max }
|
73
|
-
|
74
|
-
i = -1
|
75
|
-
table.map! do |row|
|
76
|
-
i += 1
|
77
|
-
row.inject("|") { |r,x| r + " #{x} " + " "*(col_width[i]-x.length) + "|" }
|
78
|
-
end
|
79
|
-
|
80
|
-
row_sep = "\n" + table.first.scan(/./m).map { |c| c == '|' ? '+' : '-' }.join + "\n"
|
81
|
-
|
82
|
-
row_sep + table.join(row_sep) + row_sep + "\n"
|
83
|
-
end
|
84
|
-
|
85
|
-
def basic_props(m)
|
86
|
-
out = "Order: #{m.order}\n"
|
87
|
-
out += "Generators: #{set_to_list m.generating_subset, m.elements}\n"
|
88
|
-
out + "Properties: #{props m}\n\n"
|
89
|
-
end
|
90
|
-
|
91
|
-
def props(m)
|
92
|
-
str = ['commutative', 'idempotent', 'aperiodic', 'syntactic', 'group'].select do |p|
|
93
|
-
m.send((p + '?').to_sym)
|
94
|
-
end.join(', ')
|
95
|
-
end
|
96
|
-
|
97
|
-
def submonoids_to_txt(m)
|
98
|
-
psm = m.proper_submonoids
|
99
|
-
out = "Submonoids: "
|
100
|
-
|
101
|
-
if psm.empty?
|
102
|
-
out += "none\n\n"
|
103
|
-
else
|
104
|
-
out += psm.map! do |sm|
|
105
|
-
translate_binop(sm).map { |r| r.join(sm.order > 10 ? ',' : '') }.join(" ")
|
106
|
-
end.join("; ")
|
107
|
-
|
108
|
-
out += "\n\n"
|
109
|
-
end
|
110
|
-
|
111
|
-
out
|
112
|
-
end
|
113
|
-
|
114
|
-
def classes_to_txt(m)
|
115
|
-
out = "L-Classes: " + m.l_classes.map { |c| "{#{ set_to_list c, m.elements}}" }.join('; ')
|
116
|
-
out += "\n"
|
117
|
-
out += "R-Classes: " + m.r_classes.map { |c| "{#{ set_to_list c, m.elements}}" }.join('; ')
|
118
|
-
out += "\n"
|
119
|
-
out += "H-Classes: " + m.h_classes.map { |c| "{#{ set_to_list c, m.elements}}" }.join('; ')
|
120
|
-
out += "\n"
|
121
|
-
out += "D-Classes: " + m.d_classes.map { |c| "{#{ set_to_list c, m.elements}}" }.join('; ')
|
122
|
-
out + "\n\n"
|
123
|
-
end
|
124
|
-
|
125
|
-
def special_elements(m)
|
126
|
-
out = "Special Elements:\n"
|
127
|
-
out += "Null Element: " + (m.null_element ? m.elements[m.null_element] : 'none') + "\n"
|
128
|
-
out += "Idempotents: #{set_to_list m.idempotents, m.elements}\n"
|
129
|
-
|
130
|
-
unless m.null_element
|
131
|
-
rn, ln = m.right_nulls, m.left_nulls
|
132
|
-
unless rn.empty?
|
133
|
-
out += "Right Nulls: #{set_to_list rn, m.elements}\n"
|
134
|
-
end
|
135
|
-
|
136
|
-
unless ln.empty?
|
137
|
-
out += "Left Nulls: #{set_to_list ln, m.elements}\n"
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
out + "\n"
|
142
|
-
end
|
143
|
-
|
144
|
-
def syntactic_stuff(m)
|
145
|
-
out = "Disjunctive Subsets: " + m.all_disjunctive_subsets.map do |dss|
|
146
|
-
"{"+ set_to_list(dss, m.elements) + "}"
|
147
|
-
end.join("; ") + "\n"
|
148
|
-
|
149
|
-
dfa = m.to_dfa
|
150
|
-
re = dfa.to_regexp
|
151
|
-
|
152
|
-
out += "DFA for {#{set_to_list m.disjunctive_subset, m.elements}}:\n"
|
153
|
-
out += dfa.to_s + "\n\n"
|
154
|
-
|
155
|
-
out + "Corresponding RegExp: #{re.to_s}\n\n"
|
156
|
-
end
|
157
|
-
end
|
data/lib/smon/smon.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
require "readline"
|
2
|
-
require "abbrev"
|
3
|
-
require "rubygems"
|
4
|
-
require File.join(File.dirname(__FILE__), '..', 'rlsm')
|
5
|
-
require File.join(File.dirname(__FILE__), 'presenter')
|
6
|
-
|
7
|
-
class Smon
|
8
|
-
Commands = []
|
9
|
-
CmdHelp = {}
|
10
|
-
Categories = {}
|
11
|
-
LoadPath = File.join(File.dirname(__FILE__), 'commands')
|
12
|
-
|
13
|
-
def initialize
|
14
|
-
#Load all commands
|
15
|
-
cmds = Dir.glob(File.join(LoadPath, '*.rb'))
|
16
|
-
cmds.each do |cmd|
|
17
|
-
load cmd, false
|
18
|
-
end
|
19
|
-
|
20
|
-
#Add the built-in commands to the help system
|
21
|
-
Commands << 'load'
|
22
|
-
CmdHelp['load'] = ["Loads a command into the system.\n",
|
23
|
-
"\nUsage: load /path/to/cmd\n",
|
24
|
-
"\n Loads the file at the given location and prints a small message if loading succeded."]
|
25
|
-
Categories['built-in'] = ['load']
|
26
|
-
|
27
|
-
#Initialize the help system
|
28
|
-
@cmd_abbrev = Commands.abbrev
|
29
|
-
|
30
|
-
#Setting up readline
|
31
|
-
Readline.completion_proc = lambda { |str| @cmd_abbrev[str] }
|
32
|
-
|
33
|
-
loop do
|
34
|
-
begin
|
35
|
-
instance_eval Readline.readline("rlsm (help for help) :> ", true)
|
36
|
-
rescue Exception => e
|
37
|
-
puts "Something went wrong."
|
38
|
-
puts e
|
39
|
-
end
|
40
|
-
|
41
|
-
break if @quit
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def load(file, reinit = true)
|
46
|
-
#Parsing the file
|
47
|
-
cat = nil
|
48
|
-
name = nil
|
49
|
-
help = []
|
50
|
-
parse_help = false
|
51
|
-
input = []
|
52
|
-
File.open(file).each_line do |line|
|
53
|
-
#Extracting the help
|
54
|
-
parse_help = false if line =~ Regexp.new("=end.*")
|
55
|
-
help << line if parse_help
|
56
|
-
parse_help = true if line =~ Regexp.new("=begin.*")
|
57
|
-
|
58
|
-
|
59
|
-
#Getting the category
|
60
|
-
cat = $1.dup if line =~ Regexp.new("#category\\s\+\(\\w\+\)")
|
61
|
-
|
62
|
-
#Getting the name
|
63
|
-
name = $1.dup if line =~ /def\s+(\w+)/
|
64
|
-
|
65
|
-
input << line
|
66
|
-
end
|
67
|
-
|
68
|
-
#Adding the method
|
69
|
-
self.class.class_eval input.join
|
70
|
-
|
71
|
-
#Setting up the help system
|
72
|
-
(Categories[cat] ||= []) << name
|
73
|
-
Commands << name
|
74
|
-
CmdHelp[name] = help
|
75
|
-
|
76
|
-
@cmd_abbrev = Commands.abbrev if reinit
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
data/test/dfa_spec.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '..', 'lib', 'rlsm', 'dfa')
|
2
|
-
|
3
|
-
describe RLSM::DFA do
|
4
|
-
before :each do
|
5
|
-
@dfa = RLSM::DFA.new ['a'],[0],0,[0],[['a',0,0]]
|
6
|
-
@dfa2 = RLSM::DFA.new( ['a', 'b'], [0,1,2], 0, [2],
|
7
|
-
[['a',0,0], ['a',1,2], ['a',2,2],
|
8
|
-
['b',0,1], ['b',1,1], ['b',2,2]])
|
9
|
-
@dfa3 = RLSM::DFA.new( ['a', 'b'], [0,1,2], 0, [2],
|
10
|
-
[['a',0,0], ['a',1,2], ['a',2,2],
|
11
|
-
['b',0,1], ['b',1,1]])
|
12
|
-
|
13
|
-
@dfa4 = RLSM::DFA.new( ['a', 'b'], [0,1,2,3,4], 0, [2,3],
|
14
|
-
[['a',0,0], ['a',1,2], ['a',2,2],
|
15
|
-
['b',0,1], ['b',1,1],
|
16
|
-
['a',3,4], ['a',4,3], ['b',3,2]])
|
17
|
-
|
18
|
-
@dfa5 = RLSM::DFA.new( ['a', 'b'], [0,1,2], 0, [1],
|
19
|
-
[['a',0,0], ['a',1,2], ['a',2,2],
|
20
|
-
['b',0,1], ['b',1,1]])
|
21
|
-
|
22
|
-
@dfa5b = RLSM::DFA.new( ['a', 'b'], [0,1,'c'], 0, [1],
|
23
|
-
[['a',0,0], ['a',1,'c'], ['a','c','c'],
|
24
|
-
['b',0,1], ['b',1,1]])
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should have an initial state" do
|
28
|
-
@dfa.initial_state.should_not be_nil
|
29
|
-
@dfa.initial_state.label.should == '0'
|
30
|
-
@dfa2.initial_state.should_not be_nil
|
31
|
-
@dfa2.initial_state.label.should == '0'
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should know the number of states" do
|
35
|
-
@dfa.num_states.should == 1
|
36
|
-
@dfa2.num_states.should == 3
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should know the number of final states" do
|
40
|
-
@dfa.num_finals.should == 1
|
41
|
-
@dfa2.num_finals.should == 1
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should know if it is complete" do
|
45
|
-
@dfa.complete?.should == true
|
46
|
-
@dfa2.complete?.should == true
|
47
|
-
@dfa3.complete?.should == false
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should complete a non complete DFA if requested" do
|
51
|
-
@dfa3.complete.should be_complete
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should find dead states" do
|
55
|
-
[@dfa,@dfa2,@dfa3].each { |d| d.dead_states?.should == false }
|
56
|
-
|
57
|
-
@dfa5.dead_states?.should == true
|
58
|
-
@dfa5.dead_states.map { |s| s.label }.should == ['2']
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should find unreachable states" do
|
62
|
-
[@dfa,@dfa2,@dfa3].each { |d| d.unreachable_states?.should == false }
|
63
|
-
|
64
|
-
@dfa4.unreachable_states?.should == true
|
65
|
-
@dfa4.unreachable_states.size.should == 2
|
66
|
-
@dfa4.unreachable_states.map { |s| s.label }.sort.should == ['3','4']
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should remove dead states" do
|
70
|
-
@dfa5.remove_dead_states.states.map { |s| s.label }.should == ['0','1']
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should remove unreachable states" do
|
74
|
-
d = @dfa4.remove_unreachable_states
|
75
|
-
d.states.map { |s| s.label }.sort.should == ['0','1','2']
|
76
|
-
end
|
77
|
-
|
78
|
-
it "should minimize a DFA" do
|
79
|
-
d = RLSM::DFA.new(['a','b','c'], [0,1,2,3,4], 0, [4],
|
80
|
-
[['a',0,1], ['b',0,2], ['c',1,3], ['c',2,3], ['c',3,4]])
|
81
|
-
|
82
|
-
d.minimize!
|
83
|
-
d.states.map { |s| s.label }.sort.should == ['0','12', '3','4']
|
84
|
-
end
|
85
|
-
|
86
|
-
it "should check for isomorphisms" do
|
87
|
-
@dfa2.should be_isomorph_to(@dfa2)
|
88
|
-
@dfa5.should be_isomorph_to(@dfa5b)
|
89
|
-
@dfa3.should_not be_isomorph_to(@dfa2)
|
90
|
-
end
|
91
|
-
|
92
|
-
it "should calculate the transition monoid" do
|
93
|
-
@dfa.transition_monoid.should == RLSM::Monoid.new('0')
|
94
|
-
end
|
95
|
-
|
96
|
-
it "should caclulate a RegExp representation" do
|
97
|
-
@dfa.to_regexp.to_s.should == 'a*'
|
98
|
-
end
|
99
|
-
end
|
data/test/monoid_spec.rb
DELETED
@@ -1,270 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '..', 'lib', 'rlsm', 'monoid')
|
2
|
-
|
3
|
-
describe RLSM::Monoid, "basic stuff" do
|
4
|
-
before :each do
|
5
|
-
@m1 = RLSM::Monoid.new '0'
|
6
|
-
@m2 = RLSM::Monoid.new '00 01' #-> 01 11
|
7
|
-
@m3 = RLSM::Monoid.new '012 112 212'
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should have '0' as the neutral element" do
|
11
|
-
@m1[0,0].should == 0
|
12
|
-
|
13
|
-
[0,1].each { |x| @m2[0,x].should == x; @m2[x,0].should == x }
|
14
|
-
[0,1,2].each { |x| @m3[0,x].should == x; @m3[x,0].should == x }
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should decide if an other monoid is isomorphic" do
|
18
|
-
@m2.should == RLSM::Monoid.new('01 11')
|
19
|
-
@m3.should == RLSM::Monoid.new('002 012 022')
|
20
|
-
|
21
|
-
@m2.should_not == @m3
|
22
|
-
|
23
|
-
@m2.should_not == RLSM::Monoid.new('01 10')
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
describe RLSM::Monoid do
|
29
|
-
before :each do
|
30
|
-
@m0 = RLSM::Monoid.new '0'
|
31
|
-
@m1 = RLSM::Monoid.new '01 11'
|
32
|
-
@m2 = RLSM::Monoid.new '0123 1032 2323 3232'
|
33
|
-
end
|
34
|
-
|
35
|
-
[[],[0],[1], [2], [1,2], [1,3], [2,3], [1,2,3]].each do |set|
|
36
|
-
@m0 = RLSM::Monoid.new '0'
|
37
|
-
@m1 = RLSM::Monoid.new '01 11'
|
38
|
-
@m2 = RLSM::Monoid.new '0123 1032 2323 3232'
|
39
|
-
|
40
|
-
case set
|
41
|
-
when [], [0]
|
42
|
-
[@m0, @m1, @m2].each do |m|
|
43
|
-
it "should calculate the submonoid of #{m} generated by #{set}" do
|
44
|
-
sm = m.get_submonoid(set)
|
45
|
-
sm.should_not be_nil
|
46
|
-
sm.should == RLSM::Monoid.new('0')
|
47
|
-
end
|
48
|
-
end
|
49
|
-
when [1]
|
50
|
-
it "should calculate the submonoid of #{@m1} generated by #{set}" do
|
51
|
-
@m1.get_submonoid(set).should == @m1
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should calculate the submonoid of #{@m2} generated by #{set}" do
|
55
|
-
@m2.get_submonoid(set).should == RLSM::Monoid.new('01 10')
|
56
|
-
end
|
57
|
-
when [2]
|
58
|
-
it "should calculate the submonoid of #{@m2} generated by #{set}" do
|
59
|
-
@m2.get_submonoid(set).should == @m1
|
60
|
-
end
|
61
|
-
when [1,2]
|
62
|
-
it "should calculate the submonoid of #{@m2} generated by #{set}" do
|
63
|
-
@m2.get_submonoid(set).should == @m2
|
64
|
-
end
|
65
|
-
when [1,3]
|
66
|
-
it "should calculate the submonoid of #{@m2} generated by #{set}" do
|
67
|
-
@m2.get_submonoid(set).should == @m2
|
68
|
-
end
|
69
|
-
when [2,3]
|
70
|
-
it "should calculate the submonoid of #{@m2} generated by #{set}" do
|
71
|
-
@m2.get_submonoid(set).should == RLSM::Monoid.new('012 112 221')
|
72
|
-
end
|
73
|
-
when [1,2,3]
|
74
|
-
it "should calculate the submonoid of #{@m2} generated by #{set}" do
|
75
|
-
@m2.get_submonoid(set).should == @m2
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
it "should calculate the generator subset of #{RLSM::Monoid.new('0')}" do
|
81
|
-
RLSM::Monoid.new('0').generating_subset.should == []
|
82
|
-
end
|
83
|
-
|
84
|
-
it "should calculate the generator subset of #{RLSM::Monoid.new('01 11')}" do
|
85
|
-
RLSM::Monoid.new('01 11').generating_subset.should == [1]
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should calculate the generator subset of #{RLSM::Monoid.new('0123 1032 2323 3232')}" do
|
89
|
-
RLSM::Monoid.new('0123 1032 2323 3232').generating_subset.should == [1,2]
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
|
94
|
-
describe RLSM::Monoid do
|
95
|
-
before :each do
|
96
|
-
@m1 = RLSM::Monoid.new '012345 113315 245255 315355 442245 555555'
|
97
|
-
@m2 = RLSM::Monoid.new '012345 103254 235454 324545 455454 544545'
|
98
|
-
end
|
99
|
-
|
100
|
-
it "should calculate left ideals of elements" do
|
101
|
-
@m1.left_ideal_of(0).should == [0,1,2,3,4,5]
|
102
|
-
@m1.left_ideal_of(1).should == [1,4,5]
|
103
|
-
@m1.left_ideal_of(2).should == [2,3,5]
|
104
|
-
@m1.left_ideal_of(3).should == [2,3,5]
|
105
|
-
@m1.left_ideal_of(4).should == [1,4,5]
|
106
|
-
@m1.left_ideal_of(5).should == [5]
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should calculate right ideals of elements" do
|
110
|
-
@m1.right_ideal_of(0).should == [0,1,2,3,4,5]
|
111
|
-
@m1.right_ideal_of(1).should == [1,3,5]
|
112
|
-
@m1.right_ideal_of(2).should == [2,4,5]
|
113
|
-
@m1.right_ideal_of(3).should == [1,3,5]
|
114
|
-
@m1.right_ideal_of(4).should == [2,4,5]
|
115
|
-
@m1.right_ideal_of(5).should == [5]
|
116
|
-
end
|
117
|
-
|
118
|
-
it "should calculate ideals of elements" do
|
119
|
-
@m1.ideal_of(0).should == [0,1,2,3,4,5]
|
120
|
-
@m1.ideal_of(1).should == [1,2,3,4,5]
|
121
|
-
@m1.ideal_of(2).should == [1,2,3,4,5]
|
122
|
-
@m1.ideal_of(3).should == [1,2,3,4,5]
|
123
|
-
@m1.ideal_of(4).should == [1,2,3,4,5]
|
124
|
-
@m1.ideal_of(5).should == [5]
|
125
|
-
end
|
126
|
-
|
127
|
-
it "should calculate L-classes of elements" do
|
128
|
-
@m1.l_class_of(0).should == [0]
|
129
|
-
@m1.l_class_of(1).should == [1,4]
|
130
|
-
@m1.l_class_of(2).should == [2,3]
|
131
|
-
@m1.l_class_of(3).should == [2,3]
|
132
|
-
@m1.l_class_of(4).should == [1,4]
|
133
|
-
@m1.l_class_of(5).should == [5]
|
134
|
-
end
|
135
|
-
|
136
|
-
it "should calculate R-classes of elements" do
|
137
|
-
@m1.r_class_of(0).should == [0]
|
138
|
-
@m1.r_class_of(1).should == [1,3]
|
139
|
-
@m1.r_class_of(2).should == [2,4]
|
140
|
-
@m1.r_class_of(3).should == [1,3]
|
141
|
-
@m1.r_class_of(4).should == [2,4]
|
142
|
-
@m1.r_class_of(5).should == [5]
|
143
|
-
end
|
144
|
-
|
145
|
-
# it "should calculate J-classes of elements" do
|
146
|
-
# @m1.j_class_of(0).should == [0]
|
147
|
-
# @m1.j_class_of(1).should == [1,2,3,4]
|
148
|
-
# @m1.j_class_of(2).should == [1,2,3,4]
|
149
|
-
# @m1.j_class_of(3).should == [1,2,3,4]
|
150
|
-
# @m1.j_class_of(4).should == [1,2,3,4]
|
151
|
-
# @m1.j_class_of(5).should == [5]
|
152
|
-
# end
|
153
|
-
|
154
|
-
it "should calculate H-classes of elements" do
|
155
|
-
@m1.h_class_of(0).should == [0]
|
156
|
-
@m1.h_class_of(1).should == [1]
|
157
|
-
@m1.h_class_of(2).should == [2]
|
158
|
-
@m1.h_class_of(3).should == [3]
|
159
|
-
@m1.h_class_of(4).should == [4]
|
160
|
-
@m1.h_class_of(5).should == [5]
|
161
|
-
end
|
162
|
-
|
163
|
-
it "should calculate D-classes of elements" do
|
164
|
-
@m1.d_class_of(0).should == [0]
|
165
|
-
@m1.d_class_of(1).should == [1,2,3,4]
|
166
|
-
@m1.d_class_of(2).should == [1,2,3,4]
|
167
|
-
@m1.d_class_of(3).should == [1,2,3,4]
|
168
|
-
@m1.d_class_of(4).should == [1,2,3,4]
|
169
|
-
@m1.d_class_of(5).should == [5]
|
170
|
-
end
|
171
|
-
|
172
|
-
it "should detect aperiodicity" do
|
173
|
-
@m1.aperiodic?.should == true
|
174
|
-
@m2.aperiodic?.should == false
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
describe RLSM::Monoid do
|
179
|
-
before :each do
|
180
|
-
@m1 = RLSM::Monoid.new '0'
|
181
|
-
@m2 = RLSM::Monoid.new '01 10'
|
182
|
-
@m3 = RLSM::Monoid.new '01 11'
|
183
|
-
@m4 = RLSM::Monoid.new '012 102 222'
|
184
|
-
end
|
185
|
-
|
186
|
-
it "should detect a null element" do
|
187
|
-
@m1.null_element.should == false
|
188
|
-
@m2.null_element.should == false
|
189
|
-
@m3.null_element.should == 1
|
190
|
-
@m4.null_element.should == 2
|
191
|
-
end
|
192
|
-
|
193
|
-
it "should detect idempotent elements" do
|
194
|
-
[@m1, @m2, @m3].each { |m| m.idempotent?(0).should == true }
|
195
|
-
@m2.idempotent?(1).should == false
|
196
|
-
@m3.idempotent?(1).should == true
|
197
|
-
@m4.idempotent?(2).should == true
|
198
|
-
@m4.idempotent?(1).should == false
|
199
|
-
end
|
200
|
-
|
201
|
-
it "should find all idempotents" do
|
202
|
-
@m1.idempotents.should == [0]
|
203
|
-
@m2.idempotents.should == [0]
|
204
|
-
@m3.idempotents.should == [0,1]
|
205
|
-
@m4.idempotents.should == [0,2]
|
206
|
-
end
|
207
|
-
|
208
|
-
it "should decide if all elements are idempotent" do
|
209
|
-
@m1.idempotent?.should == true
|
210
|
-
@m2.idempotent?.should == false
|
211
|
-
@m3.idempotent?.should == true
|
212
|
-
@m4.idempotent?.should == false
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
describe RLSM::Monoid do
|
217
|
-
before :each do
|
218
|
-
@m1 = RLSM::Monoid.new('0123 1032 2323 3232')
|
219
|
-
end
|
220
|
-
|
221
|
-
it "should calculate all submonoids of a given order upto to isomorphie" do
|
222
|
-
@m1.submonoids_of_order(1).should == [RLSM::Monoid.new('0')]
|
223
|
-
@m1.submonoids_of_order(2).should == [RLSM::Monoid.new('01 10'), RLSM::Monoid.new('01 11')]
|
224
|
-
@m1.submonoids_of_order(3).should == [RLSM::Monoid.new('012 112 221')]
|
225
|
-
@m1.submonoids_of_order(4).should == [@m1]
|
226
|
-
end
|
227
|
-
|
228
|
-
it "should calculate all submonoids upto to isomorphie" do
|
229
|
-
@m1.submonoids.should == [RLSM::Monoid.new('0'), RLSM::Monoid.new('01 10'), RLSM::Monoid.new('01 11'),RLSM::Monoid.new('012 112 221'), @m1]
|
230
|
-
|
231
|
-
RLSM::Monoid.new('0').submonoids.should == [RLSM::Monoid.new('0')]
|
232
|
-
end
|
233
|
-
|
234
|
-
it "should calculate all proper submonoids upto to isomorphie" do
|
235
|
-
@m1.proper_submonoids.should == [RLSM::Monoid.new('01 10'), RLSM::Monoid.new('01 11'),RLSM::Monoid.new('012 112 221')]
|
236
|
-
|
237
|
-
RLSM::Monoid.new('0').proper_submonoids.should == []
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
describe RLSM::Monoid do
|
242
|
-
['0', '01 11', '012 112 212', '01234 11111 21212 31133 41234'].each do |tab|
|
243
|
-
it "should detect syntacticity of #{tab}" do
|
244
|
-
RLSM::Monoid.new(tab).syntactic?.should == true
|
245
|
-
end
|
246
|
-
|
247
|
-
it "should find a disjunctive subset of #{tab}" do
|
248
|
-
case tab
|
249
|
-
when '0'
|
250
|
-
RLSM::Monoid.new(tab).disjunctive_subset.should == []
|
251
|
-
when '01 11'
|
252
|
-
RLSM::Monoid.new(tab).disjunctive_subset.should == [0]
|
253
|
-
when '012 112 212'
|
254
|
-
RLSM::Monoid.new(tab).disjunctive_subset.should == [1]
|
255
|
-
when '01234 11111 21212 31133 41234'
|
256
|
-
RLSM::Monoid.new(tab).disjunctive_subset.should == [0,4]
|
257
|
-
end
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
['0123 1111 2222 3333', '01234 10234 22222 33222 44222'].each do |tab|
|
262
|
-
it "should detect nonsyntacticity of #{tab}" do
|
263
|
-
RLSM::Monoid.new(tab).syntactic?.should == false
|
264
|
-
end
|
265
|
-
|
266
|
-
it "should not find a disjunctive subset of #{tab}" do
|
267
|
-
RLSM::Monoid.new(tab).disjunctive_subset.should be_nil
|
268
|
-
end
|
269
|
-
end
|
270
|
-
end
|