Class: LogicTools::NodeNary
- Extended by:
- Forwardable
- Includes:
- Enumerable
- Defined in:
- lib/logic_tools/logictree.rb
Overview
Represents an operator node with multiple children.
Instance Attribute Summary collapse
-
#op ⇒ Object
readonly
Returns the value of attribute op.
Class Method Summary collapse
-
.make(op, *children) ⇒ Object
Creates a node with operator
opandchildren(factory method).
Instance Method Summary collapse
-
#==(node) ⇒ Object
Compares with
node. -
#distribute(dop, node) ⇒ Object
Creates a new tree where the current node is distributed over
nodeaccording to thedopoperator. -
#each(&blk) ⇒ Object
Iterates over the children.
-
#flatten ⇒ Object
Flatten ands, ors and nots.
-
#flatten_deep ⇒ Object
Creates a new tree where all the and, or and not operators from the current node are flattened.
-
#getVariablesRecurse ⇒ Object
Gets the variables, recursively, without postprocessing.
-
#reduce ⇒ Object
Reduces a node: remove its redundancies using the absbortion rules.
-
#sort ⇒ Object
Creates a new node whose childrens are sorted.
-
#to_sym ⇒ Object
Converts to a symbol.
-
#uniq(&blk) ⇒ Object
Creates a new node without duplicate in the children.
Methods inherited from Node
#each_line, #each_maxterm, #each_minterm, #eql?, #getVariables, #hash, #inspect, #simplify, #size, #to_std_conjunctive, #to_std_disjunctive, #to_sum_product
Instance Attribute Details
#op ⇒ Object (readonly)
Returns the value of attribute op.
365 366 367 |
# File 'lib/logic_tools/logictree.rb', line 365 def op @op end |
Class Method Details
.make(op, *children) ⇒ Object
Creates a node with operator op and children (factory method).
385 386 387 388 389 390 391 392 393 394 |
# File 'lib/logic_tools/logictree.rb', line 385 def NodeNary.make(op,*children) case op when :or return NodeOr.new(*children) when :and return NodeAnd.new(*children) else raise ArgumentError.new("Not a valid operator: #{op}") end end |
Instance Method Details
#==(node) ⇒ Object
Compares with node.
440 441 442 443 444 445 446 447 448 449 |
# File 'lib/logic_tools/logictree.rb', line 440 def ==(node) # :nodoc: return false unless node.is_a?(Node) return false unless self.op == node.op # There is no find_with_index! # return ! @children.find_with_index {|child,i| child != node[i] } @children.each_with_index do |child,i| return false if child != node[i] end return true end |
#distribute(dop, node) ⇒ Object
Creates a new tree where the current node is distributed over node
according to the +dop+ operator.
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 |
# File 'lib/logic_tools/logictree.rb', line 549 def distribute(dop,node) # :nodoc: fop = dop == :and ? :or : :and # print "dop=#{dop} fop=#{fop} self.op=#{@op}\n" if (@op == dop) then # Self operator is dop: merge node in self return NodeNary.make(dop,*self,node).flatten else # self operator if fop if (node.op == fop) then # node operator is also fop: (a+b)(c+d) or ab+cd case nchildren = [] self.each do |child0| node.each do |child1| # print "child0=#{child0}, child1=#{child1}\n" nchildren << NodeNary.make(dop, child0, child1).flatten # print "nchildren=#{nchildren}\n" end end return NodeNary.make(fop,*nchildren).flatten else # node operator is not fop: (a+b)c or ab+c case nchildren = self.map do |child| NodeNary.make(dop,child,node).flatten end return NodeNary.make(fop,*nchildren).flatten end end end |
#each(&blk) ⇒ Object
Iterates over the children.
401 402 403 404 |
# File 'lib/logic_tools/logictree.rb', line 401 def each(&blk) # :nodoc: @children.each(&blk) return self end |
#flatten ⇒ Object
Flatten ands, ors and nots.
522 523 524 525 526 527 528 529 530 |
# File 'lib/logic_tools/logictree.rb', line 522 def flatten # :nodoc: return NodeNary.make(@op,*(@children.reduce([]) do |nchildren,child| if (child.op == self.op) then nchildren.push(*child) else nchildren << child end end)).reduce end |
#flatten_deep ⇒ Object
Creates a new tree where all the and, or and not operators
from the current node are flattened.
Default: simply duplicate.
536 537 538 539 540 541 542 543 544 545 |
# File 'lib/logic_tools/logictree.rb', line 536 def flatten_deep # :nodoc: return NodeNary.make(@op,*(@children.reduce([]) do |nchildren,child| child = child.flatten_deep if (child.op == self.op) then nchildren.push(*child) else nchildren << child end end)).reduce end |
#getVariablesRecurse ⇒ Object
Gets the variables, recursively, without postprocessing.
Returns the variables into sets of arrays with possible doublon
433 434 435 436 437 |
# File 'lib/logic_tools/logictree.rb', line 433 def getVariablesRecurse() # :nodoc: return @children.reduce([]) do |res,child| res.concat(child.getVariablesRecurse) end end |
#reduce ⇒ Object
Reduces a node: remove its redundancies using the absbortion rules.
--
TODO consider the X~X and X+~X cases.
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 |
# File 'lib/logic_tools/logictree.rb', line 485 def reduce # The operator used for the factors fop = @op == :and ? :or : :and # Gather the terms converted to a sorted string for fast # comparison terms = @children.map do |child| if (child.op == fop) then [ child, child.sort.to_s ] else [ child, child.to_s ] end end nchildren = [] # Keep only the terms that do not contain another one terms.each_with_index do |term0,i| skipped = false terms.each_with_index do |term1,j| next if (i==j) # Same term if (term0[1].include?(term1[1])) and term0[1]!=term1[1] then # term0 contains term1 but is different, skip it skipped = true break end end nchildren << term0[0] unless skipped # Term has not been skipped end # Avoid duplicates nchildren.uniq! # Generate the result if (nchildren.size == 1) return nchildren[0] else return NodeNary.make(@op,*nchildren) end end |
#sort ⇒ Object
Creates a new node whose childrens are sorted.
407 408 409 |
# File 'lib/logic_tools/logictree.rb', line 407 def sort return NodeNary.make(@op,*@children.sort_by {|child| child.to_sym }) end |
#to_sym ⇒ Object
Converts to a symbol.
426 427 428 |
# File 'lib/logic_tools/logictree.rb', line 426 def to_sym # :nodoc: return @sym end |
#uniq(&blk) ⇒ Object
Creates a new node without duplicate in the children.
412 413 414 415 416 417 418 419 420 421 422 423 |
# File 'lib/logic_tools/logictree.rb', line 412 def uniq(&blk) if blk then nchildren = @children.uniq(&blk) else nchildren = @children.uniq { |child| child.to_sym } end if nchildren.size == 1 then return nchildren[0] else return NodeNary.make(@op,*nchildren) end end |