rlsm 1.1.0 → 1.8.1
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/Manifest +26 -0
- data/README +10 -10
- data/Rakefile +9 -55
- data/data/monoids.db +0 -0
- data/examples/benchmark.rb +14 -0
- data/examples/creating_db.rb +52 -0
- data/examples/creating_lists.rb +185 -0
- data/examples/numbers.rb +41 -0
- data/examples/order8.rb +13 -0
- data/examples/presenting_monoids_in_tex.rb +373 -0
- data/examples/regular_monoids.rb +144 -0
- data/ext/array/array_c_ext.c +21 -12
- data/ext/monoid/monoid_c_ext.c +76 -85
- data/lib/rlsm.rb +1 -1
- data/lib/rlsm/dfa.rb +9 -8
- data/lib/rlsm/helper.rb +12 -6
- data/lib/rlsm/monoid.rb +627 -217
- data/lib/rlsm/regexp.rb +2 -1
- data/lib/rlsm/regexp_parser.rb +2 -1
- data/rlsm.gemspec +26 -0
- data/test/test_dfa.rb +16 -14
- data/test/test_monoid.rb +43 -43
- data/test/test_regexp.rb +2 -2
- metadata +51 -83
- data/ext/binop/binop_c_ext.c +0 -57
- data/ext/binop/extconf.rb +0 -2
- data/lib/rlsm/binary_operation.rb +0 -151
- data/test/test_binop.rb +0 -119
data/ext/binop/binop_c_ext.c
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
#include <ruby.h>
|
2
|
-
|
3
|
-
|
4
|
-
static VALUE
|
5
|
-
non_associative_triple(VALUE self) {
|
6
|
-
VALUE table = rb_iv_get(self, "@table");
|
7
|
-
VALUE max = NUM2INT(rb_iv_get(self, "@order"));
|
8
|
-
VALUE base = rb_iv_get(self, "@elements");
|
9
|
-
|
10
|
-
int i,j,k;
|
11
|
-
for (i=0; i < max; ++i) {
|
12
|
-
for (j=0; j < max; ++j) {
|
13
|
-
for (k=0; k < max; ++k) {
|
14
|
-
int ij,jk, i_jk, ij_k;
|
15
|
-
ij = NUM2INT(RARRAY(table)->ptr[max*i + j]);
|
16
|
-
jk = NUM2INT(RARRAY(table)->ptr[max*j + k]);
|
17
|
-
i_jk = NUM2INT(RARRAY(table)->ptr[max*i + jk]);
|
18
|
-
ij_k = NUM2INT(RARRAY(table)->ptr[max*ij + k]);
|
19
|
-
if (ij_k != i_jk) {
|
20
|
-
return (rb_ary_new3(3,RARRAY(base)->ptr[i],RARRAY(base)->ptr[j],RARRAY(base)->ptr[k]));
|
21
|
-
}
|
22
|
-
}
|
23
|
-
}
|
24
|
-
}
|
25
|
-
|
26
|
-
return (Qnil);
|
27
|
-
}
|
28
|
-
|
29
|
-
static VALUE
|
30
|
-
is_commutative(VALUE self) {
|
31
|
-
VALUE table = rb_iv_get(self, "@table");
|
32
|
-
VALUE max = NUM2INT(rb_iv_get(self, "@order"));
|
33
|
-
|
34
|
-
int i,j;
|
35
|
-
for (i=0; i < max; ++i) {
|
36
|
-
for (j=0; j < max; ++j) {
|
37
|
-
if (NUM2INT(RARRAY(table)->ptr[max*i + j]) != NUM2INT(RARRAY(table)->ptr[max*j + i]))
|
38
|
-
return (Qfalse);
|
39
|
-
}
|
40
|
-
}
|
41
|
-
|
42
|
-
return (Qtrue);
|
43
|
-
}
|
44
|
-
|
45
|
-
#ifdef __cplusplus
|
46
|
-
extern "C" {
|
47
|
-
#endif
|
48
|
-
void Init_binop_cext() {
|
49
|
-
VALUE rlsm = rb_define_module("RLSM");
|
50
|
-
VALUE binop = rb_define_class_under(rlsm, "BinaryOperation", rb_cObject);
|
51
|
-
|
52
|
-
rb_define_private_method(binop, "is_commutative", (VALUE(*)(ANYARGS))is_commutative, 0);
|
53
|
-
rb_define_private_method(binop, "non_associative_triple", (VALUE(*)(ANYARGS))non_associative_triple, 0);
|
54
|
-
}
|
55
|
-
#ifdef __cplusplus
|
56
|
-
}
|
57
|
-
#endif
|
data/ext/binop/extconf.rb
DELETED
@@ -1,151 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
-
RLSM.require_extension 'binop'
|
3
|
-
|
4
|
-
module RLSM
|
5
|
-
class BinaryOperation
|
6
|
-
class << self; alias original_new new; end
|
7
|
-
=begin rdoc
|
8
|
-
Creates a BinaryOperation from given description and validates the result.
|
9
|
-
Raises a ParseError if validation fails.
|
10
|
-
|
11
|
-
The description is of the form
|
12
|
-
[<elements>:]<table>
|
13
|
-
where the optional <elements> part lists the elements on which the binary
|
14
|
-
operation acts in the order in which they appear in the table part.
|
15
|
-
The elements are seperated by commas. The commas are optional if each
|
16
|
-
element is identified by a single letter. no withespaces are allowed in
|
17
|
-
an element identifier.
|
18
|
-
|
19
|
-
The table part describes the transition table of the binary operation.
|
20
|
-
Rows are seperated by at least one whitespace character and elements in
|
21
|
-
a row are seperated by commas. The commas are optional if each element
|
22
|
-
is identified by a single letter.
|
23
|
-
If commas are used in one row to seperate the elements, one must use
|
24
|
-
commas in each row.
|
25
|
-
|
26
|
-
*Remark*: If the elements part is omitted it is assumed that
|
27
|
-
the elements are appearing in the right order and all elements
|
28
|
-
are appearing. This is the case for a monoid with neutral element
|
29
|
-
in the first row.
|
30
|
-
|
31
|
-
*Examples*
|
32
|
-
012 120 201
|
33
|
-
012:000 000 000
|
34
|
-
x1,x2,x3: x1,x2,x2 x2,x2,x1 x3,x2,x1
|
35
|
-
000 000 000 -> error
|
36
|
-
0,1,2 120 2,1,0 -> error
|
37
|
-
=end
|
38
|
-
def self.new(description)
|
39
|
-
binop = new!(description)
|
40
|
-
validate(binop)
|
41
|
-
|
42
|
-
binop
|
43
|
-
end
|
44
|
-
|
45
|
-
#Like new, but without validation of the input.
|
46
|
-
def self.new!(description)
|
47
|
-
original_new *parse(description)
|
48
|
-
end
|
49
|
-
|
50
|
-
#:call-seq:
|
51
|
-
# original_new(table,elements,mapping) -> BinaryOperation
|
52
|
-
#
|
53
|
-
#Creates a BinaryOperation. The arguments are a table an array with elements
|
54
|
-
#and a mapping.
|
55
|
-
#*Remark*: Use this method only if you know what you're doing. No
|
56
|
-
#validation or argument checking is made. Its primary porpose is to speed up
|
57
|
-
#monoid generation in the RLSM::Monoid.each method.
|
58
|
-
def initialize(table, elements, mapping)
|
59
|
-
@table, @elements, @mapping = table, elements, mapping
|
60
|
-
@order = @mapping.size
|
61
|
-
end
|
62
|
-
|
63
|
-
#Internal representation of the table.
|
64
|
-
attr_reader :table
|
65
|
-
|
66
|
-
#Array with all different elements
|
67
|
-
attr_reader :elements
|
68
|
-
|
69
|
-
#The number of elements.
|
70
|
-
attr_reader :order
|
71
|
-
|
72
|
-
#Maps element names to numbers.
|
73
|
-
attr_reader :mapping
|
74
|
-
|
75
|
-
#Calculate the product of +x+ and +y+.
|
76
|
-
#
|
77
|
-
#If at least one of the given elements is unknown raises an ArgumentError.
|
78
|
-
def [](x, y)
|
79
|
-
if @mapping[x].nil?
|
80
|
-
raise ArgumentError, "Unknown element #{x}"
|
81
|
-
elsif @mapping[y].nil?
|
82
|
-
raise ArgumentError, "Unknown element #{y}"
|
83
|
-
else
|
84
|
-
@elements[@table[@mapping[x]*@order + @mapping[y]]]
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
#Checks if binary operation is associative.
|
89
|
-
def associative?
|
90
|
-
!non_associative_triple
|
91
|
-
end
|
92
|
-
|
93
|
-
#Checks if binary operation is commutative.
|
94
|
-
def commutative?
|
95
|
-
is_commutative
|
96
|
-
end
|
97
|
-
|
98
|
-
#Checks if the binary operation is associative. If not raises an BinOpError.
|
99
|
-
def enforce_associativity
|
100
|
-
nat = non_associative_triple
|
101
|
-
|
102
|
-
unless nat.nil?
|
103
|
-
err_str = "(#{nat[0]}#{nat[0]})#{nat[0]} != #{nat[0]}(#{nat[1]}#{nat[2]})"
|
104
|
-
raise BinOpError, "Associativity required, but #{err_str}."
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
private
|
109
|
-
def self.validate(binop)
|
110
|
-
if binop.table.size == 0
|
111
|
-
raise ArgumentError, "No elements given."
|
112
|
-
end
|
113
|
-
|
114
|
-
if binop.table.size != binop.mapping.size**2
|
115
|
-
raise ParseError, "Either to many elements or wrong table format."
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def self.parse(description)
|
120
|
-
mapping = {}
|
121
|
-
elements = []
|
122
|
-
table = []
|
123
|
-
if description =~ /\s*:\s*/
|
124
|
-
elements = desc2ary(Regexp.last_match.pre_match)
|
125
|
-
elements.each_with_index { |el,i| mapping[el] = i }
|
126
|
-
|
127
|
-
desc2ary(Regexp.last_match.post_match).
|
128
|
-
each { |el| table << mapping[el] }
|
129
|
-
else
|
130
|
-
desc2ary(description).each do |element|
|
131
|
-
if mapping[element].nil?
|
132
|
-
mapping[element] = elements.size
|
133
|
-
elements << element
|
134
|
-
end
|
135
|
-
|
136
|
-
table << mapping[element]
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
[table, elements, mapping]
|
141
|
-
end
|
142
|
-
|
143
|
-
def self.desc2ary(str)
|
144
|
-
if str.include?(',')
|
145
|
-
str.gsub(/^\s+/,'').gsub(/,*\s+,*/,',').split(',')
|
146
|
-
else
|
147
|
-
str.gsub(/\s+/,'').scan(/./)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
data/test/test_binop.rb
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'shoulda'
|
3
|
-
|
4
|
-
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
5
|
-
|
6
|
-
require 'rlsm/binary_operation'
|
7
|
-
|
8
|
-
class BinaryOperationTest < Test::Unit::TestCase
|
9
|
-
context "BinaryOperation::new" do
|
10
|
-
should "Require argument" do
|
11
|
-
assert_raises ArgumentError do
|
12
|
-
RLSM::BinaryOperation.new
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
should "Parse a valid description with elements" do
|
17
|
-
binop = RLSM::BinaryOperation.new "012:000 000 000"
|
18
|
-
|
19
|
-
assert_equal Hash['0', 0, '1', 1, '2', 2], binop.mapping
|
20
|
-
assert_equal %w(0 1 2), binop.elements
|
21
|
-
assert_equal 3, binop.order
|
22
|
-
assert_equal [0]*9, binop.table
|
23
|
-
end
|
24
|
-
|
25
|
-
should "Ignore whitspaces between element seperators" do
|
26
|
-
binop = RLSM::BinaryOperation.new "0, 1,2:0,0,0 0,0, 0 0, 0,0"
|
27
|
-
|
28
|
-
assert_equal Hash['0', 0, '1', 1, '2', 2], binop.mapping
|
29
|
-
assert_equal %w(0 1 2), binop.elements
|
30
|
-
assert_equal 3, binop.order
|
31
|
-
assert_equal [0]*9, binop.table
|
32
|
-
end
|
33
|
-
|
34
|
-
should "Raise ParseError if some commas are missing" do
|
35
|
-
assert_raises ParseError do
|
36
|
-
RLSM::BinaryOperation.new "012:0,1,2 210 2,2,2"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
should "Parse commas in the elements part, no commas in table part" do
|
41
|
-
binop = RLSM::BinaryOperation.new "0,1,2:000 000 000"
|
42
|
-
|
43
|
-
assert_equal Hash['0', 0, '1', 1, '2', 2], binop.mapping
|
44
|
-
assert_equal %w(0 1 2), binop.elements
|
45
|
-
assert_equal 3, binop.order
|
46
|
-
assert_equal [0]*9, binop.table
|
47
|
-
end
|
48
|
-
|
49
|
-
should "Parse commas in the table part, no commas in elements part" do
|
50
|
-
binop = RLSM::BinaryOperation.new "012:0,0,0 0,0,0 0,0,0"
|
51
|
-
|
52
|
-
assert_equal Hash['0', 0, '1', 1, '2', 2], binop.mapping
|
53
|
-
assert_equal %w(0 1 2), binop.elements
|
54
|
-
assert_equal 3, binop.order
|
55
|
-
assert_equal [0]*9, binop.table
|
56
|
-
end
|
57
|
-
|
58
|
-
should "Raise ParseError if too many elements are given." do
|
59
|
-
assert_raises ParseError do
|
60
|
-
RLSM::BinaryOperation.new "012:0,1,3 210 2,2,2"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
should "Raise ParseError if too few elements are given." do
|
65
|
-
assert_raises ParseError do
|
66
|
-
RLSM::BinaryOperation.new "000 000 000"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
should "Raise ParseError if table format is wrong." do
|
71
|
-
assert_raises ParseError do
|
72
|
-
RLSM::BinaryOperation.new "012:0,1,2 2,1 2,2,2"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
should "Parse a monoid with neutral element in first row." do
|
77
|
-
binop = RLSM::BinaryOperation.new "0123 1230 2301 3012"
|
78
|
-
|
79
|
-
assert_equal Hash['0', 0, '1', 1, '2', 2, '3', 3], binop.mapping
|
80
|
-
assert_equal %w(0 1 2 3), binop.elements
|
81
|
-
assert_equal 4, binop.order
|
82
|
-
assert_equal [0,1,2,3,1,2,3,0,2,3,0,1,3,0,1,2], binop.table
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
context "BinaryOperation#associative?" do
|
87
|
-
should "Return true if binary operation is associative." do
|
88
|
-
assert_equal true, RLSM::BinaryOperation.new("01:00 00").associative?
|
89
|
-
end
|
90
|
-
|
91
|
-
should "Return false if binary operation is not associative." do
|
92
|
-
assert_equal false, RLSM::BinaryOperation.new("01 00").associative?
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
context "BinaryOperation#commutative?" do
|
97
|
-
should "Return true if binary operation is commutative." do
|
98
|
-
assert_equal true, RLSM::BinaryOperation.new("012 111 211").commutative?
|
99
|
-
end
|
100
|
-
|
101
|
-
should "Return false if binary operation is not commutative." do
|
102
|
-
assert_equal false, RLSM::BinaryOperation.new("012 111 222").commutative?
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
context "BinaryOperation#enforce_associativity" do
|
107
|
-
should "Raise BinOpError for nonassociative binary operation." do
|
108
|
-
assert_raises BinOpError do
|
109
|
-
RLSM::BinaryOperation.new("01 00").enforce_associativity
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
should "Do nothing for assovityive binary operation." do
|
114
|
-
assert_nothing_raised do
|
115
|
-
RLSM::BinaryOperation.new("01 10").enforce_associativity
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|