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.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -0
  4. data/CODE_OF_CONDUCT.md +74 -0
  5. data/Gemfile +8 -0
  6. data/Gemfile.lock +32 -0
  7. data/LICENSE.txt +31 -0
  8. data/README.md +98 -0
  9. data/Rakefile +2 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/exe/rover_prover +5 -0
  13. data/lib/rover_prover/language/expression.rb +33 -0
  14. data/lib/rover_prover/language/formula/and.rb +41 -0
  15. data/lib/rover_prover/language/formula/for_all.rb +44 -0
  16. data/lib/rover_prover/language/formula/formulae.rb +7 -0
  17. data/lib/rover_prover/language/formula/implies.rb +41 -0
  18. data/lib/rover_prover/language/formula/not.rb +39 -0
  19. data/lib/rover_prover/language/formula/or.rb +41 -0
  20. data/lib/rover_prover/language/formula/predicate.rb +64 -0
  21. data/lib/rover_prover/language/formula/there_exists.rb +42 -0
  22. data/lib/rover_prover/language/formula.rb +5 -0
  23. data/lib/rover_prover/language/sequent.rb +126 -0
  24. data/lib/rover_prover/language/term/function.rb +63 -0
  25. data/lib/rover_prover/language/term/terms.rb +3 -0
  26. data/lib/rover_prover/language/term/unification_term.rb +38 -0
  27. data/lib/rover_prover/language/term/variable.rb +40 -0
  28. data/lib/rover_prover/language/term.rb +10 -0
  29. data/lib/rover_prover/language.rb +3 -0
  30. data/lib/rover_prover/processor/commands.rb +32 -0
  31. data/lib/rover_prover/processor/processor.rb +2 -0
  32. data/lib/rover_prover/processor/rover_lexer.rb +23 -0
  33. data/lib/rover_prover/processor/rover_parser.rb +64 -0
  34. data/lib/rover_prover/prover/prover.rb +277 -0
  35. data/lib/rover_prover/prover/unifier.rb +29 -0
  36. data/lib/rover_prover/version.rb +3 -0
  37. data/lib/rover_prover.rb +111 -0
  38. data/logo.png +0 -0
  39. data/rover_prover.gemspec +28 -0
  40. 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,3 @@
1
+ require_relative 'function.rb'
2
+ require_relative 'unification_term.rb'
3
+ require_relative 'variable.rb'
@@ -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,10 @@
1
+ require_relative 'expression.rb'
2
+ class Term
3
+ attr_reader :time, :name
4
+ TIME_DEFAULT = 0
5
+ include Expression
6
+ def initialize(name)
7
+ @name = name
8
+ @time = TIME_DEFAULT
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ require_relative 'language/formula/formulae.rb'
2
+ require_relative 'language/term/terms.rb'
3
+ require_relative 'language/sequent.rb'
@@ -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,2 @@
1
+ require_relative 'rover_lexer.rb'
2
+ require_relative 'rover_parser.rb'
@@ -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