rover_prover 0.1.0
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 +7 -0
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +32 -0
- data/LICENSE.txt +31 -0
- data/README.md +98 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/rover_prover +5 -0
- data/lib/rover_prover/language/expression.rb +33 -0
- data/lib/rover_prover/language/formula/and.rb +41 -0
- data/lib/rover_prover/language/formula/for_all.rb +44 -0
- data/lib/rover_prover/language/formula/formulae.rb +7 -0
- data/lib/rover_prover/language/formula/implies.rb +41 -0
- data/lib/rover_prover/language/formula/not.rb +39 -0
- data/lib/rover_prover/language/formula/or.rb +41 -0
- data/lib/rover_prover/language/formula/predicate.rb +64 -0
- data/lib/rover_prover/language/formula/there_exists.rb +42 -0
- data/lib/rover_prover/language/formula.rb +5 -0
- data/lib/rover_prover/language/sequent.rb +126 -0
- data/lib/rover_prover/language/term/function.rb +63 -0
- data/lib/rover_prover/language/term/terms.rb +3 -0
- data/lib/rover_prover/language/term/unification_term.rb +38 -0
- data/lib/rover_prover/language/term/variable.rb +40 -0
- data/lib/rover_prover/language/term.rb +10 -0
- data/lib/rover_prover/language.rb +3 -0
- data/lib/rover_prover/processor/commands.rb +32 -0
- data/lib/rover_prover/processor/processor.rb +2 -0
- data/lib/rover_prover/processor/rover_lexer.rb +23 -0
- data/lib/rover_prover/processor/rover_parser.rb +64 -0
- data/lib/rover_prover/prover/prover.rb +277 -0
- data/lib/rover_prover/prover/unifier.rb +29 -0
- data/lib/rover_prover/version.rb +3 -0
- data/lib/rover_prover.rb +111 -0
- data/logo.png +0 -0
- data/rover_prover.gemspec +28 -0
- metadata +138 -0
@@ -0,0 +1,126 @@
|
|
1
|
+
require_relative './formula/formulae.rb'
|
2
|
+
class Sequent
|
3
|
+
attr_reader :left, :right, :siblings, :depth
|
4
|
+
def initialize(left, right, siblings, depth)
|
5
|
+
@left = []
|
6
|
+
@right = []
|
7
|
+
@left_depth_tbl = {}
|
8
|
+
@right_depth_tbl = {}
|
9
|
+
left.each { |l| left_add(l) }
|
10
|
+
right.each { |l| right_add(l) }
|
11
|
+
@siblings = siblings
|
12
|
+
@depth = depth
|
13
|
+
end
|
14
|
+
|
15
|
+
def deepen(enable_siblings: false)
|
16
|
+
new_siblings = @siblings.nil? ? (enable_siblings ? [] : @siblings): @siblings.dup
|
17
|
+
new = Sequent.new(@left.dup, @right.dup, new_siblings, @depth + 1)
|
18
|
+
@left.each do |formula|
|
19
|
+
new.left_set_depth(formula, left_get_depth(formula))
|
20
|
+
end
|
21
|
+
@right.each do |formula|
|
22
|
+
new.right_set_depth(formula, right_get_depth(formula))
|
23
|
+
end
|
24
|
+
new
|
25
|
+
end
|
26
|
+
|
27
|
+
def trivial?
|
28
|
+
(@left & @right).length > 0
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_default_instantiation_time(time)
|
32
|
+
@left.each { |l| l.set_instantiation_time(time) }
|
33
|
+
@right.each { |r| r.set_instantiation_time(time) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def left_formula
|
37
|
+
@left.reject { |f| f.is_a?(Predicate) }.min_by { |f| left_get_depth(f) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def right_formula
|
41
|
+
@right.reject { |f| f.is_a?(Predicate) }.min_by { |f| right_get_depth(f) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def left_add(l)
|
45
|
+
@left.push(l)
|
46
|
+
@left_depth_tbl[l] = 0
|
47
|
+
end
|
48
|
+
|
49
|
+
def right_add(r)
|
50
|
+
@right.push(r)
|
51
|
+
@right_depth_tbl[r] = 0
|
52
|
+
end
|
53
|
+
|
54
|
+
def left_remove(l)
|
55
|
+
@left.delete(l)
|
56
|
+
@left_depth_tbl.delete(l)
|
57
|
+
end
|
58
|
+
|
59
|
+
def right_remove(r)
|
60
|
+
@right.delete(r)
|
61
|
+
@right_depth_tbl.delete(r)
|
62
|
+
end
|
63
|
+
|
64
|
+
def left_get_depth(l)
|
65
|
+
@left_depth_tbl[l]
|
66
|
+
end
|
67
|
+
|
68
|
+
def right_get_depth(r)
|
69
|
+
@right_depth_tbl[r]
|
70
|
+
end
|
71
|
+
|
72
|
+
def left_set_depth(l, t)
|
73
|
+
@left_depth_tbl[l] = t
|
74
|
+
end
|
75
|
+
|
76
|
+
def right_set_depth(r, t)
|
77
|
+
@right_depth_tbl[r] = t
|
78
|
+
end
|
79
|
+
|
80
|
+
def free_variables
|
81
|
+
@left.map { |formula| formula.free_variables }.flatten | @right.map { |formula| formula.free_variables}.flatten
|
82
|
+
end
|
83
|
+
|
84
|
+
def free_unification_terms
|
85
|
+
@left.map { |formula| formula.free_unification_terms }.flatten | @right.map { |formula| formula.free_unification_terms}.flatten
|
86
|
+
end
|
87
|
+
|
88
|
+
def get_variable_name(prefix)
|
89
|
+
names = free_variables.map(&:name) | free_unification_terms.map(&:name)
|
90
|
+
index = 1
|
91
|
+
name = prefix + index.to_s
|
92
|
+
while names.include?(name) do
|
93
|
+
index += 1
|
94
|
+
name = prefix + index.to_s
|
95
|
+
end
|
96
|
+
name
|
97
|
+
end
|
98
|
+
|
99
|
+
def get_unifiable_pairs
|
100
|
+
pairs = []
|
101
|
+
@left.each do |formula_a|
|
102
|
+
@right.each do |formula_b|
|
103
|
+
pairs.push([formula_a, formula_b]) unless formula_a.unify(formula_b).nil?
|
104
|
+
end
|
105
|
+
end
|
106
|
+
pairs
|
107
|
+
end
|
108
|
+
|
109
|
+
def to_s
|
110
|
+
"#{@left.map(&:to_s).join(', ')} ⊢ #{@right.map(&:to_s).join(', ')}"
|
111
|
+
end
|
112
|
+
|
113
|
+
def eql?(sequent)
|
114
|
+
include?(@left, sequent.left) &&
|
115
|
+
include?(@right, sequent.right) &&
|
116
|
+
include?(sequent.left, @left) &&
|
117
|
+
include?(sequent.right, @right)
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
def include?(formulas1, formulas2)
|
122
|
+
formulas2.all? do |f2|
|
123
|
+
formulas1.any? { |f1| f1.eql?(f2) }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative '../term.rb'
|
2
|
+
|
3
|
+
class Function < Term
|
4
|
+
attr_reader :terms
|
5
|
+
def initialize(name, terms)
|
6
|
+
super(name)
|
7
|
+
@terms = terms
|
8
|
+
end
|
9
|
+
|
10
|
+
def free_variables
|
11
|
+
@terms.map(&:free_variables).flatten.uniq
|
12
|
+
end
|
13
|
+
|
14
|
+
def free_unification_terms
|
15
|
+
@terms.map(&:free_unification_terms).flatten.uniq
|
16
|
+
end
|
17
|
+
|
18
|
+
def replace(old, new)
|
19
|
+
return new if eql?(old)
|
20
|
+
Function.new(@name, @terms.map { |term| term.replace(old, new) })
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_instantiation_time(time)
|
24
|
+
@time = time
|
25
|
+
@terms.each{ |term| term.set_instantiation_time(time) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def occurs(unification_term)
|
29
|
+
@terms.any? { |term| term.occurs(unification_term) }
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def eql?(function)
|
34
|
+
return false unless function.is_a?(Function)
|
35
|
+
return false unless @name == function.name
|
36
|
+
return false unless @terms.length == function.terms.length
|
37
|
+
@terms.zip(function.terms).all? { |t1, t2| t1.eql?(t2) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
terms_s = @terms.empty? ? "" : "(#{@terms.map(&:to_s).join(', ')})"
|
42
|
+
"#{@name}#{terms_s}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def unify(term)
|
46
|
+
return term.unify(self) if term.is_a?(UnificationTerm)
|
47
|
+
return nil unless term.is_a?(Function)
|
48
|
+
return nil unless @terms.length == term.terms.length
|
49
|
+
term_pair = @terms.zip(term.terms)
|
50
|
+
subst = {}
|
51
|
+
|
52
|
+
term_pair.each do |term_a, term_b|
|
53
|
+
subst.each do |k, v|
|
54
|
+
term_a = term_a.replace(k, v)
|
55
|
+
term_b = term_b.replace(k, v)
|
56
|
+
end
|
57
|
+
sub = term_a.unify(term_b)
|
58
|
+
return nil if sub == nil
|
59
|
+
subst.merge!(sub)
|
60
|
+
end
|
61
|
+
subst
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative '../term.rb'
|
2
|
+
|
3
|
+
class UnificationTerm < Term
|
4
|
+
def free_variables
|
5
|
+
[]
|
6
|
+
end
|
7
|
+
|
8
|
+
def free_unification_terms
|
9
|
+
[self]
|
10
|
+
end
|
11
|
+
|
12
|
+
def replace(old, new)
|
13
|
+
return new if eql?(old)
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def occurs(unification_term)
|
18
|
+
eql?(unification_term)
|
19
|
+
end
|
20
|
+
|
21
|
+
def set_instantiation_time(time)
|
22
|
+
@time = time
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
@name
|
27
|
+
end
|
28
|
+
|
29
|
+
def eql?(uni)
|
30
|
+
return false unless uni.is_a?(UnificationTerm)
|
31
|
+
@name == uni.name
|
32
|
+
end
|
33
|
+
|
34
|
+
def unify(term)
|
35
|
+
return nil if term.occurs(self) || term.time > @time
|
36
|
+
{ self => term }
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative '../term.rb'
|
2
|
+
|
3
|
+
class Variable < Term
|
4
|
+
def free_variables
|
5
|
+
[self]
|
6
|
+
end
|
7
|
+
|
8
|
+
def free_unification_terms
|
9
|
+
[]
|
10
|
+
end
|
11
|
+
|
12
|
+
def replace(old, new)
|
13
|
+
return new if eql?(old)
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def occurs(unification_term)
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def set_instantiation_time(time)
|
22
|
+
@time = time
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
@name
|
27
|
+
end
|
28
|
+
|
29
|
+
def eql?(var)
|
30
|
+
return false unless var.is_a?(Variable)
|
31
|
+
@name == var.name
|
32
|
+
end
|
33
|
+
|
34
|
+
def unify(term)
|
35
|
+
return term.unify(self) if term.is_a?(UnificationTerm)
|
36
|
+
return nil unless term.is_a?(Variable)
|
37
|
+
return nil unless eql?(term)
|
38
|
+
{}
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Axioms
|
2
|
+
end
|
3
|
+
|
4
|
+
class Lemmas
|
5
|
+
end
|
6
|
+
|
7
|
+
class Axiom
|
8
|
+
attr_reader :formula
|
9
|
+
def initialize(formula)
|
10
|
+
@formula = formula
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Lemma
|
15
|
+
attr_reader :formula
|
16
|
+
def initialize(formula)
|
17
|
+
@formula = formula
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Remove
|
22
|
+
attr_reader :formula
|
23
|
+
def initialize(formula)
|
24
|
+
@formula = formula
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Reset
|
29
|
+
end
|
30
|
+
|
31
|
+
class Exit
|
32
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rltk'
|
2
|
+
|
3
|
+
class RoverLexer < RLTK::Lexer
|
4
|
+
rule(/axioms/) { :AXIOMS }
|
5
|
+
rule(/lemmas/) { :LEMMAS }
|
6
|
+
rule(/axiom/) { :AXIOM }
|
7
|
+
rule(/lemma/) { :LEMMA }
|
8
|
+
rule(/remove/) { :REMOVE }
|
9
|
+
rule(/reset/) { :RESET }
|
10
|
+
rule(/exit/) { :EXIT }
|
11
|
+
rule(/\(/) { :LPAREN }
|
12
|
+
rule(/\)/) { :RPAREN }
|
13
|
+
rule(/\./) { :PERIOD }
|
14
|
+
rule(/,/) { :COMMA }
|
15
|
+
rule(/not/) { :NOT }
|
16
|
+
rule(/and/) { :AND }
|
17
|
+
rule(/or/) { :OR }
|
18
|
+
rule(/implies/) { :IMPLIES }
|
19
|
+
rule(/forall/) { :FORALL }
|
20
|
+
rule(/exists/) { :EXISTS }
|
21
|
+
rule(/[a-zA-Z][a-zA-Z0-9]*/) { |t| [:SYMBOL, t] }
|
22
|
+
rule(/\s/)
|
23
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rltk'
|
2
|
+
require_relative 'commands.rb'
|
3
|
+
require_relative '../language.rb'
|
4
|
+
|
5
|
+
class RoverParser < RLTK::Parser
|
6
|
+
right :IMPLIES
|
7
|
+
left :OR, :AND
|
8
|
+
|
9
|
+
production(:cmd) do
|
10
|
+
clause('AXIOMS') { |_| Axioms.new }
|
11
|
+
clause('LEMMAS') { |_| Lemmas.new }
|
12
|
+
clause('AXIOM noright') { |_, e| Axiom.new(e) }
|
13
|
+
clause('LEMMA noright') { |_, e| Lemma.new(e) }
|
14
|
+
clause('REMOVE noright') { |_, e| Remove.new(e) }
|
15
|
+
clause('RESET') { |_| Reset.new }
|
16
|
+
clause('EXIT') { |_| Exit.new }
|
17
|
+
clause('noright') { |e| e }
|
18
|
+
end
|
19
|
+
|
20
|
+
production(:noright) do
|
21
|
+
clause('FORALL SYMBOL PERIOD noright') { |_, s, _, f| ForAll.new(Variable.new(s), f) }
|
22
|
+
clause('EXISTS SYMBOL PERIOD noright') { |_, s, _, f| ThereExists.new(Variable.new(s), f) }
|
23
|
+
clause('formula') { |e| e }
|
24
|
+
end
|
25
|
+
|
26
|
+
production(:formula) do
|
27
|
+
clause('formula_with_right OR noright') { |e1, _, e2| Or.new(e1, e2) }
|
28
|
+
clause('formula_with_right AND noright') { |e1, _, e2| And.new(e1, e2) }
|
29
|
+
clause('formula_with_right IMPLIES noright') { |e1, _, e2| Implies.new(e1, e2) }
|
30
|
+
clause('literal') { |e| e }
|
31
|
+
end
|
32
|
+
|
33
|
+
production(:formula_with_right) do
|
34
|
+
clause('formula_with_right OR formula_with_right') { |e1, _, e2| Or.new(e1, e2) }
|
35
|
+
clause('formula_with_right AND formula_with_right') { |e1, _, e2| And.new(e1, e2) }
|
36
|
+
clause('formula_with_right IMPLIES formula_with_right') { |e1, _, e2| Implies.new(e1, e2) }
|
37
|
+
clause('literal') { |e| e }
|
38
|
+
end
|
39
|
+
|
40
|
+
production(:literal) do
|
41
|
+
clause('NOT literal') { |_, e| Not.new(e) }
|
42
|
+
clause('predicate') { |e| e }
|
43
|
+
end
|
44
|
+
|
45
|
+
production(:predicate) do
|
46
|
+
clause('SYMBOL') { |s| Predicate.new(s, []) }
|
47
|
+
clause('SYMBOL LPAREN RPAREN') { |s, _, _| Predicate.new(s, []) }
|
48
|
+
clause('SYMBOL LPAREN term_ls RPAREN') { |s, _, ls, _| Predicate.new(s, ls) }
|
49
|
+
clause('LPAREN formula RPAREN') { |_, f, _| f }
|
50
|
+
end
|
51
|
+
|
52
|
+
production(:term_ls) do
|
53
|
+
clause('term COMMA term_ls') { |t, _, ls| ls.unshift(t) }
|
54
|
+
clause('term') { |t| [t] }
|
55
|
+
end
|
56
|
+
|
57
|
+
production(:term) do
|
58
|
+
clause('SYMBOL') { |s| Variable.new(s) }
|
59
|
+
clause('SYMBOL LPAREN RPAREN') { |s, _, _| Function.new(s, []) }
|
60
|
+
clause('SYMBOL LPAREN term_ls RPAREN') { |s, _, ls, _| Function.new(s, ls) }
|
61
|
+
end
|
62
|
+
|
63
|
+
finalize
|
64
|
+
end
|
@@ -0,0 +1,277 @@
|
|
1
|
+
require_relative 'unifier.rb'
|
2
|
+
require_relative '../language.rb'
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
class Prover
|
6
|
+
def prove_formula(axioms, formula)
|
7
|
+
prove(
|
8
|
+
Sequent.new(
|
9
|
+
axioms,
|
10
|
+
[formula],
|
11
|
+
nil,
|
12
|
+
0
|
13
|
+
)
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def prove(sequent)
|
18
|
+
sequent.set_default_instantiation_time(0)
|
19
|
+
unifier = Unifier.new
|
20
|
+
|
21
|
+
frontier = [sequent]
|
22
|
+
proven = []
|
23
|
+
while true do
|
24
|
+
frontier = frontier - proven
|
25
|
+
old = frontier.pop
|
26
|
+
break if old.nil?
|
27
|
+
puts "#{old.depth}. #{old.to_s}"
|
28
|
+
|
29
|
+
if old.trivial?
|
30
|
+
proven.push(old)
|
31
|
+
next
|
32
|
+
end
|
33
|
+
|
34
|
+
unless old.siblings.nil?
|
35
|
+
pairs_list = old.siblings.map(&:get_unifiable_pairs)
|
36
|
+
if pairs_list.all? { |list| !list.empty? }
|
37
|
+
subst = unifier.unify_all(pairs_list)
|
38
|
+
unless subst.nil?
|
39
|
+
subst.each { |k, v| puts "#{k.to_s} = #{v.to_s}" }
|
40
|
+
proven = proven | old.siblings
|
41
|
+
frontier = frontier - proven
|
42
|
+
next
|
43
|
+
end
|
44
|
+
else
|
45
|
+
old.siblings.delete(old)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
left = old.left_formula
|
50
|
+
right = old.right_formula
|
51
|
+
return false if left.nil? && right.nil?
|
52
|
+
|
53
|
+
if apply_left?(old, left, right)
|
54
|
+
frontier.push(*derivation_left(old, left))
|
55
|
+
else
|
56
|
+
frontier.push(*derivation_right(old, right))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
def derivation_left(old, left)
|
63
|
+
return derivation_left_not(old, left) if left.is_a?(Not)
|
64
|
+
return derivation_left_and(old, left) if left.is_a?(And)
|
65
|
+
return derivation_left_or(old, left) if left.is_a?(Or)
|
66
|
+
return derivation_left_implies(old, left) if left.is_a?(Implies)
|
67
|
+
return derivation_left_for_all(old, left) if left.is_a?(ForAll)
|
68
|
+
return derivation_left_there_exists(old, left) if left.is_a?(ThereExists)
|
69
|
+
[]
|
70
|
+
end
|
71
|
+
|
72
|
+
def derivation_right(old, right)
|
73
|
+
return derivation_right_not(old, right) if right.is_a?(Not)
|
74
|
+
return derivation_right_and(old, right) if right.is_a?(And)
|
75
|
+
return derivation_right_or(old, right) if right.is_a?(Or)
|
76
|
+
return derivation_right_implies(old, right) if right.is_a?(Implies)
|
77
|
+
return derivation_right_for_all(old, right) if right.is_a?(ForAll)
|
78
|
+
return derivation_right_there_exists(old, right) if right.is_a?(ThereExists)
|
79
|
+
[]
|
80
|
+
end
|
81
|
+
|
82
|
+
def derivation_left_not(sequent, left)
|
83
|
+
new = sequent.deepen
|
84
|
+
new.left_remove(left)
|
85
|
+
new.right_add(left.formula)
|
86
|
+
new.right_set_depth(left.formula, (sequent.left_get_depth(left) + 1))
|
87
|
+
unless new.siblings.nil?
|
88
|
+
new.siblings.push(new)
|
89
|
+
end
|
90
|
+
[new]
|
91
|
+
end
|
92
|
+
|
93
|
+
def derivation_left_and(sequent, left)
|
94
|
+
new = sequent.deepen
|
95
|
+
new.left_remove(left)
|
96
|
+
left_depth = sequent.left_get_depth(left)
|
97
|
+
new.left_add(left.formula_a)
|
98
|
+
new.left_set_depth(left.formula_a, left_depth + 1)
|
99
|
+
new.left_add(left.formula_b)
|
100
|
+
new.left_set_depth(left.formula_b, left_depth + 1)
|
101
|
+
unless new.siblings.nil?
|
102
|
+
new.siblings.push(new)
|
103
|
+
end
|
104
|
+
[new]
|
105
|
+
end
|
106
|
+
|
107
|
+
def derivation_left_or(sequent, left)
|
108
|
+
new_a = sequent.deepen
|
109
|
+
new_b = sequent.deepen
|
110
|
+
new_a.left_remove(left)
|
111
|
+
new_b.left_remove(left)
|
112
|
+
left_depth = sequent.left_get_depth(left)
|
113
|
+
new_a.left_add(left.formula_a)
|
114
|
+
new_a.left_set_depth(left.formula_a, left_depth + 1)
|
115
|
+
new_b.left_add(left.formula_b)
|
116
|
+
new_b.left_set_depth(left.formula_b, left_depth + 1)
|
117
|
+
unless new_a.siblings.nil?
|
118
|
+
new_a.siblings.push(new_a)
|
119
|
+
end
|
120
|
+
unless new_b.siblings.nil?
|
121
|
+
new_b.siblings.push(new_b)
|
122
|
+
end
|
123
|
+
[new_a, new_b]
|
124
|
+
end
|
125
|
+
|
126
|
+
def derivation_left_implies(sequent, left)
|
127
|
+
new_a = sequent.deepen
|
128
|
+
new_b = sequent.deepen
|
129
|
+
new_a.left_remove(left)
|
130
|
+
new_b.left_remove(left)
|
131
|
+
left_depth = sequent.left_get_depth(left)
|
132
|
+
new_a.right_add(left.formula_a)
|
133
|
+
new_a.right_set_depth(left.formula_a, left_depth + 1)
|
134
|
+
new_b.left_add(left.formula_b)
|
135
|
+
new_b.left_set_depth(left.formula_b, left_depth + 1)
|
136
|
+
unless new_a.siblings.nil?
|
137
|
+
new_a.siblings.push(new_a)
|
138
|
+
end
|
139
|
+
unless new_b.siblings.nil?
|
140
|
+
new_b.siblings.push(new_b)
|
141
|
+
end
|
142
|
+
[new_a, new_b]
|
143
|
+
end
|
144
|
+
|
145
|
+
def derivation_left_for_all(sequent, left)
|
146
|
+
new = sequent.deepen(enable_siblings: true)
|
147
|
+
left_depth = sequent.left_get_depth(left)
|
148
|
+
new.left_set_depth(left, left_depth + 1)
|
149
|
+
formula = left.formula.replace(
|
150
|
+
left.variable,
|
151
|
+
UnificationTerm.new(sequent.get_variable_name('t'))
|
152
|
+
)
|
153
|
+
formula.set_instantiation_time(sequent.depth + 1)
|
154
|
+
unless new.left.include?(formula)
|
155
|
+
new.left_add(formula)
|
156
|
+
new.left_set_depth(formula, left_depth + 1)
|
157
|
+
end
|
158
|
+
unless new.siblings.nil?
|
159
|
+
new.siblings.push(new)
|
160
|
+
end
|
161
|
+
[new]
|
162
|
+
end
|
163
|
+
|
164
|
+
def derivation_left_there_exists(sequent, left)
|
165
|
+
new = sequent.deepen
|
166
|
+
new.left_remove(left)
|
167
|
+
left_depth = sequent.left_get_depth(left)
|
168
|
+
variable = Variable.new(sequent.get_variable_name('v'))
|
169
|
+
formula = left.formula.replace(left.variable, variable)
|
170
|
+
formula.set_instantiation_time(sequent.depth + 1)
|
171
|
+
new.left_add(formula)
|
172
|
+
new.left_set_depth(formula, left_depth + 1)
|
173
|
+
unless new.siblings.nil?
|
174
|
+
new.siblings.push(new)
|
175
|
+
end
|
176
|
+
[new]
|
177
|
+
end
|
178
|
+
|
179
|
+
def derivation_right_not(sequent, right)
|
180
|
+
new = sequent.deepen
|
181
|
+
new.right_remove(right)
|
182
|
+
new.left_add(right.formula)
|
183
|
+
new.left_set_depth(right.formula, (sequent.right_get_depth(right) + 1))
|
184
|
+
unless new.siblings.nil?
|
185
|
+
new.siblings.push(new)
|
186
|
+
end
|
187
|
+
[new]
|
188
|
+
end
|
189
|
+
|
190
|
+
def derivation_right_and(sequent, right)
|
191
|
+
new_a = sequent.deepen
|
192
|
+
new_b = sequent.deepen
|
193
|
+
new_a.right_remove(right)
|
194
|
+
new_b.right_remove(right)
|
195
|
+
right_depth = sequent.right_get_depth(right)
|
196
|
+
new_a.right_add(right.formula_a)
|
197
|
+
new_a.right_set_depth(right.formula_a, right_depth + 1)
|
198
|
+
new_b.right_add(right.formula_b)
|
199
|
+
new_b.right_set_depth(right.formula_b, right_depth + 1)
|
200
|
+
unless new_a.siblings.nil?
|
201
|
+
new_a.siblings.push(new_a)
|
202
|
+
end
|
203
|
+
unless new_b.siblings.nil?
|
204
|
+
new_b.siblings.push(new_b)
|
205
|
+
end
|
206
|
+
[new_a, new_b]
|
207
|
+
end
|
208
|
+
|
209
|
+
def derivation_right_or(sequent, right)
|
210
|
+
new = sequent.deepen
|
211
|
+
new.right_remove(right)
|
212
|
+
right_depth = sequent.right_get_depth(right)
|
213
|
+
new.right_add(right.formula_a)
|
214
|
+
new.right_set_depth(right.formula_a, right_depth + 1)
|
215
|
+
new.right_add(right.formula_b)
|
216
|
+
new.right_set_depth(right.formula_b, right_depth + 1)
|
217
|
+
unless new.siblings.nil?
|
218
|
+
new.siblings.push(new)
|
219
|
+
end
|
220
|
+
[new]
|
221
|
+
end
|
222
|
+
|
223
|
+
def derivation_right_implies(sequent, right)
|
224
|
+
new = sequent.deepen
|
225
|
+
new.right_remove(right)
|
226
|
+
right_depth = sequent.right_get_depth(right)
|
227
|
+
new.left_add(right.formula_a)
|
228
|
+
new.left_set_depth(right.formula_a, right_depth + 1)
|
229
|
+
new.right_add(right.formula_b)
|
230
|
+
new.right_set_depth(right.formula_b, right_depth + 1)
|
231
|
+
unless new.siblings.nil?
|
232
|
+
new.siblings.push(new)
|
233
|
+
end
|
234
|
+
[new]
|
235
|
+
end
|
236
|
+
|
237
|
+
def derivation_right_for_all(sequent, right)
|
238
|
+
new = sequent.deepen
|
239
|
+
new.right_remove(right)
|
240
|
+
right_depth = sequent.right_get_depth(right)
|
241
|
+
variable = Variable.new(sequent.get_variable_name('v'))
|
242
|
+
formula = right.formula.replace(right.variable, variable)
|
243
|
+
formula.set_instantiation_time(sequent.depth + 1)
|
244
|
+
new.right_add(formula)
|
245
|
+
new.right_set_depth(formula, right_depth + 1)
|
246
|
+
unless new.siblings.nil?
|
247
|
+
new.siblings.push(new)
|
248
|
+
end
|
249
|
+
[new]
|
250
|
+
end
|
251
|
+
|
252
|
+
def derivation_right_there_exists(sequent, right)
|
253
|
+
new = sequent.deepen(enable_siblings: true)
|
254
|
+
right_depth = sequent.right_get_depth(right)
|
255
|
+
new.right_set_depth(right, right_depth + 1)
|
256
|
+
formula = right.formula.replace(
|
257
|
+
right.variable,
|
258
|
+
UnificationTerm.new(sequent.get_variable_name('t'))
|
259
|
+
)
|
260
|
+
unless new.right.include?(formula)
|
261
|
+
formula.set_instantiation_time(sequent.depth + 1)
|
262
|
+
new.right_add(formula)
|
263
|
+
end
|
264
|
+
new.right_set_depth(formula, right_depth + 1)
|
265
|
+
unless new.siblings.nil?
|
266
|
+
new.siblings.push(new)
|
267
|
+
end
|
268
|
+
[new]
|
269
|
+
end
|
270
|
+
|
271
|
+
private
|
272
|
+
def apply_left?(sequent, left, right)
|
273
|
+
return true if right.nil?
|
274
|
+
return false if left.nil?
|
275
|
+
sequent.right_get_depth(right) > sequent.left_get_depth(left)
|
276
|
+
end
|
277
|
+
end
|