porolog 0.0.2 → 0.0.3
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 +4 -4
- data/README.md +3 -1
- data/Rakefile +7 -0
- data/lib/porolog/error.rb +1 -0
- data/lib/porolog/predicate.rb +41 -10
- data/lib/porolog/scope.rb +30 -9
- data/lib/porolog.rb +9 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 536a3d026aa1bec9bfbd2ead7d114eaad2e80073b85be0719fd100308c8429fc
|
4
|
+
data.tar.gz: 0fd27e6e5e621d5490c8db18d65950fad59352b913c07a13530eccae83e5dffb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e3f448233128166af31c06aefe940654b651cdd92669c1f74fa7e0f7cf2f65ba8c2e3f52683e8c04cfe2787ea9bb851265baa6c026756e400b73717268f98dc
|
7
|
+
data.tar.gz: 1df194f8edc97a02f3f6be5420908ab5f81ac1f6f04738a493b770b91404a2f4f6352e18ec9fc4f630c050c238766d14eb1ada179992f90fbdaa0f4fc46ac33f
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# porolog
|
2
2
|
|
3
|
+
<img src="https://repository-images.githubusercontent.com/131847563/b3754100-636a-11e9-995b-20d409b992c9" width="240" height="120" align="right" />
|
4
|
+
|
3
5
|
Plain Old Ruby Objects Prolog
|
4
6
|
|
5
7
|
[](https://badge.fury.io/rb/porolog)
|
@@ -20,7 +22,7 @@ Ruby objects could be passed in and Ruby objects were passed back.
|
|
20
22
|
## Dependencies
|
21
23
|
|
22
24
|
The aim of `porolog` is to provide a logic engine with a minimal footprint.
|
23
|
-
|
25
|
+
The only dependency is Yard for documentation.
|
24
26
|
|
25
27
|
## Installation
|
26
28
|
|
data/Rakefile
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
#
|
6
6
|
|
7
7
|
require 'rake/testtask'
|
8
|
+
require 'yard'
|
8
9
|
|
9
10
|
|
10
11
|
# -- Run All Tests Task --
|
@@ -25,6 +26,11 @@ Dir['test/porolog/*_test.rb'].each do |test_file|
|
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
29
|
+
# -- Documentation Task --
|
30
|
+
YARD::Rake::YardocTask.new('doc') do |task|
|
31
|
+
task.stats_options = ['--list-undoc']
|
32
|
+
end
|
33
|
+
|
28
34
|
# -- Tasks --
|
29
35
|
task default: :test
|
30
36
|
|
@@ -33,6 +39,7 @@ task :help do
|
|
33
39
|
puts <<-EOF
|
34
40
|
Porolog is a Ruby library.
|
35
41
|
See README.md for more information.
|
42
|
+
See doc/index.html for documentation.
|
36
43
|
Run
|
37
44
|
rake -T
|
38
45
|
for other tasks.
|
data/lib/porolog/error.rb
CHANGED
data/lib/porolog/predicate.rb
CHANGED
@@ -5,25 +5,29 @@
|
|
5
5
|
# created
|
6
6
|
#
|
7
7
|
|
8
|
-
# Porolog::Predicate
|
9
|
-
#
|
10
|
-
# A Porolog::Predicate corresponds to a Prolog predicate.
|
11
|
-
# It contains rules (Porolog::Rule) and belongs to a Porolog::Scope.
|
12
|
-
# When provided with arguments, it produces a Porolog::Arguments.
|
13
|
-
#
|
14
|
-
|
15
8
|
module Porolog
|
16
9
|
|
10
|
+
# A Porolog::Predicate corresponds to a Prolog predicate.
|
11
|
+
# It contains rules (Porolog::Rule) and belongs to a Porolog::Scope.
|
12
|
+
# When provided with arguments, it produces a Porolog::Arguments.
|
13
|
+
# @author Luis Esteban
|
14
|
+
# @!attribute [r] name
|
15
|
+
# Name of the Predicate.
|
16
|
+
# @!attribute [r] rules
|
17
|
+
# Rules of the Predicate.
|
17
18
|
class Predicate
|
18
19
|
|
20
|
+
# Error class for rescuing or detecting any Predicate error.
|
19
21
|
class PredicateError < PorologError ; end
|
22
|
+
# Error class indicating an error with the name of a Predicate.
|
20
23
|
class NameError < PredicateError ; end
|
21
24
|
|
22
25
|
attr_reader :name, :rules
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
+
# Returns the current scope, or sets the current scope if a paramter is provided
|
28
|
+
# (creating the new scope if necessary).
|
29
|
+
# @param scope_name [Object] the name (or otherwise object) used to register a scope.
|
30
|
+
# @return [Porolog::Scope] the current Scope.
|
27
31
|
def self.scope(scope_name = nil)
|
28
32
|
if scope_name
|
29
33
|
@@current_scope = Scope[scope_name] || Scope.new(scope_name)
|
@@ -32,23 +36,35 @@ module Porolog
|
|
32
36
|
end
|
33
37
|
end
|
34
38
|
|
39
|
+
# Sets the current scope (creating the new scope if necessary.
|
40
|
+
# @param scope_name [Object] the name (or otherwise object) used to register a scope.
|
41
|
+
# @return [Porolog::Scope] the current Scope.
|
35
42
|
def self.scope=(scope_name)
|
36
43
|
if scope_name
|
37
44
|
@@current_scope = Scope[scope_name] || Scope.new(scope_name)
|
38
45
|
end
|
46
|
+
@@current_scope
|
39
47
|
end
|
40
48
|
|
49
|
+
# Resets the current scope to default and deregisters builtin predicates.
|
50
|
+
# @return [Porolog::Scope] the current Scope.
|
41
51
|
def self.reset
|
42
52
|
scope(:default)
|
43
53
|
@builtin_predicate_ids = {}
|
44
54
|
end
|
45
55
|
|
56
|
+
# Looks up a Predicate in the current scope by its name.
|
57
|
+
# @param name [Object] the name (or otherwise object) used to register a scope.
|
58
|
+
# @return [Porolog::Predicate] the Predicate with the given name.
|
46
59
|
def self.[](name)
|
47
60
|
@@current_scope[name]
|
48
61
|
end
|
49
62
|
|
50
63
|
reset
|
51
64
|
|
65
|
+
# Initializes a Porolog::Predicate and registers it by its name.
|
66
|
+
# @param name [#to_sym] the input object to read from
|
67
|
+
# @param scope_name the name of the scope in which to register the Predicate; if omitted, defaults to the name of the current scope
|
52
68
|
def initialize(name, scope_name = Predicate.scope.name)
|
53
69
|
@name = name.to_sym
|
54
70
|
@rules = []
|
@@ -59,23 +75,35 @@ module Porolog
|
|
59
75
|
scope[@name] = self
|
60
76
|
end
|
61
77
|
|
78
|
+
# Creates a new Predicate, or returns an existing Predicate if one already exists with the given name in the current scope.
|
79
|
+
# @return [Porolog::Predicate] a new or existing Predicate.
|
62
80
|
def self.new(*args)
|
63
81
|
name, _ = *args
|
64
82
|
scope[name.to_sym] || super
|
65
83
|
end
|
66
84
|
|
85
|
+
# Create Arguments for the Predicate.
|
86
|
+
# Provides the syntax options:
|
87
|
+
# * p.(x,y,z)
|
88
|
+
# @return [Porolog::Arguments] Arguments of the Predicate with the given arguments.
|
67
89
|
def call(*args)
|
68
90
|
Arguments.new(self,args)
|
69
91
|
end
|
70
92
|
|
93
|
+
# Create Arguments for the Predicate.
|
71
94
|
def arguments(*args)
|
72
95
|
Arguments.new(self,args)
|
73
96
|
end
|
74
97
|
|
98
|
+
# Add a Rule to the Predicate.
|
99
|
+
# @param rule [Object] the name (or otherwise object) used to register a scope.
|
100
|
+
# @return [Array<Porolog::Rule>] the Predicate's rule.
|
75
101
|
def <<(rule)
|
76
102
|
@rules << rule
|
77
103
|
end
|
78
104
|
|
105
|
+
# A pretty print String of the Predicate.
|
106
|
+
# @return [String] the Predicate as a String.
|
79
107
|
def inspect
|
80
108
|
lines = []
|
81
109
|
|
@@ -91,6 +119,9 @@ module Porolog
|
|
91
119
|
lines.join("\n")
|
92
120
|
end
|
93
121
|
|
122
|
+
# Return a builtin Predicate based on its key.
|
123
|
+
# @param key [Symbol] the name (or otherwise object) used to register a scope.
|
124
|
+
# @return [Porolog::Predicate] a Predicate with the next id based on the key.
|
94
125
|
def self.builtin(key)
|
95
126
|
@builtin_predicate_ids[key] ||= 0
|
96
127
|
@builtin_predicate_ids[key] += 1
|
data/lib/porolog/scope.rb
CHANGED
@@ -5,28 +5,32 @@
|
|
5
5
|
# created
|
6
6
|
#
|
7
7
|
|
8
|
-
# == Porolog::Scope ==
|
9
|
-
#
|
10
|
-
# A Porolog::Scope is a container for Porolog::Predicates.
|
11
|
-
# Its purpose is to allow a Ruby program to contain multiple Prolog programs
|
12
|
-
# without the Prolog programs interfering with each other.
|
13
|
-
#
|
14
|
-
|
15
8
|
module Porolog
|
16
9
|
|
10
|
+
# A Porolog::Scope is a container for Porolog::Predicates.
|
11
|
+
# Its purpose is to allow a Ruby program to contain multiple Prolog programs
|
12
|
+
# without the Prolog programs interfering with each other.
|
13
|
+
# @author Luis Esteban
|
14
|
+
# @!attribute [r] name
|
15
|
+
# Name of the Scope.
|
17
16
|
class Scope
|
18
17
|
|
18
|
+
# Error class for rescuing or detecting any Scope error.
|
19
19
|
class ScopeError < PorologError ; end
|
20
|
+
# Error class indicating a non-Predicate was assigned to a Scope.
|
20
21
|
class NotPredicateError < ScopeError ; end
|
21
22
|
|
22
23
|
attr_reader :name
|
23
24
|
|
24
|
-
|
25
|
-
|
25
|
+
# Creates a new Scope unless it already exists.
|
26
|
+
# @param name [Object] the name (or otherwise object) used to register a scope.
|
27
|
+
# @return [Porolog::Scope] new or existing Scope.
|
26
28
|
def self.new(name)
|
27
29
|
@@scopes[name] || super
|
28
30
|
end
|
29
31
|
|
32
|
+
# Initializes and registers the Scope.
|
33
|
+
# @param name [Object] the name (or otherwise object) used to register a scope.
|
30
34
|
def initialize(name)
|
31
35
|
@name = name
|
32
36
|
@predicates = {}
|
@@ -34,6 +38,8 @@ module Porolog
|
|
34
38
|
@@scopes[@name] = self
|
35
39
|
end
|
36
40
|
|
41
|
+
# Clears all scopes and re-creates the default Scope.
|
42
|
+
# @return [Porolog::Scope] the default Scope.
|
37
43
|
def self.reset
|
38
44
|
@@scopes = {}
|
39
45
|
new(:default)
|
@@ -41,23 +47,38 @@ module Porolog
|
|
41
47
|
|
42
48
|
reset
|
43
49
|
|
50
|
+
# Looks up a Scope by its name.
|
51
|
+
# @param name [Object] the name (or otherwise object) used to register a scope.
|
52
|
+
# @return [Porolog::Scope] the default Scope.
|
44
53
|
def self.[](name)
|
45
54
|
@@scopes[name]
|
46
55
|
end
|
47
56
|
|
57
|
+
# Returns the names of all registered Scopes.
|
58
|
+
# @return [Array<Symbol>,Array<Object>] the names.
|
48
59
|
def self.scopes
|
49
60
|
@@scopes.keys
|
50
61
|
end
|
51
62
|
|
63
|
+
# Looks up a Predicate in the Scope by its name.
|
64
|
+
# @param name [Object] the name (or otherwise object) used to register a scope.
|
65
|
+
# @return [Porolog::Predicate] the Predicate indicated by the name.
|
52
66
|
def [](name)
|
53
67
|
@predicates[name.to_sym]
|
54
68
|
end
|
55
69
|
|
70
|
+
# Assigns a Predicate to the Scope by its name.
|
71
|
+
# @param name [Object] the name (or otherwise object) used to register a scope.
|
72
|
+
# @param predicate [Porolog::Predicate] a Predicate to be assigned to the Scope.
|
73
|
+
# @return [Porolog::Predicate] the Predicate assigned to the Scope.
|
74
|
+
# @raise [NotPredicateError] when provided predicate is not actually a Predicate.
|
56
75
|
def []=(name,predicate)
|
57
76
|
raise NotPredicateError.new("#{predicate.inspect} is not a Predicate") unless predicate.is_a?(Predicate)
|
58
77
|
@predicates[name.to_sym] = predicate
|
59
78
|
end
|
60
79
|
|
80
|
+
# Returns the Predicates contained in the Scope.
|
81
|
+
# @return [Array<Porolog::Predicate>] Predicates assigned to the Scope.
|
61
82
|
def predicates
|
62
83
|
@predicates.values
|
63
84
|
end
|
data/lib/porolog.rb
CHANGED
@@ -7,9 +7,16 @@
|
|
7
7
|
|
8
8
|
module Porolog
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
# The most recent version of the Porolog gem.
|
11
|
+
VERSION = '0.0.3'
|
12
|
+
# The most recent date of when the VERSION changed.
|
13
|
+
VERSION_DATE = '2019-04-21'
|
12
14
|
|
15
|
+
# A convenience method to create a Predicate, along with a method
|
16
|
+
# that returns an Arguments based on the arguments provided to
|
17
|
+
# the method.
|
18
|
+
# @param names [Array<#to_sym>] names of the Predicates to create.
|
19
|
+
# @return [Porolog::Predicate|Array<Porolog::Predicate>] Predicate or Predicates created
|
13
20
|
def predicate(*names)
|
14
21
|
names = [names].flatten
|
15
22
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: porolog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luis Esteban
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-04-
|
11
|
+
date: 2019-04-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Implements a Prolog inference engine using Plain Old Ruby Objects
|
14
14
|
email:
|