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,29 @@
|
|
1
|
+
require 'pry'
|
2
|
+
class Unifier
|
3
|
+
|
4
|
+
def unify_all(pairs_list)
|
5
|
+
lengths = pairs_list.map { |pair| (0..(pair.length - 1)).to_a }
|
6
|
+
first = lengths.shift
|
7
|
+
indexes = first.product(*lengths)
|
8
|
+
indexes.each do |index|
|
9
|
+
possible_pairs = pairs_list.map.with_index { |pairs, i| pairs[index[i]] }
|
10
|
+
subst = unify_list(possible_pairs)
|
11
|
+
return subst unless subst.nil?
|
12
|
+
end
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def unify_list(pairs)
|
17
|
+
substitution = {}
|
18
|
+
pairs.each do |a, b|
|
19
|
+
substitution.each do |k, v|
|
20
|
+
a = a.replace(k, v)
|
21
|
+
b = b.replace(k, v)
|
22
|
+
end
|
23
|
+
sub = a.unify(b)
|
24
|
+
return nil if sub.nil?
|
25
|
+
substitution.merge!(sub)
|
26
|
+
end
|
27
|
+
substitution
|
28
|
+
end
|
29
|
+
end
|
data/lib/rover_prover.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
require_relative 'rover_prover/processor/processor.rb'
|
2
|
+
require_relative 'rover_prover/prover/prover.rb'
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
module RoverProver
|
6
|
+
module Main
|
7
|
+
def self.run
|
8
|
+
message = <<~MSG
|
9
|
+
Rover: First-Order Logic Theorem Prover
|
10
|
+
2019 Koki Ryu
|
11
|
+
2014 Stephan Boyer
|
12
|
+
Terms:
|
13
|
+
|
14
|
+
x (variable)
|
15
|
+
f(term, ...) (function)
|
16
|
+
|
17
|
+
Formulae:
|
18
|
+
|
19
|
+
P(term) (predicate)
|
20
|
+
not P (complement)
|
21
|
+
P or Q (disjunction)
|
22
|
+
P and Q (conjunction)
|
23
|
+
P implies Q (implication)
|
24
|
+
forall x. P (universal quantification)
|
25
|
+
exists x. P (existential quantification)
|
26
|
+
|
27
|
+
Enter formulae at the prompt. The following commands are also available for manipulating axioms:
|
28
|
+
|
29
|
+
axioms (list axioms)
|
30
|
+
lemmas (list lemmas)
|
31
|
+
axiom <formula> (add an axiom)
|
32
|
+
lemma <formula> (prove and add a lemma)
|
33
|
+
remove <formula> (remove an axiom or lemma)
|
34
|
+
reset (remove all axioms and lemmas)
|
35
|
+
|
36
|
+
Enter 'exit' command to exit the prompt.
|
37
|
+
MSG
|
38
|
+
|
39
|
+
puts message
|
40
|
+
|
41
|
+
axioms = []
|
42
|
+
lemmas = {}
|
43
|
+
|
44
|
+
prover = Prover.new
|
45
|
+
|
46
|
+
while true do
|
47
|
+
begin
|
48
|
+
print("\nRover> ")
|
49
|
+
cmd = gets
|
50
|
+
if cmd.nil?
|
51
|
+
puts 'Bye'
|
52
|
+
return
|
53
|
+
end
|
54
|
+
cmd_token = RoverParser.parse(RoverLexer.lex(cmd))
|
55
|
+
if cmd_token.is_a?(Axioms)
|
56
|
+
axioms.each { |axiom| puts axiom.to_s }
|
57
|
+
elsif cmd_token.is_a?(Lemmas)
|
58
|
+
lemmas.keys.each { |lemma| puts lemma.to_s }
|
59
|
+
elsif cmd_token.is_a?(Axiom)
|
60
|
+
axioms.push(cmd_token.formula)
|
61
|
+
puts "Axiom added: #{cmd_token.formula.to_s}"
|
62
|
+
elsif cmd_token.is_a?(Lemma)
|
63
|
+
result = prover.prove_formula(axioms | lemmas.keys, cmd_token.formula)
|
64
|
+
if result
|
65
|
+
lemmas[cmd_token.formula] = axioms.dup
|
66
|
+
puts "Lemma proven: #{cmd_token.formula.to_s}"
|
67
|
+
else
|
68
|
+
puts "Lemma unprovable: #{cmd_token.formula.to_s}"
|
69
|
+
end
|
70
|
+
elsif cmd_token.is_a?(Remove)
|
71
|
+
result = axioms.reject! { |axiom| axiom.eql?(cmd_token.formula) }
|
72
|
+
if result.nil?
|
73
|
+
puts "Not an axiom: #{cmd_token.formula.to_s}"
|
74
|
+
else
|
75
|
+
puts "Axiom removed: #{cmd_token.formula.to_s}"
|
76
|
+
bad_lemmas = lemmas.keys.select { |key| lemmas[key].any?{ |lemma| lemma.eql?(cmd_token.formula) } }
|
77
|
+
puts "Dependent axioms are also removed:"
|
78
|
+
bad_lemmas.each do |lemma|
|
79
|
+
lemmas.delete(lemma)
|
80
|
+
puts lemma.to_s
|
81
|
+
end
|
82
|
+
end
|
83
|
+
elsif cmd_token.is_a?(Reset)
|
84
|
+
axioms = []
|
85
|
+
lemmas = {}
|
86
|
+
elsif cmd_token.is_a?(Exit)
|
87
|
+
puts 'Bye'
|
88
|
+
return
|
89
|
+
else
|
90
|
+
result = prover.prove_formula(axioms | lemmas.keys, cmd_token)
|
91
|
+
if result
|
92
|
+
puts "Formula proven: #{cmd_token.to_s}"
|
93
|
+
else
|
94
|
+
puts "Formula unprovable: #{cmd_token.to_s}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
rescue Interrupt
|
100
|
+
next
|
101
|
+
rescue RLTK::LexingError => e
|
102
|
+
puts "Error: Unable to parse #{e.remainder}"
|
103
|
+
next
|
104
|
+
rescue RLTK::NotInLanguage
|
105
|
+
puts 'Error: Invalid command'
|
106
|
+
next
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/logo.png
ADDED
Binary file
|
@@ -0,0 +1,28 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "rover_prover/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "rover_prover"
|
7
|
+
spec.version = RoverProver::VERSION
|
8
|
+
spec.authors = ["Koki Ryu"]
|
9
|
+
spec.email = ["liukoki@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{First-Order Logic Theorem Prover}
|
12
|
+
spec.homepage = "https://github.com/liwii"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
# Specify which files should be added to the gem when it is released.
|
16
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
17
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
18
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec"
|
27
|
+
spec.add_runtime_dependency "rltk"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rover_prover
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Koki Ryu
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-06-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rltk
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- liukoki@gmail.com
|
72
|
+
executables:
|
73
|
+
- rover_prover
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- ".rspec"
|
79
|
+
- CODE_OF_CONDUCT.md
|
80
|
+
- Gemfile
|
81
|
+
- Gemfile.lock
|
82
|
+
- LICENSE.txt
|
83
|
+
- README.md
|
84
|
+
- Rakefile
|
85
|
+
- bin/console
|
86
|
+
- bin/setup
|
87
|
+
- exe/rover_prover
|
88
|
+
- lib/rover_prover.rb
|
89
|
+
- lib/rover_prover/language.rb
|
90
|
+
- lib/rover_prover/language/expression.rb
|
91
|
+
- lib/rover_prover/language/formula.rb
|
92
|
+
- lib/rover_prover/language/formula/and.rb
|
93
|
+
- lib/rover_prover/language/formula/for_all.rb
|
94
|
+
- lib/rover_prover/language/formula/formulae.rb
|
95
|
+
- lib/rover_prover/language/formula/implies.rb
|
96
|
+
- lib/rover_prover/language/formula/not.rb
|
97
|
+
- lib/rover_prover/language/formula/or.rb
|
98
|
+
- lib/rover_prover/language/formula/predicate.rb
|
99
|
+
- lib/rover_prover/language/formula/there_exists.rb
|
100
|
+
- lib/rover_prover/language/sequent.rb
|
101
|
+
- lib/rover_prover/language/term.rb
|
102
|
+
- lib/rover_prover/language/term/function.rb
|
103
|
+
- lib/rover_prover/language/term/terms.rb
|
104
|
+
- lib/rover_prover/language/term/unification_term.rb
|
105
|
+
- lib/rover_prover/language/term/variable.rb
|
106
|
+
- lib/rover_prover/processor/commands.rb
|
107
|
+
- lib/rover_prover/processor/processor.rb
|
108
|
+
- lib/rover_prover/processor/rover_lexer.rb
|
109
|
+
- lib/rover_prover/processor/rover_parser.rb
|
110
|
+
- lib/rover_prover/prover/prover.rb
|
111
|
+
- lib/rover_prover/prover/unifier.rb
|
112
|
+
- lib/rover_prover/version.rb
|
113
|
+
- logo.png
|
114
|
+
- rover_prover.gemspec
|
115
|
+
homepage: https://github.com/liwii
|
116
|
+
licenses:
|
117
|
+
- MIT
|
118
|
+
metadata: {}
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
requirements: []
|
134
|
+
rubygems_version: 3.0.1
|
135
|
+
signing_key:
|
136
|
+
specification_version: 4
|
137
|
+
summary: First-Order Logic Theorem Prover
|
138
|
+
test_files: []
|