lib/magic_logic.rb in magic_logic-0.0.2 vs lib/magic_logic.rb in magic_logic-0.0.3
- old
+ new
@@ -1,159 +1,67 @@
-require "magic_logic/version"
+require "magic_logic/utils"
+require "magic_logic/operator"
module MagicLogic
- module Operator
- def _ ope, l, r
- ope == :+ ? l : r
- end
-
- [:+, :*].each do |ope|
- define_method(ope) do |q|
- case q
- when Taut then _ ope, $tout, self
- when UTaut then _ ope, self, $utout
- when self then self
- else
- if neg?(q)
- (_ ope, $tout, $utout)
- elsif is_form?(ope.to_sym) && include?(q)
- self
- elsif q.is_form?(ope) && q.include?(self)
- q
- else
- FORM.new([self, q], ope)
- end
- end
- end
- end
-
- def ~@
- if is_neg? then p
- elsif is_form? then vars.map(&:~).inject(_ ope, :*, :+)
- else NEG.new(self)
- end
- end
-
- def >=(q)
- (~self + q)
- end
-
- def <=>(q)
- (self >= q) * (q >= self)
- end
- end
-
- module Utils
- def neg?(p)
- (is_neg? && self.p == p) || (p.is_neg? && p.p == self)
- end
-
- def is_neg?
- is_a?(NEG)
- end
-
- def is_form?(ope=nil)
- return is_a?(FORM) && self.ope == ope if ope
- is_a?(FORM)
- end
-
- def is_or?
- is_form?(:+)
- end
-
- def is_and?
- is_form?(:*)
- end
-
- def include?(p)
- false
- end
-
- def dpll
- !!!!!!!!!!!!!!!!!!self
- end
- end
-
module Base; include Operator; include Utils end
# Tautology
class Taut
include Base
def ~@; $utout end
def +(q); $tout end
def *(q); q end
- def !@; $tout end
def to_s; 'TRUE' end
end
$tout = Taut.new
# Non Tautology
class UTaut
include Base
def ~@; $tout end
def +(q); q end
def *(q); $utout end
- def !@; $utout end
def to_s; 'FALSE' end
end
$utout = UTaut.new
class Atom < Struct.new(:p)
include Base
def to_s; p.to_s end
- def !@; self end
- def depth; 1 end
class << self
- alias [] new
+ def [](x)
+ new(x).tap { |p| $atoms << p; $atoms.uniq! }
+ end
end
end
P = Atom
+ $atoms = []
class NEG < Struct.new(:p)
include Base
def to_s; "~#{p}" end
- def !@; ~(!p) end
- def depth; p.depth+1 end
end
class FORM < Struct.new(:vars, :ope)
include Base
def initialize(vars, ope)
self.vars = vars.map { |var| var.is_form?(ope) ? var.vars : var }.flatten
self.ope = ope
end
- def to_s; "(#{vars.map(&:to_s).join(_ ope, '|', '&')})" end
-
- def !@
- if is_or? && (and_form = vars.find { |var| var.is_and? })
- and_form.vars.map { |a| a + FORM.new((vars - [and_form]), :+) }.inject(:*)
- elsif are_there_neg?
- is_or? ? $tout : $utout
- else
- vars.map(&:!).inject(ope)
- end
- end
-
- def depth; [p.depth, q.depth].max+1; end
-
- def include?(p)
- vars.include?(p)
- end
-
- private
- def are_there_neg?
- pvars = vars.reject { |var| var.is_neg? }
- nvars = vars.select { |var| var.is_neg? }
- pvars.any? { |pvar|
- nvars.any? { |nvar| nvar.neg?(pvar) }
- }
- end
+ def to_s; "(#{vars.map(&:to_s).join(_ ope, '|', '&')})" end
+ def include?(p); vars.include?(p) end
end
class ::Array
def >>(con)
- inject($tout) { |s, p| s * p } >= con
+ l = inject($tout) { |s, p| s * p } >= con
+ case l.dpll
+ when Taut then 'TRUE'
+ when UTaut then 'FALSE'
+ else 'UNDECIDABLE'
+ end
end
end
end
+include MagicLogic