OrTerm   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 57
Duplicated Lines 0 %
Metric Value
dl 0
loc 57
rs 10
wmc 17

8 Methods

Rating   Name   Duplication   Size   Complexity  
A nnf? 0 3 1
A to_cnf() 0 7 3
A to_s() 0 4 2
B reduce() 0 16 6
A initialize() 0 4 1
A cnf? 0 4 2
A reduced? 0 3 1
A tseitin() 0 6 1
1
module PropLogic
2
  class OrTerm < Term
3
    def initialize(*terms)
4
      @terms = terms.map{|t| t.is_a?(OrTerm) ? t.terms : t}.flatten.freeze
5
      check_nnf_reduced
6
    end
7
8
    def to_s(in_term = false)
9
      str = @terms.map(&:to_s_in_term).join(' | ')
10
      in_term ? "( #{str} )" : str
11
    end
12
13
    def nnf?
14
      @is_nnf
15
    end
16
17
    def reduced?
18
      @is_reduced
19
    end
20
21
    def reduce
22
      return self if reduced?
23
      reduced_terms = @terms.map(&:reduce).uniq
24
      reduced_terms.reject!{|term| term.equal?(False)}
25
      return False if reduced_terms.empty?
26
      if reduced_terms.any?{|term| term.equal?(True)}
27
        True
28
      elsif reduced_terms.length == 1
29
        reduced_terms[0]
30
      else
31
        not_terms = reduced_terms.select{|term| term.is_a?(NotTerm)}
32
        negated_terms = not_terms.map{|term| term.terms[0]}
33
        return True unless (negated_terms & reduced_terms).empty?
34
        Term.get self.class, *reduced_terms
35
      end
36
    end
37
38
    def cnf?
39
      return false unless reduced?
40
      ! @terms.any?{ |term| term.is_a?(AndTerm) }
41
    end
42
43
    def to_cnf
44
      return super unless reduced?
45
      return self if cnf?
46
      pool = []
47
      without_pools = tseitin(pool)
48
      all_and(without_pools, *pool)
49
    end
50
51
    def tseitin(pool)
52
      val = Variable.new
53
      terms = @terms.map{|t| t.tseitin(pool)}
54
      pool << (~val | all_or(*terms))
55
      val
56
    end
57
58
  end
59
end
60