logic_tools 0.3.7 → 0.3.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8ac5ee19f5e2583fb76459f21c1081a79251d190
4
- data.tar.gz: 4d5ca6164a8a43d70b3cb3eaf2e2bdf476047b5d
3
+ metadata.gz: 37ffa5f837816fb1f10f87e520b5a1936bac7b66
4
+ data.tar.gz: 8035e691cd6d385d396a6e3d66395eae6ded6725
5
5
  SHA512:
6
- metadata.gz: a814d9ef74ffd4e25cc667af4afa2debac676a4f35d32b50338e574cd7fe1d8de863281ad0cfad7a03ec33e56a7c4e035ac36a15d8067267ac2b11cb34f708b0
7
- data.tar.gz: 6017ef5ac0677d76574861ecfc32ec5727f553f5f47c0b7459f18410dd4e66319ac931b21e734f6703697d9cdc62798cbbbc7bc1a006abae6ab21c57fa84937b
6
+ metadata.gz: 23eeb7a4e711ff0a72c11c68a58e183cd7718882e91e56e1189b2c5436c554f1b031ea6dcee13433505e618aa1b824a7ec878f2b4485a067d90a354376948a1c
7
+ data.tar.gz: 5202cd8cd9fac2dfea65f6d36c120f9e12bd64d1cb9ff22adaacb3502c15955d3b6498928c4c7ca1dfe8ef070331652c6bcf94edd816e24014172bb54bc54c35
@@ -36,7 +36,7 @@ module LogicTools
36
36
  # print "vars=#{vars}\n"
37
37
  # Converts the tree rooted by self to a sum of products
38
38
  # (reduced to limit the number of cubes and their sizes).
39
- tree = self.to_sum_product.flatten.reduce
39
+ tree = self.to_sum_product.reduce
40
40
  # print "tree=#{tree}\n"
41
41
 
42
42
  # Create an empty cover.
@@ -60,7 +60,7 @@ module LogicTools
60
60
  #
61
61
  # +input+ is assumed to be an integer.
62
62
  # Returns the evaluation result as a boolean.
63
- def eval(input)
63
+ def eval_input(input)
64
64
  result = true
65
65
  @bits.each_byte.with_index do |bit,i|
66
66
  if bit == 49 then
@@ -446,9 +446,9 @@ module LogicTools
446
446
  #
447
447
  # +input+ is assumed to be an integer.
448
448
  # Returns the evaluation result as a boolean.
449
- def eval(input)
449
+ def eval_input(input)
450
450
  # Evaluates each cube, if one results in true the result is true.
451
- return !!@cubes.each.find {|cube| cube.eval(input) }
451
+ return !!@cubes.each.find {|cube| cube.eval_input(input) }
452
452
  end
453
453
 
454
454
  ## Converts to a string.
@@ -760,7 +760,7 @@ module LogicTools
760
760
  # return false if num_minterms < 2**self.width
761
761
  # # Last check: the truth table.
762
762
  # (2**self.width).times do |input|
763
- # return false if self.eval(input) == 0
763
+ # return false if self.eval_input(input) == 0
764
764
  # end
765
765
  else
766
766
  # Compute the cofactors over the binate variables.
@@ -49,7 +49,7 @@ module LogicTools
49
49
  @rate = rate
50
50
  end
51
51
 
52
- ## Iterates over the variables of the cube
52
+ ## Iterates over the variables of the generator.
53
53
  #
54
54
  # Returns an enumberator if no block is given
55
55
  def each_variable(&blk)
@@ -60,6 +60,60 @@ module LogicTools
60
60
  end
61
61
 
62
62
 
63
+ ## Creates a random logic expression.
64
+ def random_expression
65
+ expression = ""
66
+ pre = :"(" # The previous element type: start of expression
67
+ # is equivalent to a opened parenthesis.
68
+ par = 0 # The number of opened parenthesis
69
+ @random.rand(0..(@max-1)).times do
70
+ choice = @random.rand(@variables.size+4)
71
+ # print "par=#{par} pre=#{pre}\n"
72
+ case choice
73
+ when 0 then
74
+ expression << "("
75
+ par += 1
76
+ pre = :"("
77
+ when 1 then
78
+ if ( par > 0 and ( pre==:v or pre==:")") )
79
+ expression << ")"
80
+ par -= 1
81
+ pre = :")"
82
+ end
83
+ when 3 then
84
+ if ( pre != :"(" and pre != :+ and pre != :~ )
85
+ expression << "+"
86
+ pre = :+
87
+ end
88
+ when 4 then
89
+ expression << "~"
90
+ pre = :~
91
+ else
92
+ var = @variables[choice-4]
93
+ if var.size > 1
94
+ expression << "{" + var + "}"
95
+ else
96
+ expression << var
97
+ end
98
+ pre = :v
99
+ end
100
+ # print "expression = #{expression}\n"
101
+ end
102
+ # Remove the last invalid character.
103
+ while ["~","(","+"].include?(expression[-1]) do
104
+ par -= 1 if expression[-1] == "("
105
+ expression.chop!
106
+ end
107
+ # Close the remaining opened parenthesis.
108
+ while par > 0 do
109
+ par -=1
110
+ expression << ")"
111
+ end
112
+ # Return the resulting expression.
113
+ return expression
114
+ end
115
+
116
+
63
117
  ## Creates a random truth table column value.
64
118
  def random_column
65
119
  return @random.rand(0..(2**(2**(@variables.size))-1))
@@ -105,6 +105,15 @@ module LogicTools
105
105
  0
106
106
  end
107
107
 
108
+ ## Evalutes the tree on a binary +input+.
109
+ def eval_input(input)
110
+ self.get_variables.each_with_index do |var,i|
111
+ val = input[vars.size-i-1]
112
+ var.value = val
113
+ end
114
+ return self.eval
115
+ end
116
+
108
117
  ## Iterates on each line of the truth table obtained from the tree
109
118
  # rooted by current node.
110
119
  #
@@ -259,6 +268,7 @@ module LogicTools
259
268
  #
260
269
  # Argument +flattened+ tells if the tree is already flattend
261
270
  def to_sum_product(flattened = false)
271
+ # print "NODE to_sum_product with tree=#{self}\n"
262
272
  return self.dup
263
273
  end
264
274
 
@@ -671,13 +681,17 @@ module LogicTools
671
681
 
672
682
  ## Flatten ands, ors and nots.
673
683
  def flatten # :nodoc:
674
- return NodeNary.make(@op,*(@children.reduce([]) do |nchildren,child|
684
+ # print "flatten with #{self}\n"
685
+ res = NodeNary.make(@op,*(@children.reduce([]) do |nchildren,child|
675
686
  if (child.op == self.op) then
676
- nchildren.push(*child)
687
+ # nchildren.push(*child)
688
+ nchildren.push(*child.each)
677
689
  else
678
690
  nchildren << child
679
691
  end
680
692
  end)).reduce
693
+ # print "result #{res}\n"
694
+ return res
681
695
  end
682
696
 
683
697
  ## Creates a new tree where all the *and*, *or* and *not* operators
@@ -688,7 +702,8 @@ module LogicTools
688
702
  return NodeNary.make(@op,*(@children.reduce([]) do |nchildren,child|
689
703
  child = child.flatten_deep
690
704
  if (child.op == self.op) then
691
- nchildren.push(*child)
705
+ # nchildren.push(*child)
706
+ nchildren.push(*child.each)
692
707
  else
693
708
  nchildren << child
694
709
  end
@@ -698,7 +713,7 @@ module LogicTools
698
713
  ## Creates a new tree where the current node is distributed over +node+
699
714
  # according to the +dop+ operator.
700
715
  def distribute(dop,node) # :nodoc:
701
- # print "distrubte with self=#{self} and node=#{node}\n"
716
+ # print "distribute with self=#{self} and node=#{node}\n"
702
717
  fop = dop == :and ? :or : :and
703
718
  # print "dop=#{dop} fop=#{fop} self.op=#{@op}\n"
704
719
  if (@op == dop) then
@@ -756,11 +771,18 @@ module LogicTools
756
771
  #
757
772
  # Argument +flattened+ tells if the tree is already flattend
758
773
  def to_sum_product(flattened = false) # :nodoc:
774
+ # print "AND to_sum_product with tree=#{self}\n"
759
775
  # Flatten if required
760
776
  node = flattened ? self : self.flatten_deep
761
777
  return node unless node.is_parent?
762
778
  # Convert each child to sum of product
763
- nchildren = node.map {|child| child.to_sum_product(true) }
779
+ nchildren = node.map do |child|
780
+ # print "recurse to_sum_product for child=#{child}\n"
781
+ # res = child.to_sum_product(true)
782
+ # print "child=#{child} -> res=#{res}\n"
783
+ # res
784
+ child.to_sum_product(true)
785
+ end
764
786
  # Distribute
765
787
  while(nchildren.size>1)
766
788
  # print "nchildren=#{nchildren}\n"
@@ -773,14 +795,17 @@ module LogicTools
773
795
  dist << left
774
796
  end
775
797
  end
798
+ # print "dist=#{dist}\n"
776
799
  nchildren = dist
777
800
  end
778
- # Generate the or
779
- if (nchildren.size > 1)
780
- return NodeOr.new(*nchildren)
781
- else
782
- return nchildren[0]
783
- end
801
+ # print "result=#{nchildren}\n"
802
+ # # Generate the or
803
+ # if (nchildren.size > 1)
804
+ # return NodeOr.new(*nchildren)
805
+ # else
806
+ # return nchildren[0]
807
+ # end
808
+ return nchildren[0].flatten
784
809
  end
785
810
 
786
811
  ## Converts to a string.
@@ -824,8 +849,9 @@ module LogicTools
824
849
  #
825
850
  # Argument +flattened+ tells if the tree is already flattend
826
851
  def to_sum_product(flattened = false) # :nodoc:
852
+ # print "OR to_sum_product with tree=#{self}\n"
827
853
  return NodeOr.new(
828
- *@children.map {|child| child.to_sum_product(flatten) } )
854
+ *@children.map {|child| child.to_sum_product(flattened) } ).flatten
829
855
  end
830
856
 
831
857
  ## Converts to a string.
@@ -963,6 +989,7 @@ module LogicTools
963
989
  #
964
990
  # Argument +flattened+ tells if the tree is already flattend
965
991
  def to_sum_product(flattened = false) # :nodoc:
992
+ # print "NOT to_sum_product with tree=#{self}\n"
966
993
  # return NodeNot.new(@child.to_sum_product(flatten))
967
994
  # Flatten deeply if required.
968
995
  nnode = flattened ? self : self.flatten_deep
@@ -15,3 +15,11 @@
15
15
  -> Crashes
16
16
 
17
17
  *FIXED*
18
+
19
+ ---
20
+ === Bug 3
21
+ # simpligy_es "a(b+c(d+e(f+g)))"
22
+
23
+ -> Crashes
24
+
25
+ *FIXED*
@@ -7,6 +7,7 @@
7
7
  # require 'minitest/autorun'
8
8
  require "logic_tools/logicgenerator.rb"
9
9
  require "logic_tools/logicconvert.rb"
10
+ require "logic_tools/logicparse.rb"
10
11
 
11
12
  include LogicTools
12
13
 
@@ -30,7 +31,7 @@ class TestEspresso # < MiniTest::Unit::TestCase
30
31
  def truth_tautology(cover)
31
32
  ## Generate each possible input and test it on the cover.
32
33
  (2**(cover.width)).times do |i|
33
- return false unless cover.eval(i)
34
+ return false unless cover.eval_input(i)
34
35
  end
35
36
  return true
36
37
  end
@@ -76,13 +77,36 @@ class TestEspresso # < MiniTest::Unit::TestCase
76
77
  return true
77
78
  end
78
79
 
80
+ # ## Tests the conversion to sum of product of an expression.
81
+ # def test_to_sum_product_random(dimensions = 4)
82
+ # # Create the variables.
83
+ # base = "`"
84
+ # variables = dimensions.times.map { |i| base.next!.clone }
85
+ # # Create the generator.
86
+ # generator = Generator.new(*variables)
87
+ # generator.seed = @seed
88
+ # # Creates the expression.
89
+ # expression = generator.random_expression
90
+ # # Convert it to a tree.
91
+ # tree = string2logic(expression)
92
+ # # Convert it.
93
+ # sumprod = tree.to_sum_product
94
+ # # Compare the truth tables.
95
+ # # check = same_truth_table?(tree,sumprod)
96
+ # # HOW TO CHECK? SOME VARIABLES MAY HAVE DISAPEARED...
97
+ # # assert_equal(true,check)
98
+ # print "check = #{check}\n"
99
+ # raise "Test failure" unless check
100
+ # return true
101
+ # end
102
+
79
103
 
80
104
  ## Checks if covers have the same truth table.
81
105
  def same_truth_table?(cover0,cover1)
82
106
  return false unless cover0.width == cover1.width
83
107
  # Check for each entry.
84
108
  (2**cover0.width).times do |i|
85
- return false unless cover0.eval(i) == cover1.eval(i)
109
+ return false unless cover0.eval_input(i) == cover1.eval_input(i)
86
110
  end
87
111
  return true
88
112
  end
@@ -134,8 +158,8 @@ class TestEspresso # < MiniTest::Unit::TestCase
134
158
  print "ESPRESSO on cover=[#{cover.to_s}]...\n"
135
159
  simple = cover.simplify(@deadline,@volume)
136
160
  print "result: [#{simple}]\n"
137
- check0 = (cover + simple.complement).is_tautology?
138
- # check0 = same_truth_table?(cover,simple)
161
+ # check0 = (cover + simple.complement).is_tautology?
162
+ check0 = same_truth_table?(cover,simple)
139
163
  # assert_equal(true,check0)
140
164
  print "check 0 = #{check0}\n"
141
165
  raise "Test failure" unless check0
@@ -1,3 +1,3 @@
1
1
  module LogicTools
2
- VERSION = "0.3.7"
2
+ VERSION = "0.3.8"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logic_tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.3.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lovic Gauthier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-26 00:00:00.000000000 Z
11
+ date: 2017-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler