satre 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 +35 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +110 -0
- data/Guardfile +42 -0
- data/LICENSE +22 -0
- data/README.md +82 -0
- data/Rakefile +17 -0
- data/bin/console +9 -0
- data/bin/exercise +70 -0
- data/bin/setup +7 -0
- data/lib/satre.rb +6 -0
- data/lib/satre/expression.rb +6 -0
- data/lib/satre/expression/add.rb +26 -0
- data/lib/satre/expression/const.rb +23 -0
- data/lib/satre/expression/expression.rb +22 -0
- data/lib/satre/expression/expression_parser.rb +56 -0
- data/lib/satre/expression/mul.rb +30 -0
- data/lib/satre/expression/var.rb +14 -0
- data/lib/satre/formula.rb +10 -0
- data/lib/satre/formula/and.rb +26 -0
- data/lib/satre/formula/atom.rb +28 -0
- data/lib/satre/formula/entails.rb +29 -0
- data/lib/satre/formula/false.rb +19 -0
- data/lib/satre/formula/formula.rb +61 -0
- data/lib/satre/formula/iff.rb +27 -0
- data/lib/satre/formula/imp.rb +25 -0
- data/lib/satre/formula/not.rb +22 -0
- data/lib/satre/formula/or.rb +25 -0
- data/lib/satre/formula/true.rb +17 -0
- data/lib/satre/formula_parser.rb +92 -0
- data/lib/satre/lexer.rb +47 -0
- data/lib/satre/parser.rb +15 -0
- data/lib/satre/version.rb +3 -0
- data/satre.gemspec +40 -0
- metadata +239 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'satre/formula'
|
2
|
+
|
3
|
+
module Satre
|
4
|
+
class Or < Formula
|
5
|
+
attr_reader :p
|
6
|
+
attr_reader :q
|
7
|
+
|
8
|
+
def initialize(p,q)
|
9
|
+
fail(ArgumentError, 'Argument must be a Formula') unless p.is_a?(Formula)
|
10
|
+
fail(ArgumentError, 'Argument must be a Formula') unless q.is_a?(Formula)
|
11
|
+
@p = p.dup.freeze
|
12
|
+
@q = q.dup.freeze
|
13
|
+
super "(#{@p} ∨ #{@q})"
|
14
|
+
end
|
15
|
+
|
16
|
+
def eval(valudation)
|
17
|
+
p.eval(valudation) or q.eval(valudation)
|
18
|
+
end
|
19
|
+
|
20
|
+
def atoms
|
21
|
+
atoms = p.atoms + q.atoms
|
22
|
+
atoms.uniq || []
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'satre/formula'
|
2
|
+
|
3
|
+
module Satre
|
4
|
+
class FormulaParser < Parser
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def parse_formula
|
8
|
+
lambda do |inp|
|
9
|
+
e1, i1 = parse_imp(inp)
|
10
|
+
if i1[0] == '|='
|
11
|
+
e2, i2 = parse_formula.call(i1.drop(1))
|
12
|
+
return Entails.new(e1,e2), i2
|
13
|
+
end
|
14
|
+
return e1, i1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse_imp(inp)
|
19
|
+
e1, i1 = parse_iff(inp)
|
20
|
+
if i1[0] == '=>'
|
21
|
+
e2, i2 = parse_formula.call(i1.drop(1))
|
22
|
+
return Imp.new(e1,e2), i2
|
23
|
+
end
|
24
|
+
return e1, i1
|
25
|
+
end
|
26
|
+
|
27
|
+
def parse_not(inp)
|
28
|
+
if inp.first == '~'
|
29
|
+
e1, i1 = parse_atom(inp.drop(1))
|
30
|
+
return Not.new(e1), i1
|
31
|
+
else
|
32
|
+
e1, i1 = parse_atom(inp)
|
33
|
+
return e1, i1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse_and(inp)
|
38
|
+
e1, i1 = parse_or(inp)
|
39
|
+
if i1[0] == '/\\'
|
40
|
+
e2, i2 = parse_formula.call(i1.drop(1))
|
41
|
+
return And.new(e1,e2), i2
|
42
|
+
end
|
43
|
+
return e1, i1
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse_or(inp)
|
47
|
+
e1, i1 = parse_not(inp)
|
48
|
+
if i1[0] == '\\/'
|
49
|
+
e2, i2 = parse_formula.call(i1.drop(1))
|
50
|
+
return Or.new(e1, e2), i2
|
51
|
+
end
|
52
|
+
return e1, i1
|
53
|
+
end
|
54
|
+
|
55
|
+
def parse_iff(inp)
|
56
|
+
e1, i1 = parse_and(inp)
|
57
|
+
if i1[0] == '<=>'
|
58
|
+
e2, i2 = parse_formula.call(i1.drop(1))
|
59
|
+
return Iff.new(e1, e2), i2
|
60
|
+
end
|
61
|
+
return e1, i1
|
62
|
+
end
|
63
|
+
|
64
|
+
def parse_atom(inp)
|
65
|
+
fail(ArgumentError, 'Expected an expression at end of input') if inp == []
|
66
|
+
if inp[0] == '('
|
67
|
+
e2, i2 = parse_formula.call(inp.drop(1))
|
68
|
+
if i2[0] == ')'
|
69
|
+
return e2, i2.drop(1)
|
70
|
+
else
|
71
|
+
fail(ExpressionError, 'Expected closing bracket')
|
72
|
+
end
|
73
|
+
else
|
74
|
+
return False.new, inp.drop(1) if inp[0] == "False"
|
75
|
+
return True.new, inp.drop(1) if inp[0] == "True"
|
76
|
+
return Atom.new(inp[0]), inp.drop(1)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def parse(inp)
|
81
|
+
make_parser.curry.call(parse_formula).call(inp)
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class String
|
89
|
+
def to_formula
|
90
|
+
Satre::FormulaParser.parse(self)
|
91
|
+
end
|
92
|
+
end
|
data/lib/satre/lexer.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
module Satre
|
2
|
+
class Lexer
|
3
|
+
class << self
|
4
|
+
def matches
|
5
|
+
lambda { |pattern, str| str.split("").all? { |c| pattern.include? c } }
|
6
|
+
end
|
7
|
+
|
8
|
+
def space?
|
9
|
+
self.matches.curry.call(" \t\n\r").dup.freeze
|
10
|
+
end
|
11
|
+
|
12
|
+
def punctuation?
|
13
|
+
self.matches.curry.call("()[]{}").dup.freeze
|
14
|
+
end
|
15
|
+
|
16
|
+
def symbolic?
|
17
|
+
self.matches.curry.call("~`!@#%$^&*-+<=>\\/|").dup.freeze
|
18
|
+
end
|
19
|
+
|
20
|
+
def numeric?
|
21
|
+
self.matches.curry.call("0123456789").dup.freeze
|
22
|
+
end
|
23
|
+
|
24
|
+
def alpanumeric?
|
25
|
+
self.matches.curry.call("abcdefghijklmnopqrstuvwxyz_'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789").dup.freeze
|
26
|
+
end
|
27
|
+
|
28
|
+
def lexwhile(prop, inp)
|
29
|
+
tokl = inp.split("").take_while { |c| prop.call(c) }.inject(:+)
|
30
|
+
tokl = "" if tokl.nil?
|
31
|
+
return tokl, inp[tokl.length..-1]
|
32
|
+
end
|
33
|
+
|
34
|
+
def lex(inp)
|
35
|
+
inp, rest = self.lexwhile(self.space?, inp)
|
36
|
+
return [] if rest == "" || rest.nil?
|
37
|
+
c = rest[0]
|
38
|
+
cs = rest[1..-1]
|
39
|
+
prop = if self.alpanumeric?.call(c) then self.alpanumeric?
|
40
|
+
elsif self.symbolic?.call(c) then self.symbolic?
|
41
|
+
else proc { false } end
|
42
|
+
toktl, rest = self.lexwhile prop, cs
|
43
|
+
[c+toktl] + lex(rest)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/satre/parser.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'satre/lexer'
|
2
|
+
|
3
|
+
module Satre
|
4
|
+
class Parser
|
5
|
+
class << self
|
6
|
+
def make_parser
|
7
|
+
lambda do |pfn, inp|
|
8
|
+
expr, rest = pfn.call(Lexer.lex(inp))
|
9
|
+
return expr if rest == []
|
10
|
+
fail(ParserError, 'Unparsed input')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/satre.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'satre/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'satre'
|
8
|
+
spec.version = Satre::VERSION
|
9
|
+
spec.authors = ['Roman C. Podolski']
|
10
|
+
spec.email = ['roman.podolski@tum.de']
|
11
|
+
|
12
|
+
spec.summary = %q{A propositional and first order logic library}
|
13
|
+
spec.description = %q{
|
14
|
+
I think therefore I am.
|
15
|
+
|
16
|
+
Satre is a library for proportional and first order logic.
|
17
|
+
It was inspired by the book 'Handbook of practical logic and automated reasoning' by Harrison, J (2009).
|
18
|
+
|
19
|
+
This project originated at the Technical university munich as a students project in the lecture 'Basics of Artificial Intelligence'.
|
20
|
+
}
|
21
|
+
spec.homepage = "http://in.tum.de"
|
22
|
+
spec.license = 'MIT'
|
23
|
+
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
spec.bindir = 'exe'
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ['lib']
|
28
|
+
|
29
|
+
spec.add_runtime_dependency 'terminal-table'
|
30
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
31
|
+
spec.add_development_dependency 'guard-bundler'
|
32
|
+
spec.add_development_dependency 'minitest'
|
33
|
+
spec.add_development_dependency 'simplecov'
|
34
|
+
spec.add_development_dependency 'guard-minitest'
|
35
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
36
|
+
spec.add_development_dependency 'rspec'
|
37
|
+
spec.add_development_dependency 'pry'
|
38
|
+
spec.add_development_dependency 'rubocop'
|
39
|
+
spec.add_development_dependency 'guard-rubocop'
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: satre
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Roman C. Podolski
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: terminal-table
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.10'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.10'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: guard-bundler
|
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: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: guard-minitest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '10.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '10.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rubocop
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: guard-rubocop
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
description: "\n I think therefore I am.\n \n Satre is a library for proportional
|
168
|
+
and first order logic.\n It was inspired by the book 'Handbook of practical logic
|
169
|
+
and automated reasoning' by Harrison, J (2009).\n \n This project originated at
|
170
|
+
the Technical university munich as a students project in the lecture 'Basics of
|
171
|
+
Artificial Intelligence'.\n "
|
172
|
+
email:
|
173
|
+
- roman.podolski@tum.de
|
174
|
+
executables: []
|
175
|
+
extensions: []
|
176
|
+
extra_rdoc_files: []
|
177
|
+
files:
|
178
|
+
- ".gitignore"
|
179
|
+
- ".travis.yml"
|
180
|
+
- CODE_OF_CONDUCT.md
|
181
|
+
- Gemfile
|
182
|
+
- Gemfile.lock
|
183
|
+
- Guardfile
|
184
|
+
- LICENSE
|
185
|
+
- README.md
|
186
|
+
- Rakefile
|
187
|
+
- bin/console
|
188
|
+
- bin/exercise
|
189
|
+
- bin/setup
|
190
|
+
- lib/satre.rb
|
191
|
+
- lib/satre/expression.rb
|
192
|
+
- lib/satre/expression/add.rb
|
193
|
+
- lib/satre/expression/const.rb
|
194
|
+
- lib/satre/expression/expression.rb
|
195
|
+
- lib/satre/expression/expression_parser.rb
|
196
|
+
- lib/satre/expression/mul.rb
|
197
|
+
- lib/satre/expression/var.rb
|
198
|
+
- lib/satre/formula.rb
|
199
|
+
- lib/satre/formula/and.rb
|
200
|
+
- lib/satre/formula/atom.rb
|
201
|
+
- lib/satre/formula/entails.rb
|
202
|
+
- lib/satre/formula/false.rb
|
203
|
+
- lib/satre/formula/formula.rb
|
204
|
+
- lib/satre/formula/iff.rb
|
205
|
+
- lib/satre/formula/imp.rb
|
206
|
+
- lib/satre/formula/not.rb
|
207
|
+
- lib/satre/formula/or.rb
|
208
|
+
- lib/satre/formula/true.rb
|
209
|
+
- lib/satre/formula_parser.rb
|
210
|
+
- lib/satre/lexer.rb
|
211
|
+
- lib/satre/parser.rb
|
212
|
+
- lib/satre/version.rb
|
213
|
+
- satre.gemspec
|
214
|
+
homepage: http://in.tum.de
|
215
|
+
licenses:
|
216
|
+
- MIT
|
217
|
+
metadata: {}
|
218
|
+
post_install_message:
|
219
|
+
rdoc_options: []
|
220
|
+
require_paths:
|
221
|
+
- lib
|
222
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
223
|
+
requirements:
|
224
|
+
- - ">="
|
225
|
+
- !ruby/object:Gem::Version
|
226
|
+
version: '0'
|
227
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
228
|
+
requirements:
|
229
|
+
- - ">="
|
230
|
+
- !ruby/object:Gem::Version
|
231
|
+
version: '0'
|
232
|
+
requirements: []
|
233
|
+
rubyforge_project:
|
234
|
+
rubygems_version: 2.4.6
|
235
|
+
signing_key:
|
236
|
+
specification_version: 4
|
237
|
+
summary: A propositional and first order logic library
|
238
|
+
test_files: []
|
239
|
+
has_rdoc:
|