rlsm 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,284 +0,0 @@
1
- module SMONLIBbase
2
- def quit
3
- exit
4
- end
5
-
6
- def monoid(mon, options = {})
7
- @objects << RLSM::Monoid.new(mon, options)
8
- puts "=> #{@objects.last.inspect}" if @interactive
9
- @monoid = @objects.last
10
- end
11
-
12
- def dfa(dfa)
13
- @objects << RLSM::DFA.create(dfa)
14
- puts "=> #{@objects.last.inspect}" if @interactive
15
- @dfa = @objects.last
16
- end
17
-
18
- def regexp(re)
19
- @objects << RLSM::RE.new(re)
20
- puts "=> #{@objects.last.inspect}" if @interactive
21
- @re = @objects.last
22
- end
23
-
24
- def show(obj = nil)
25
- obj ||= @objects.last
26
- if obj
27
- @out.puts obj.to_s
28
- @out.puts
29
- else
30
- STDERR.puts "No object present."
31
- end
32
- end
33
-
34
- def describe(obj = nil)
35
- obj ||= @objects.last
36
-
37
- if obj
38
- monoid, dfa = obj.to_monoid, obj.to_dfa
39
- print_language(monoid, dfa)
40
- print_monoid_properties(monoid)
41
- print_submonoids(monoid)
42
- print_syntactic_properties(monoid)
43
- else
44
- STDERR.puts "No object present."
45
- end
46
- end
47
-
48
-
49
- def self.included(mod)
50
- #Setting up the help system
51
- mod.add_help :type => 'cmd',
52
- :name => 'quit',
53
- :usage => 'quit',
54
- :summary => "Quits the program.",
55
- :description => <<DESC
56
- The 'quit' command is a synonym for the 'exit' command.
57
- Only needed in interactive mode.
58
- DESC
59
-
60
- mod.add_help :type => 'cmd',
61
- :name => 'monoid',
62
- :usage => "monoid '<mon>' [<options>]",
63
- :summary => "Creates a new monoid.",
64
- :description => <<DESC
65
- The <mon> parameter is a description of the binary operation
66
- of the monoid as a table. The <mon> parameter is parsed as follows:
67
- * Rows are seperated by spaces.
68
- * Elements in a row are seperated by commas (',').
69
- Commas are optional if each element consists of a single letter.
70
- * IMPORTANT: The first row and column belongs to the neutral element!
71
- * IMPORTANT: The <mon> parameter must be enclosed
72
- in single or double quotes.
73
-
74
- EXAMPLES:
75
- monoid '1ab aab bbb'
76
- monoid 'e,a1,a2 a1,a2,e a2,e,a1'
77
-
78
- The optional <options> parameter is a Hash and can take the following keys:
79
- :elements -> an array
80
- The value of this key is used to rename
81
- the elements of the monoid.
82
- :normalize -> true|false
83
- If true, the monoid will be normalized, i.e.
84
- the generating elements will be moved to the beginning.
85
- :rename -> true|false
86
- If true, the elements ill be renamed to 1 a b c ...
87
-
88
- Adds the created monoid to the @objects array
89
- and sets the variable @monoid to the created monoid.
90
- DESC
91
-
92
- mod.add_help :type => 'cmd',
93
- :name => 'dfa',
94
- :usage => "dfa <hash>",
95
- :summary => "Creates a new DFA.",
96
- :description => <<DESC
97
- The <hash> parameter must have the following keys:
98
- :initial -> label
99
- The label of the initial state.
100
- :finals -> an Array
101
- The array contains the labels of the final states.
102
- :transitions -> an Array
103
- The array contains the transitions of the monoid.
104
- A transition is an array consisting of
105
- the label of the transition
106
- the starting state of the transition
107
- the destination of the transition
108
-
109
- EXAMPLE:
110
- dfa :initial => '0', :finals => ['1'], :transitions => [['a','0','1']]
111
-
112
- Adds the created DFA to the @objects array
113
- and sets the variable @dfa to the created DFA.
114
- DESC
115
-
116
- mod.add_help :type => 'cmd',
117
- :name => 'regexp',
118
- :usage => "regexp '<re>'",
119
- :summary => "Creates a new Regular Expression.",
120
- :description => <<DESC
121
- The <re> parameter is simply a regular expression. Special Symbols are
122
- #{RLSM::RE::Lambda} -> the empty word
123
- #{RLSM::RE::Star} -> the Kleene star
124
- #{RLSM::RE::Union} -> the union of two regexps
125
- #{RLSM::RE::LeftBracket}, #{RLSM::RE::RightBracket} -> Parenthesis to group a subregexp
126
-
127
- IMPORTANT: The <re> parameter must be enclosed in single or double quotes.
128
- Parentheses must be balanced.
129
-
130
- EXAMPLES:
131
- regexp 'a'
132
- regexp
133
- '#{RLSM::RE::Lambda}#{RLSM::RE::Union}#{RLSM::RE::LeftBracket}a#{RLSM::RE::Union}aab#{RLSM::RE::Star}#{RLSM::RE::RightBracket}'
134
-
135
- Adds the created regular expression to the @objects array
136
- and sets the variable @re to the created regular expression.
137
- DESC
138
-
139
- mod.add_help :type => 'cmd',
140
- :name => 'show',
141
- :usage => "show [<obj>]",
142
- :summary => "Prints a very concise description of <obj>.",
143
- :description => <<DESC
144
- The optional <obj> parameter is either a monoid, a DFA or a RE.
145
- If none is given the last created object will be used.
146
- DESC
147
-
148
- mod.add_help :type => 'cmd',
149
- :name => 'describe',
150
- :usage => "describe [<obj>]",
151
- :summary => "Prints a verbose description of <obj>.",
152
- :description => <<DESC
153
- The optional <obj> parameter is either a monoid, a DFA or a RE.
154
- If none is given the last created object will be used.
155
- DESC
156
- end
157
-
158
- private
159
- def print_syntactic_properties(m)
160
- if m.syntactic?
161
- @out.puts "SYNTACTIC PROPERTIES:"
162
-
163
- m.all_disjunctive_subsets.each do |ds|
164
- @out.puts "{#{ds.join(',')}} => #{m.to_dfa(ds).to_re}"
165
- end
166
- @out.puts
167
- end
168
- end
169
-
170
- def print_submonoids(m)
171
- subs = m.proper_submonoids.map do |sm|
172
- binary_operation(sm)
173
- end
174
-
175
- if subs.empty?
176
- @out.puts "SUBMONOIDS: none"
177
- @out.puts
178
- else
179
- @out.puts "SUBMONOIDS:"
180
- rows = [[]]
181
- width = 0
182
- subs.each do |sm|
183
- spl = sm.split("\n")
184
- if (width + spl[0].length) <= 30
185
- rows.last << spl
186
- width += spl[0].length
187
- else
188
- rows << [spl]
189
- width = spl[0].length
190
- end
191
- end
192
- rows.each do |row|
193
- max_lines = row.map { |sm| sm.size }.max
194
-
195
- row.map! { |sm| sm + [' '*sm[0].length]*(max_lines-sm.size) }
196
- (0...row[0].size).each do |i|
197
- @out.puts row.map { |sm| sm[i] }.join(' ')
198
- end
199
- @out.puts
200
- end
201
- end
202
- end
203
-
204
- def print_monoid_properties(m)
205
- block1 = []
206
- block1 << "PROPERTIES OF THE MONOID:"
207
- block1 << " Generator: {#{m.generating_subset.join(',')}}"
208
- block1 << " Group: #{m.group?}"
209
- block1 << " Commutative: #{m.commutative?}"
210
- block1 << " Idempotent: #{m.idempotent?}"
211
- block1 << " Syntactic: #{m.syntactic?}"
212
- block1 << " Aperiodic: #{m.aperiodic?}"
213
- block1 << " L-trivial: #{m.l_trivial?}"
214
- block1 << " R-trivial: #{m.r_trivial?}"
215
- block1 << " D-trivial: #{m.d_trivial?}"
216
- block1 << "Zero element: #{!m.zero_element.nil?}"
217
-
218
- max_length = block1.map { |row| row.length }.max
219
- block1.map! { |row| row + ' '*(max_length - row.length) }
220
-
221
- block2 = []
222
- block2 << "SPECIAL ELEMENTS:"
223
- block2 << " Idempotents: #{m.idempotents.join(',')}"
224
- if m.zero_element
225
- block2 << "Zero element: #{m.zero_element}"
226
- else
227
- lz = (m.left_zeros.empty? ? ['none'] : m.left_zeros).join(',')
228
- block2 << " Left-Zeros: #{lz}"
229
- rz = (m.right_zeros.empty? ? ['none'] : m.right_zeros).join(',')
230
- block2 << " Right-Zeros: #{rz}"
231
- end
232
- block2 << ''
233
- block2 << ''
234
- block2 << "GREEN RELATIONS:"
235
- lc = m.l_classes.map { |cl| '{' + cl.join(',') + '}' }.join(' ')
236
- rc = m.r_classes.map { |cl| '{' + cl.join(',') + '}' }.join(' ')
237
- hc = m.h_classes.map { |cl| '{' + cl.join(',') + '}' }.join(' ')
238
- dc = m.d_classes.map { |cl| '{' + cl.join(',') + '}' }.join(' ')
239
- block2 << "L-Classes: #{lc}"
240
- block2 << "R-Classes: #{rc}"
241
- block2 << "H-Classes: #{hc}"
242
- block2 << "D-Classes: #{dc}"
243
- block2 << ''
244
-
245
- @out.puts block1.zip(block2).map { |row| row.join(' ') }.join("\n")
246
- @out.puts
247
- end
248
-
249
- def print_language(m,d)
250
- @out.puts "\nDFA:\n#{d.to_s}\n"
251
- @out.puts "\nMONOID:\n"
252
- @out.puts binary_operation(m)
253
- @out.puts
254
- end
255
-
256
- def binary_operation(monoid)
257
- max_length = monoid.elements.map { |e| e.length }.max
258
- rows = monoid.binary_operation.map do |row|
259
- row.map do |e|
260
- space = ' '*((max_length - e.length)/2)
261
- extra_space = ' '*((max_length - e.length)%2)
262
- space + extra_space + e + space
263
- end.join(' | ')
264
- end
265
-
266
- first = ' '*(max_length + 2) + '| ' + rows[0].clone + ' |'
267
- seperator = first.gsub(/[^|]/,'-').gsub('|', '+')
268
-
269
- rows.map! do |row|
270
- ' ' + row[/^[^|]+\|/] + ' ' + row + " |"
271
- end
272
-
273
- result = [first]
274
- result << seperator
275
- result << rows.join("\n" + seperator + "\n")
276
- result << seperator
277
-
278
- result.join("\n")
279
- end
280
-
281
- def get_elements(obj)
282
- [obj.to_monoid, obj.to_dfa, obj.to_re]
283
- end
284
- end
@@ -1,98 +0,0 @@
1
- module SMONLIBdb
2
- def db_stat
3
- stat = RLSM::MonoidDB.statistic
4
- result = stat.shift.join(' | ')
5
-
6
- column_widths = result.scan(/./).inject([0]) do |res,char|
7
- if char == '|'
8
- res << 0
9
- else
10
- res << res.pop + 1
11
- end
12
-
13
- res
14
- end
15
-
16
- result += ("\n" + ' ' + result.gsub(/[^|]/, '-').gsub('|', '+'))
17
-
18
- stat.each do |row|
19
- justified = []
20
- row.each_with_index do |col,i|
21
- col = col.to_s
22
- space = ' '*((column_widths[i] - col.length)/2)
23
- extra_space = ' '*((column_widths[i] - col.length)%2)
24
- justified << space + col + space + extra_space
25
- end
26
-
27
- result += ("\n" + ' ' + justified.join('|'))
28
- end
29
-
30
- @out.puts result
31
- @out.puts
32
- end
33
-
34
- def db_find(args)
35
- count = RLSM::MonoidDB.count(args)
36
- STDOUT.puts "Found: #{count[0]} monoid(s) (#{count[1]} syntactic)"
37
- STDOUT.puts "Saved result in variable '@search_result'"
38
-
39
- @search_result = RLSM::MonoidDB.find(args).flatten
40
- end
41
-
42
- def self.included(mon)
43
- #Check if database is usable
44
- begin
45
- require 'database'
46
-
47
- mon.add_help :type => 'cmd',
48
- :name => 'db_stat',
49
- :summary => "Shows an overview of the database.",
50
- :usage => 'db_stat',
51
- :description => <<DESC
52
- Prints for each order of a monoid the number of monoids in the database
53
- and the number of monoids with certain properties.
54
- DESC
55
-
56
- mon.add_help :type => 'cmd',
57
- :name => 'db_find',
58
- :summary => "Finds monoids in the database.",
59
- :usage => 'db_find [<options>]',
60
- :description => <<DESC
61
- Finds monoids which matches the given options and saves the result
62
- in the variable '@serach_result'.
63
-
64
- The optional <options> parameter is a Hash with the following keys:
65
- :binop -> a String
66
- Searches in the database for a monoid with this binary operation.
67
- The :binop-value must have the same format as for the monoid command
68
- and in the database the element names are 0 1 2 3 4 5 ...
69
- (Not very useful in practice.)
70
-
71
- :m_order -> an Integer
72
- Searches for monoids with the given order.
73
-
74
- :num_generators
75
- :num_idempotents
76
- :num_left_nulls
77
- :num_right_nulls -> an Integer
78
- Seraches for monoids with the given number of special
79
- elements like idempotents or left-zeros.
80
-
81
- :syntactic
82
- :idempotent
83
- :aperiodic
84
- :commutative
85
- :is_group
86
- :has_null
87
- :l_trivial
88
- :r_trivial
89
- :d_trivial -> true|false
90
- Searches for monoids with the given attribute.
91
- DESC
92
- rescue LoadError
93
- STDERR.puts "W: Could not load 'db'."
94
- remove_method :db_find
95
- remove_method :db_stat
96
- end
97
- end
98
- end
@@ -1,65 +0,0 @@
1
- module SMONLIBdot
2
- #Creates a picture of a DFA using dot.
3
- def dfa2pic(dfa, options = {:format => 'png'})
4
- filename = options[:filename] || SMON.tmp_filename
5
- File.open(filename + ".dot", "w") { |f| f.puts dfa2dot(dfa) }
6
- system "dot -T#{options[:format]} -o #{filename}.#{options[:format]} #{filename}.dot"
7
- File.delete(filename + ".dot")
8
- end
9
-
10
- #Creates string which is a dot representation of a DFA.
11
- def dfa2dot(dfa)
12
- str = "digraph {\n"
13
- str += "size=\"2,2\"\nratio=1.0\n"
14
- str += "node [shape=circle]\n"
15
- str += "preinit [shape=plaintext, label=\"\"]\n"
16
- (dfa.states - dfa.finals).each do |state|
17
- str += state + "\n"
18
- end
19
- str += "node [shape=doublecircle]\n"
20
- dfa.finals.each do |state|
21
- str += state + "\n"
22
- end
23
- str += "preinit -> #{dfa.initial_state}\n"
24
- dfa.states.product(dfa.states).each do |s1,s2|
25
- res = dfa.transitions.find_all { |tr| tr[1] == s1 and tr[2] == s2 }
26
- unless res.empty?
27
- label = res.map { |tr| tr[0] }.join(',')
28
- str += s1 + "->" + s2 + "[label=\"#{label}\"]\n"
29
- end
30
- end
31
-
32
- str + "}"
33
- end
34
-
35
- def self.included(mod)
36
- unless system("which dot > /dev/null")
37
- remove_method :dfa2pic
38
- STDERR.puts "W: No 'dot' command found."
39
- else
40
- mod.add_help :type => 'cmd',
41
- :name => 'dfa2pic',
42
- :summary => 'Creates a picture of a DFA using dot.',
43
- :usage => 'dfa2pic <dfa> [<options>]',
44
- :description => <<DESC
45
- The parameter <dfa> is a DFA which will be transformed with the dot program.
46
- Possible optional parameters are
47
- :format -> a String.
48
- The output format. Defaults to 'png'. Could be all what dot
49
- accepts.
50
-
51
- :filename -> a String.
52
- The filename of the output.
53
- DESC
54
- end
55
-
56
- mod.add_help :type => 'cmd',
57
- :name => 'dfa2dot',
58
- :summary => 'Creates a string with dot commands.',
59
- :usage => 'dfa2pic <dfa>',
60
- :description => <<DESC
61
- The parameter <dfa> is a DFA which will be transformed to a string
62
- which is a valid dot description of a digraph.
63
- DESC
64
- end
65
- end
@@ -1,313 +0,0 @@
1
- require 'enumerator'
2
-
3
- module SMONLIBlatex
4
- def m2tex(monoid)
5
- buffer = ['\begin{tabular}{' +
6
- (['c']*(monoid.order+1)).join('|') + '|}']
7
-
8
- buffer << ' & ' + monoid.binary_operation[0].map do |el|
9
- "\\textbf{#{el}}"
10
- end.join(' & ') + "\\\\ \\hline"
11
-
12
- monoid.binary_operation.each do |row|
13
- buffer << "\\textbf{#{row[0]}} & " + row.join(' & ') + "\\\\ \\hline"
14
- end
15
-
16
- buffer << ['\end{tabular}']
17
- buffer.join("\n")
18
- end
19
-
20
- def d2tex(dfa, opts = {:dot => true})
21
- #Have we dot support
22
- if opts[:dot] #and @__cmds.include? "dfa2pic"
23
- filename = SMON.tmp_filename
24
- dfa2pic dfa, :filename => filename, :format => 'plain'
25
- str = "\\begin{xy}\n0;<1.27cm,0cm>:\n"
26
-
27
- edges = []
28
- File.open(filename + ".plain", 'r').each_line do |line|
29
- values = line.split
30
- if ['edge','node'].include? values.first
31
- str += tex_xy_node(values)
32
- end
33
- edges << tex_xy_edge(values) if values.first == 'edge'
34
- end
35
-
36
- str += edges.join("\n")
37
-
38
- File.delete(filename + ".plain")
39
-
40
- return str + "\n\\end{xy}\n"
41
- else
42
- str = "\\begin{tabular}{r|" +
43
- (['c']*dfa.alphabet.size).join('|') + "}\n"
44
- str += " & " + dfa.alphabet.map do |l|
45
- "\\textbf{#{l}}"
46
- end.join(' & ') + " \\\\ \\hline\n"
47
- dfa.states.each do |state|
48
- tmp_str = ''
49
- tmp_str += "\\ensuremath{*}" if dfa.finals.include? state
50
- tmp_str += "\\ensuremath{\\rightarrow}" if dfa.initial_state == state
51
- tmp_str += state + " & "
52
- tmp_str += dfa.alphabet.map do |letter|
53
- tmp = dfa[letter,state]
54
- tmp ? tmp : 'nil'
55
- end.join(' & ')
56
- str+= tmp_str + " \\\\\n"
57
- end
58
-
59
- return str + "\\end{tabular}\n"
60
- end
61
- end
62
-
63
- def r2tex(re)
64
- re_str = re.pattern.
65
- gsub(RLSM::RE::Lambda, "\\lambda ").
66
- gsub(RLSM::RE::Union, "\\mid ").
67
- gsub(RLSM::RE::Star, "^{*}")
68
-
69
- "\\ensuremath{#{re_str}}"
70
- end
71
-
72
- def tex_describe(obj)
73
- monoid = obj.to_monoid
74
- dfa = obj.to_dfa
75
-
76
- str = <<LATEX
77
- \\begin{tabular}[t]{c|c}
78
- \\textbf{Binary Operation} & \\textbf{DFA} \\\\ \\hline
79
- #{m2tex(monoid)} & #{d2tex(dfa)}
80
- \\end{tabular}\\\\[2ex]
81
- #{tex_properties(monoid)}\\\\[2ex]
82
- #{tex_submonoids(monoid)}\\\\[2ex]
83
- #{monoid.syntactic? ? tex_syntactic_properties(monoid) : ''}
84
-
85
- LATEX
86
-
87
- @out.puts str if @interactive
88
-
89
- str
90
- end
91
-
92
- def tex_preamble
93
- <<PREAMBLE
94
- \\documentclass[a4paper,DIV15,halfparskip*]{scrartcl}
95
- \\usepackage[all]{xy}
96
- \\usepackage{amsmath}
97
-
98
- \\begin{document}
99
- PREAMBLE
100
- end
101
-
102
- def compile(opts = {:format => 'dvi'})
103
- str = tex_preamble
104
- if opts[:object]
105
- str += tex_describe(opts[:object])
106
- else
107
- str += opts[:input]
108
- end
109
- str += "\n\\end{document}"
110
-
111
- filename = opts[:filename] || SMON.tmp_filename
112
-
113
- File.open(filename + ".tex", 'w') { |f| f.puts str }
114
-
115
- cmd = "latex -interaction=nonstopmode "
116
- cmd += "-output-format=#{opts[:format]} " + filename + ".tex"
117
-
118
- system cmd
119
-
120
- clean_up filename
121
- end
122
-
123
- def self.included(mod)
124
- unless system("which latex >/dev/null")
125
- remove_method :complile
126
- STDERR.puts "W: compile command disabled."
127
- else
128
- mod.add_help :type => 'cmd',
129
- :name => 'compile',
130
- :summary => 'Creates a dvi or pdf from the given string or object.',
131
- :usage => 'compile <options>',
132
- :description => <<DESC
133
- Possible options are
134
- :input -> a String.
135
- A string which contains a valid latex source file.
136
-
137
- :object -> a DFA or Monoid or Regular Expression.
138
- The object will be transformed using tex_describe
139
- and then typsetted.
140
-
141
- :format -> a String.
142
- Either 'dvi' or 'pdf'. Determines the output format of the
143
- latex command.
144
-
145
- :filename -> a String.
146
- The filename of the output.
147
- DESC
148
- end
149
-
150
- mod.add_help :type => 'cmd',
151
- :name => 'm2tex',
152
- :summary => 'Transforms a monoid to tex code.',
153
- :usage => 'm2tex <monoid>',
154
- :description => <<DESC
155
- Takes a monoid and returns a string containing tex code for
156
- representing the monoid in tex.
157
- DESC
158
-
159
- mod.add_help :type => 'cmd',
160
- :name => 'r2tex',
161
- :summary => 'Transforms a regular expression to tex code.',
162
- :usage => 'r2tex <re>',
163
- :description => <<DESC
164
- Takes a regular expression and returns a string containing tex code for
165
- representing the regular expression in tex.
166
- DESC
167
-
168
- mod.add_help :type => 'cmd',
169
- :name => 'd2tex',
170
- :summary => 'Transforms a DFA to tex code.',
171
- :usage => 'd2tex <dfa> [<options>]',
172
- :description => <<DESC
173
- Takes a DFA and returns a string containing tex code for
174
- representing the DFA in tex.
175
-
176
- Optional a parameter :dot can be given.
177
- :dot -> true|false
178
- If true and the dfa2pic command is found, uses dot and xy-pic
179
- to genearte a graph for the DFA.
180
- If false a simple table is used for representing the DFA.
181
- DESC
182
-
183
- mod.add_help :type => 'cmd',
184
- :name => 'tex_describe',
185
- :summary => 'Returns tex code equivalent to the describe command.',
186
- :usage => 'tex_describe <object>',
187
- :description => <<DESC
188
- Takes an object and returns a string containing tex code for
189
- representing this object in tex. Focuses on the monoid properties.
190
- DESC
191
-
192
- mod.add_help :type => 'cmd',
193
- :name => 'tex_preamble',
194
- :summary => 'Returns the tex preamble used by the compile command.',
195
- :usage => 'tex_preamble',
196
- :description => <<DESC
197
- Not very useful in interactive mode.
198
- DESC
199
- end
200
-
201
- private
202
- def clean_up(file)
203
- files = Dir.glob(file + ".*").reject { |f| f =~ /(dvi|pdf)$/ }
204
- files.each { |f| system("rm " + f) }
205
- end
206
-
207
- def set(s)
208
- "\\ensuremath{\\lbrace \\mbox{#{s.join(', ')}}\\rbrace}"
209
- end
210
-
211
- def list(s)
212
- str = s.join(', ')
213
- str.empty? ? 'none' : str
214
- end
215
-
216
- def tex_submonoids(m)
217
- sm = m.proper_submonoids.map { |s| m2tex(s) }
218
- buffer = nil
219
- if sm.empty?
220
- buffer = ["\\textbf{Submonoids:} none"]
221
- else
222
- buffer = ["\\textbf{Submonoids:}\\\\[.5\\baselineskip]"]
223
- buffer << sm.join("\\quad\n")
224
- end
225
-
226
- buffer.join("\n")
227
- end
228
-
229
- def tex_syntactic_properties(m)
230
- buffer = ["\\textbf{Syntactic Properties:}\\\\"]
231
- buffer << "\\begin{tabular}{ll}"
232
- buffer << "Disjunctive Subset & Possible Regular Expression \\\\"
233
- m.all_disjunctive_subsets.each do |ds|
234
- re = m.to_dfa(ds).to_re
235
- buffer << set(ds) + " & " + r2tex(re) + "\\\\"
236
- end
237
- buffer << "\\end{tabular}"
238
-
239
- buffer.join("\n")
240
- end
241
-
242
-
243
- def tex_properties(m)
244
- buffer = ['\begin{tabular}{llcll}']
245
- buffer << '\multicolumn{2}{l}{\textbf{Properties of the Monoid:}} &'
246
- buffer << ' & \multicolumn{2}{l}{\textbf{Special Elements:}} \\\\'
247
- buffer << "Generator: & #{set(m.generating_subset)} & \\quad &" +
248
- "Idempotents: & #{list(m.idempotents)} \\\\"
249
-
250
- buffer << "Group: & #{m.group?} & \\quad &"
251
- if m.zero_element
252
- buffer[-1] += " Zero Element: & #{m.zero_element} \\\\"
253
- else
254
- buffer[-1] += " Left-Zeros: & #{list(m.left_zeros)} \\\\"
255
- end
256
-
257
- buffer << "Commutative: & #{m.commutative?} & \\quad &"
258
- if m.zero_element
259
- buffer[-1] += " & \\\\"
260
- else
261
- buffer[-1] += " Rigth-Zeros: & #{list(m.right_zeros)} \\\\"
262
- end
263
-
264
- buffer << "Idempotent: & #{m.idempotent?} & \\quad & & \\\\"
265
- buffer << "Syntactic: & #{m.syntactic?} & \\quad &" +
266
- "\\multicolumn{2}{l}{\\textbf{Green Relations:}} \\\\"
267
- buffer << "Aperiodic: & #{m.aperiodic?} & \\quad &" +
268
- " L-Classes: & #{list(m.l_classes.map { |x| set(x) })} \\\\"
269
- buffer << "L-trivial: & #{m.l_trivial?} & \\quad &" +
270
- " R-Classes: & #{list(m.r_classes.map { |x| set(x) })} \\\\"
271
- buffer << "R-trivial: & #{m.r_trivial?} & \\quad &" +
272
- " H-Classes: & #{list(m.h_classes.map { |x| set(x) })} \\\\"
273
- buffer << "D-trivial: & #{m.d_trivial?} & \\quad &" +
274
- " D-Classes: & #{list(m.d_classes.map { |x| set(x) })} \\\\"
275
- buffer << "Zero Element: & #{!m.zero_element.nil?} & \\quad & & \\\\"
276
- buffer << '\end{tabular}'
277
-
278
- buffer.join("\n")
279
- end
280
-
281
- def tex_xy_node(n)
282
- if n.first == 'edge'
283
- return "" if n[1] == 'preinit'
284
-
285
- num_points = n[3].to_i
286
- lable_pos = n[2*num_points + 5,2].join(',')
287
- label = n[2*num_points + 4].gsub("\"",'')
288
-
289
- return ";(#{lable_pos})*[r]\\txt{#{label}}\n"
290
- else
291
- id = n[1]
292
- xypos = n[2,2].join(',')
293
- return "(#{xypos})*{}=\"#{id}\"\n" if n[1] == 'preinit'
294
-
295
- label = n[6]
296
- type = n[8] == 'circle' ? '' : '='
297
-
298
- return ";(#{xypos})*+=[o]++[F#{type}]{#{label}}=\"#{id}\"\n"
299
- end
300
- end
301
-
302
- def tex_xy_edge(e)
303
- from, to = e[1,2]
304
- num_points = e[3].to_i
305
- points = points_to_str(e[4,2*num_points])
306
-
307
- "\\ar @`{#{points}} \"#{from}\";\"#{to}\""
308
- end
309
-
310
- def points_to_str(a)
311
- "(" + a.enum_slice(2).to_a.map { |x| x.join(',') }.join('),(') + ")"
312
- end
313
- end