Class: LogicTools::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/logic_tools/logicgenerator.rb

Overview

Class used for genrating logic expression.

Instance Method Summary collapse

Constructor Details

#initialize(*variables) ⇒ Generator

Creates a new generator for logic expressions on the

boolean space based on a +variables+ set.


15
16
17
18
19
20
# File 'lib/logic_tools/logicgenerator.rb', line 15

def initialize(*variables)
    @variables = variables.map {|var| var.to_s }
    @random = Random.new(0)   # The default seed is fixed to 0.
    @max = 2**@variables.size # The max number of cube per random cover.
    @rate= Rational(1,3)      # The rate of "-" in a cube.
end

Instance Method Details

#each_1coverObject

Iterates over all the possible cover made of 1-cubes.

NOTE: this iteration can be huge!


233
234
235
236
237
238
239
240
241
242
243
# File 'lib/logic_tools/logicgenerator.rb', line 233

def each_1cover
    # No block given? Return an enumerator.
    return to_enum(:each_1cover) unless block_given?
    
    # Block given? Apply it on each bit.
    # Iterate on each possible truth table.
    ( 2 ** (2 ** @variables.size) ).times do |table|
        # Create the expression and apply the block on it.
        yield(make_1cover(table))
    end
end

#each_std_conjObject

Iterates over all the possible standard conjunctive forms.

NOTE: this iteration can be huge!


179
180
181
182
183
184
185
186
187
188
189
# File 'lib/logic_tools/logicgenerator.rb', line 179

def each_std_conj
    # No block given? Return an enumerator.
    return to_enum(:each_std_conj) unless block_given?
    
    # Block given? Apply it on each bit.
    # Iterate on each possible truth table.
    ( 2 ** (2 ** @variables.size) ).times do |table|
        # Create the expression and apply the block on it.
        yield(make_std_conj(table))
    end
end

#each_variable(&blk) ⇒ Object

Iterates over the variables of the generator.

Returns an enumberator if no block is given


55
56
57
58
59
60
# File 'lib/logic_tools/logicgenerator.rb', line 55

def each_variable(&blk)
    # No block given? Return an enumerator
    return to_enum(:each_variable) unless block_given?
    # Block given? Apply it.
    @variables.each(&blk)
end

#make_1cover(table) ⇒ Object

Create a 1-cube cover from its values in a truth table.



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/logic_tools/logicgenerator.rb', line 213

def make_1cover(table)
    # Convert the +table+ to a bit string if necessary.
    unless table.is_a?(String) then
        table = table.to_s(2).rjust(2 ** @variables.size,"0")
    end
    # Generate the cover.
    cover = Cover.new(*@variables)
    # Fill it with the required 1-cubes.
    table.each_char.with_index do |val,i|
        if (val == "1") then
            cover << make_cube(i)
        end
    end
    # Returns the cover.
    return cover
end

#make_cube(row) ⇒ Object

Creates a cube from binary row.



204
205
206
207
208
209
210
# File 'lib/logic_tools/logicgenerator.rb', line 204

def make_cube(row)
    # Convert the +row+ to a bit string if necessary.
    unless (row.is_a?(String))
        row = row.to_s(2).rjust(@variables.size,"0")
    end
    return Cube.new(row)
end

#make_minterm(row) ⇒ Object

Creates a minterm from the binary value of a truth table’s row.



142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/logic_tools/logicgenerator.rb', line 142

def make_minterm(row)
    # Convert the +row+ to a bit string if necessary.
    unless (row.is_a?(String))
        row = row.to_s(2).rjust(@variables.size,"0")
    end
    # Create the minterm from the bit string: an AND where
    # each term is variable if the corresponding bit is "1"
    # and the opposite if the corresponding bit is "0".
    return NodeAnd.new(*row.each_char.with_index.map do |bit,j|
        var = NodeVar.new(Variable.get(@variables[j]))
        bit == "1" ? var : NodeNot.new(var)
    end )
end

#make_std_conj(table) ⇒ Object

Create a standard conjunctive form from its values in a

truth +table+.


158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/logic_tools/logicgenerator.rb', line 158

def make_std_conj(table)
    # Convert the +table+ to a bit string if necessary.
    unless table.is_a?(String) then
        table = table.to_s(2).rjust(2 ** @variables.size,"0")
    end
    # Generate the terms from it.
    terms = []
    table.each_char.with_index do |val,i|
        if (val == "1") then
            terms << make_minterm(i)
        end
    end
    # If no term, return a NodeFalse
    return NodeFalse.new if terms.empty?
    # Generate and return the resulting sum.
    return NodeOr.new(*terms)
end

#maxObject

Gets the maximum number of cubes for a cover.



33
34
35
# File 'lib/logic_tools/logicgenerator.rb', line 33

def max
    return @max
end

#max=(max) ⇒ Object

Sets the maximum number of cubes for a cover.



38
39
40
# File 'lib/logic_tools/logicgenerator.rb', line 38

def max=(max)
    @max = max.to_i
end

#random_1coverObject

Creates a random cover made of 1-cubes.



251
252
253
# File 'lib/logic_tools/logicgenerator.rb', line 251

def random_1cover
    return make_1cover(random_column)
end

#random_1cubeObject

Creates a random 1-cube.



246
247
248
# File 'lib/logic_tools/logicgenerator.rb', line 246

def random_1cube
    return make_cube(random_2row)
end

#random_3rowObject

Creates a random 3-states row.



129
130
131
132
133
134
135
136
137
138
# File 'lib/logic_tools/logicgenerator.rb', line 129

def random_3row
    result = "-" * @variables.size
    @variables.size.times do |i| 
        value = @random.rand
        if value > @rate then
            result[i] = value <= @rate + (1-@rate)/2 ? "0" : "1"
        end
    end
    return result
end

#random_columnObject

Creates a random truth table column value.



118
119
120
# File 'lib/logic_tools/logicgenerator.rb', line 118

def random_column
    return @random.rand(0..(2**(2**(@variables.size))-1))
end

#random_coverObject

Creates a random cover.



261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/logic_tools/logicgenerator.rb', line 261

def random_cover
    # Create the new cover.
    cover = Cover.new(*@variables)
    # Fill it with a random number of random cubes.
    volume = 0
    @random.rand(0..(@max-1)).times do
        cube = make_cube(random_3row)
        # volume += 2 ** cube.each_bit.count { |b| b == "-" }
        # break if volume >= 2 ** @variables.size
        cover << cube
    end
    # Return it.
    return cover
end

#random_cubeObject

Creates a random cube.



256
257
258
# File 'lib/logic_tools/logicgenerator.rb', line 256

def random_cube
    return make_cube(random_3row)
end

#random_expressionObject

Creates a random logic expression.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/logic_tools/logicgenerator.rb', line 64

def random_expression
    expression = ""
    pre = :"(" # The previous element type: start of expression
               #    is equivalent to a opened parenthesis.
    par = 0    # The number of opened parenthesis
    @random.rand(0..(@max-1)).times do
        choice = @random.rand(@variables.size+4)
        # print "par=#{par} pre=#{pre}\n"
        case choice
        when 0 then
            expression << "("
            par += 1
            pre = :"("
        when 1 then
            if ( par > 0 and ( pre==:v or pre==:")") )
                expression << ")" 
                par -= 1
                pre = :")"
            end
        when 3 then
            if ( pre != :"(" and pre != :+ and pre != :~ )
                expression << "+" 
                pre = :+
            end
        when 4 then
            expression << "~"
            pre = :~
        else
            var = @variables[choice-4]
            if var.size > 1
                expression << "{" + var + "}"
            else
                expression << var
            end
            pre = :v
        end
        # print "expression = #{expression}\n"
    end
    # Remove the last invalid character.
    while ["~","(","+"].include?(expression[-1]) do
        par -= 1 if expression[-1] == "("
        expression.chop!
    end
    # Close the remaining opened parenthesis.
    while par > 0 do
        par -=1
        expression << ")"
    end
    # Return the resulting expression.
    return expression
end

#random_mintermObject

Creates a random minterm.



192
193
194
# File 'lib/logic_tools/logicgenerator.rb', line 192

def random_minterm
    return make_minterm(random_row)
end

#random_rowObject Also known as: random_2row

Creates a random truth table row value.



123
124
125
# File 'lib/logic_tools/logicgenerator.rb', line 123

def random_row
    return @random.rand(0..(2**(@variables.size)-1))
end

#random_std_conjObject

Creates a random standard conjunctive from.



197
198
199
# File 'lib/logic_tools/logicgenerator.rb', line 197

def random_std_conj
    return make_std_conj(random_column)
end

#rateObject

Gets the rate of “-” in a cube.



43
44
45
# File 'lib/logic_tools/logicgenerator.rb', line 43

def rate
    return @rate
end

#rate=(rate) ⇒ Object

Sets the rate of “-” in a cube.



48
49
50
# File 'lib/logic_tools/logicgenerator.rb', line 48

def rate=(rate)
    @rate = rate
end

#seedObject

Gets the seed.



23
24
25
# File 'lib/logic_tools/logicgenerator.rb', line 23

def seed
    @random.seed
end

#seed=(value) ⇒ Object

Sets the seed to value.



28
29
30
# File 'lib/logic_tools/logicgenerator.rb', line 28

def seed=(value)
    @random = Random.new(value)
end