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.
@@ -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,2 +0,0 @@
1
- require 'mkmf'
2
- create_makefile('binop_cext')
@@ -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