rlsm 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,39 @@
1
+ #
2
+ # This file is part of the RLSM gem.
3
+ #
4
+ #(The MIT License)
5
+ #
6
+ #Copyright (c) 2008 Gunther Diemant <g.diemant@gmx.net>
7
+ #
8
+ #Permission is hereby granted, free of charge, to any person obtaining
9
+ #a copy of this software and associated documentation files (the
10
+ #'Software'), to deal in the Software without restriction, including
11
+ #without limitation the rights to use, copy, modify, merge, publish,
12
+ #distribute, sublicense, and/or sell copies of the Software, and to
13
+ #permit persons to whom the Software is furnished to do so, subject to
14
+ #the following conditions:
15
+ #
16
+ #The above copyright notice and this permission notice shall be
17
+ #included in all copies or substantial portions of the Software.
18
+ #
19
+ #THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
20
+ #EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ #MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22
+ #IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23
+ #CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24
+ #TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
+ #SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ #
27
+
28
+
29
+ class RLSMException < Exception
30
+ end
31
+
32
+ class MonoidException < RLSMException
33
+ end
34
+
35
+ class DFAException < RLSMException
36
+ end
37
+
38
+ class RegExpException < RLSMException
39
+ end
data/lib/rlsm/mgen.rb ADDED
@@ -0,0 +1,138 @@
1
+ #
2
+ # This file is part of the RLSM gem.
3
+ #
4
+ #(The MIT License)
5
+ #
6
+ #Copyright (c) 2008 Gunther Diemant <g.diemant@gmx.net>
7
+ #
8
+ #Permission is hereby granted, free of charge, to any person obtaining
9
+ #a copy of this software and associated documentation files (the
10
+ #'Software'), to deal in the Software without restriction, including
11
+ #without limitation the rights to use, copy, modify, merge, publish,
12
+ #distribute, sublicense, and/or sell copies of the Software, and to
13
+ #permit persons to whom the Software is furnished to do so, subject to
14
+ #the following conditions:
15
+ #
16
+ #The above copyright notice and this permission notice shall be
17
+ #included in all copies or substantial portions of the Software.
18
+ #
19
+ #THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
20
+ #EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ #MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22
+ #IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23
+ #CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24
+ #TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
+ #SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ #
27
+
28
+ require File.join(File.dirname(__FILE__), 'monoid')
29
+
30
+ #Generates all monoids of a given order. May take some time if order is greater than 5.
31
+ module RLSM
32
+ class MonoidGenerator
33
+
34
+ #Iterates over all monoids of order n.
35
+ def self.each(n=2)
36
+ #The pathological cases...
37
+ if n == 1
38
+ yield Monoid.new('0')
39
+ return
40
+ elsif n == 2
41
+ yield Monoid.new('01 10')
42
+ yield Monoid.new('01 11')
43
+ return
44
+ end
45
+
46
+ @@n = n-1
47
+ @@t = ([0]*((n-1)*(n-1)))/(n-1)
48
+ @@t = table_adjoin_one
49
+ @@i, @@j = n-1, n-1
50
+
51
+ @@end_reached = false
52
+ yield Monoid.new(tab_to_str, :normalize => false) if restrictions_satisfied?
53
+ succ
54
+
55
+ while not @@end_reached
56
+ yield Monoid.new(tab_to_str, :normalize => false)
57
+ succ
58
+ end
59
+ end
60
+
61
+ private
62
+ def self.succ
63
+ loop do
64
+ @@t[@@i][@@j] += 1
65
+ if @@t[@@i][@@j] > @@n
66
+ @@t[@@i][@@j] = -1
67
+ if @@i == 1 and @@j == 1
68
+ @@end_reached = true
69
+ break
70
+ elsif @@j == 1
71
+ @@j = @@n; @@i -= 1
72
+ else
73
+ @@j -= 1
74
+ end
75
+ else
76
+ if restrictions_satisfied? and first?
77
+ if @@i == @@n and @@j == @@n
78
+ break
79
+ elsif @@j == @@n
80
+ @@j = 1; @@i += 1
81
+ else
82
+ @@j += 1
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ def self.first?
90
+ (1..@@n).to_a.permutations.collect{|p| p.unshift 0}.all? do |p|
91
+ #if a permutation changes some elements before the given position
92
+ #and the replacement is undefined no answer can be given
93
+ last = (@@i-1)*(@@n) + @@j -1
94
+
95
+ index = (0..last).find do |ind|
96
+ i,j = (ind / (@@n))+1, (ind % (@@n))+1
97
+ bij = @@t[p.index(i)][p.index(j)]
98
+
99
+ (bij == -1) or @@t[i][j] != p[bij]
100
+ end
101
+
102
+ if index
103
+ i,j = (index / (@@n))+1, (index % (@@n))+1
104
+ bij = @@t[p.index(i)][p.index(j)]
105
+
106
+ (bij == -1) or (@@t[i][j] < p[@@t[p.index(i)][p.index(j)]])
107
+ else
108
+ true
109
+ end
110
+ end
111
+ end
112
+
113
+ def self.restrictions_satisfied?
114
+ #Associativity
115
+ return false unless (0..@@n).to_a.triples.all? do |a,b,c|
116
+ if [@@t[a][b],
117
+ @@t[b][c],
118
+ @@t[a][@@t[b][c]],
119
+ @@t[@@t[a][b]][c]].include? -1
120
+ true
121
+ else
122
+ @@t[a][@@t[b][c]] == @@t[@@t[a][b]][c]
123
+ end
124
+ end
125
+
126
+ true
127
+ end
128
+
129
+ def self.table_adjoin_one
130
+ res = [(1..@@n).to_a] + @@t
131
+ (0..@@n).to_a.zip(res).collect { |i,x| [i]+x }
132
+ end
133
+
134
+ def self.tab_to_str
135
+ @@t.collect { |r| r.join(@@n >= 10 ? ',' : '') }.join(' ')
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,126 @@
1
+ #
2
+ # This file is part of the RLSM gem.
3
+ #
4
+ #(The MIT License)
5
+ #
6
+ #Copyright (c) 2008 Gunther Diemant <g.diemant@gmx.net>
7
+ #
8
+ #Permission is hereby granted, free of charge, to any person obtaining
9
+ #a copy of this software and associated documentation files (the
10
+ #'Software'), to deal in the Software without restriction, including
11
+ #without limitation the rights to use, copy, modify, merge, publish,
12
+ #distribute, sublicense, and/or sell copies of the Software, and to
13
+ #permit persons to whom the Software is furnished to do so, subject to
14
+ #the following conditions:
15
+ #
16
+ #The above copyright notice and this permission notice shall be
17
+ #included in all copies or substantial portions of the Software.
18
+ #
19
+ #THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
20
+ #EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ #MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22
+ #IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23
+ #CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24
+ #TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
+ #SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ #
27
+
28
+
29
+ class Object
30
+ #Makes a deep copy. Usful for cloning complexer classes.
31
+ def deep_copy
32
+ Marshal.load(Marshal.dump(self))
33
+ end
34
+ end
35
+
36
+
37
+ class Array
38
+ def tuples
39
+ res = []
40
+ self.each { |a| self.each { |b| res << [a,b] } }
41
+
42
+ res
43
+ end
44
+
45
+ def triples
46
+ res = []
47
+ tuples.each { |a,b| self.each { |c| res << [a,b,c] } }
48
+
49
+ res
50
+ end
51
+
52
+ #Only syntactic sugar. Adds an element unless the element is already in the array.
53
+ def add?(x)
54
+ if x
55
+ unless include? x
56
+ push(x).sort
57
+ end
58
+ end
59
+
60
+ self
61
+ end
62
+
63
+ #Returns the powerset of the array (interpreted as set).
64
+ def powerset
65
+ ret = self.inject([[]]) do |acc, x|
66
+ res = []
67
+ acc.each { |s| res << s; res << ([x]+s).sort }
68
+ res
69
+ end
70
+
71
+ ret.sort do |s1,s2|
72
+ if s1.size == s2.size
73
+ s1 <=> s2
74
+ else
75
+ s1.size <=> s2.size
76
+ end
77
+ end
78
+ end
79
+
80
+ #Returns all proper subsets of the array (the array interpreted as a set).
81
+ def proper_subsets
82
+ powerset.select { |s| s.size > 0 and s.size < size }
83
+ end
84
+
85
+ #Returns all permutations of the array.
86
+ def permutations
87
+ return [self] if size < 2
88
+ perm = []
89
+ each { |e| (self - [e]).permutations.each { |p| perm << ([e] + p) } }
90
+ perm
91
+ end
92
+
93
+ #Returns the Array divided into subarrays each of length +l+. If The size of the array isn't even divisible by +l+, then the last subarray isn't of size +l+.
94
+ def /(l)
95
+ res = []
96
+
97
+ each_with_index do |x,i|
98
+ res << [] if i % l == 0
99
+ res.last << x
100
+ end
101
+
102
+ res
103
+ end
104
+
105
+ #This is some hack, that in my regexp code, it works for both Strings and Arrays...
106
+ def each_char(&block)
107
+ each &block
108
+ end
109
+ end
110
+
111
+ class String
112
+ #Iterates over every character in a string. (Compatibility with 1.9 and convinience)
113
+ def each_char
114
+ if block_given?
115
+ scan(/./m) { |c| yield c }
116
+ else
117
+ scan(/./m)
118
+ end
119
+ end
120
+
121
+ #This is some hack, that in my regexp code, it works for both Strings and Arrays...
122
+ def reject(&block)
123
+ tmp = scan(/./m).reject &block
124
+ tmp.join
125
+ end
126
+ end