cycr 0.0.8 → 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.
@@ -62,7 +62,7 @@ The you can start 'irb' to see it in action:
62
62
  cyc = Cyc::Client.new
63
63
 
64
64
  # check if Dog generalizes to Animal
65
- cyc.genls? :Dog, :Animal # => T
65
+ cyc.genls? :Dog, :Animal # => true
66
66
 
67
67
  # check if Animal generalizes to Dog
68
68
  cyc.genls? :Animal, :Dog # => nil
@@ -90,15 +90,41 @@ The you can start 'irb' to see it in action:
90
90
 
91
91
  # What is more, you might even build complex subcalls, such as:
92
92
  cyc.genls? :Person, :HomoSapiens # => nil
93
- cyc.with_any_mt{|cyc| cyc.genls? :Person, :HomoSapiens} # => T
94
-
95
- # If you want to see the query which is send to Cyc, just turn on the
93
+ cyc.with_any_mt{|cyc| cyc.genls? :Person, :HomoSapiens} # => true
94
+
95
+ # The assertions are parsed, as well as Cyc symbols and variables
96
+ keys = cyc.key_predicate_rule_index :isa
97
+ # => [:POS, :NEG]
98
+ keys[0].class
99
+ # => Cyc::Symbol
100
+ cyc.symbolp keys[0]
101
+ # => true
102
+
103
+ keys1 = cyc.key_predicate_rule_index :isa, keys[0]
104
+ # => [:ComputerRunningMt, :HumanManipulationMt, :BuyingMt, ...
105
+ keys2 = cyc.key_predicate_rule_index :isa, keys[0], keys1[2]
106
+ # => [:BACKWARD]
107
+ rules = cyc.gather_predicate_rule_index :isa, keys[0], keys1[2], keys2[0]
108
+ # => [[:implies, [:and, [:objectOfPossessionTransfer, :TheBuying, ?OBJ],
109
+ [:activityObjectType, :TheSelectingAProduct, ?PREFERED]],
110
+ [:isa, ?OBJ, ?PREFERED]] : BuyingMt]
111
+ cyc.assertion_p rules[0]
112
+ # => true
113
+
114
+ rules[0].formula[1][1][2]
115
+ # => ?OBJ
116
+ rules[0].formula[1][1][2].class
117
+ # => Cyc::Variable
118
+ # the variable cannot be checked for type, since it won't be bound
119
+
120
+
121
+ # If you want to see the query which is send to Cyc, just turn on
96
122
  # debugging:
97
123
  cyc.debug = true
98
124
  cyc.genls? :Dog, :Anial
99
125
  # Send: (genls? #$Dog #$Animal)
100
126
  # Recv: 200 T
101
- # => "T"
127
+ # => true
102
128
 
103
129
  # The same way, you can turn it off:
104
130
  cyc.debug = false
@@ -108,9 +134,9 @@ The you can start 'irb' to see it in action:
108
134
 
109
135
  == LICENSE:
110
136
 
111
- (The MIT License)
137
+ (The MIT/X11 License)
112
138
 
113
- Copyright (c) 2008-2010 Aleksander Pohl
139
+ Copyright (c) 2008-2012 Aleksander Pohl
114
140
 
115
141
  Permission is hereby granted, free of charge, to any person obtaining
116
142
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,7 +1,15 @@
1
- task :default => [:install]
1
+ task :default => [:test]
2
2
 
3
3
  $gem_name = "cycr"
4
4
 
5
+ desc "Run tests"
6
+ task :test do
7
+ puts "WARNING: The test have to be run with an available Cyc server"
8
+ sh "rspec spec/parser.rb"
9
+ sh "rspec integration/assertion.rb"
10
+ sh "rspec integration/client.rb"
11
+ end
12
+
5
13
  desc "Build the gem"
6
14
  task :build do
7
15
  sh "gem build #$gem_name.gemspec"
data/changelog.txt CHANGED
@@ -1,3 +1,13 @@
1
+ 0.1.0
2
+ - Add license info to some files
3
+ - Add tests to Rakefile
4
+ - More specs for the client
5
+ - Parse variables and cyc symbols
6
+ - Move files to cyc dir, improve parenthesis check
7
+ - Better organization of tests (specs/integration separation)
8
+ - T atom interpreted as true value
9
+ 0.0.9
10
+ - raises error for raw answer if Cyc reports error
1
11
  0.0.8
2
12
  - fix documentation for Cyc::Builder
3
13
  - removal of legacy code
data/cycr.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cycr"
3
- s.version = "0.0.8"
3
+ s.version = "0.1.0"
4
4
  s.date = "#{Time.now.strftime("%Y-%m-%d")}"
5
5
  s.summary = "Ruby client for the (Open)Cyc server"
6
6
  s.email = "apohllo@o2.pl"
@@ -10,10 +10,9 @@ Gem::Specification.new do |s|
10
10
  s.has_rdoc = false
11
11
  s.authors = ['Aleksander Pohl']
12
12
  s.files = `git ls-files`.split("\n")
13
- s.test_files = Dir.glob("spec/**/*")
14
- s.rdoc_options = ["--main", "README.txt"]
13
+ s.test_files = Dir.glob("spec/**/*") + Dir.glob("integration/**/*")
14
+ s.rdoc_options = ["--main", "README.rdoc"]
15
15
  s.has_rdoc = true
16
- s.extra_rdoc_files = ["README.txt"]
16
+ s.extra_rdoc_files = ["README.rdoc"]
17
17
  s.add_development_dependency("rspec", [">= 1.2.9"])
18
18
  end
19
-
@@ -0,0 +1,35 @@
1
+ $:.unshift "lib"
2
+ require 'cycr'
3
+
4
+ describe Cyc::Assertion do
5
+ before(:all) do
6
+ @client = Cyc::Client.new()
7
+ #@client.debug = true
8
+ @assertion = @client.talk('(gather-predicate-extent-index #$minimizeExtent #$BaseKB)').
9
+ first
10
+ end
11
+
12
+ after(:all) do
13
+ @client.close
14
+ end
15
+
16
+ it "should have microtheory assigned" do
17
+ @assertion.microtheory.should_not == nil
18
+ end
19
+
20
+ it "should have formula assigned" do
21
+ @assertion.formula.should_not == nil
22
+ end
23
+
24
+ it "should allow to check its direction" do
25
+ @client.assertion_direction(@assertion).should_not == nil
26
+ end
27
+
28
+ it "should allow to check its truth" do
29
+ @client.assertion_truth(@assertion).should_not == nil
30
+ end
31
+
32
+ it "should allow to check its strength" do
33
+ @client.assertion_strength(@assertion).should_not == nil
34
+ end
35
+ end
@@ -25,12 +25,34 @@ describe Cyc::Client do
25
25
  result.should be_a_kind_of String
26
26
  end
27
27
 
28
+ it "should raise an error for raw talk if Cyc reported error" do
29
+ lambda {@client.raw_talk("(aaa)")}.should raise_error(Cyc::CycError)
30
+ end
31
+
28
32
  it "should allow to talk to server and return parsed answer" do
29
- result = @client.talk("(genls \#\$Dog)")
33
+ result = @client.talk('(genls #$Dog)')
30
34
  result.should_not == nil
31
35
  result.should respond_to :size
32
36
  end
33
37
 
38
+ it "should not allow to send a message with unbalanced parenthesis" do
39
+ lambda {@client.talk("(")}.should raise_error(Cyc::UnbalancedOpeningParenthesis)
40
+ lambda {@client.talk("())")}.should raise_error(Cyc::UnbalancedClosingParenthesis)
41
+ end
42
+
43
+ it "should parse results with assertions" do
44
+ @client.talk('(gather-predicate-extent-index #$minimizeExtent #$BaseKB)').should_not == nil
45
+ end
46
+
47
+ it "should return assertions as results if present in the result" do
48
+ @client.talk('(gather-predicate-extent-index #$minimizeExtent #$BaseKB)').
49
+ first.class.should == Cyc::Assertion
50
+ end
51
+
52
+ it "should return results with continuation" do
53
+ @client.talk('(gather-predicate-extent-index #$minimizeExtent)').size.should > 100
54
+ end
55
+
34
56
  it "should allow multiple processes to use the client" do
35
57
  parent_pid = Process.pid
36
58
  if fork
@@ -0,0 +1,36 @@
1
+ module Cyc
2
+ # Author:: Aleksander Pohl (mailto:apohllo@o2.pl)
3
+ # License:: MIT/X11 License
4
+ #
5
+ # This class represent the Cyc assertions.
6
+ class Assertion
7
+ # The logical formula of the assertion.
8
+ attr_reader :formula
9
+
10
+ # The microtheory the assertion was asserted in.
11
+ attr_reader :microtheory
12
+
13
+ # Initialize the assertion with a +formula+ and a +microtheory+.
14
+ def initialize(formula,microtheory)
15
+ @formula = formula
16
+ @microtheory = microtheory
17
+ end
18
+
19
+ # Returns the string representation of the assertion.
20
+ def to_s
21
+ "#{@formula} : #{@microtheory}"
22
+ end
23
+
24
+ # Returns the representation of the assertion understandable by Cyc.
25
+ def to_cyc(raw=false)
26
+ "(find-assertion (caar (el-to-hl '#{@formula.to_cyc(true)})) #{@microtheory.to_cyc})"
27
+ end
28
+
29
+ def ==(other)
30
+ return true if self.object_id == other.object_id
31
+ return false unless other.respond_to?(:formula)
32
+ return false unless other.respond_to?(:microtheory)
33
+ self.formula == other.formula && self.microtheory == other.microtheory
34
+ end
35
+ end
36
+ end
@@ -1,7 +1,4 @@
1
1
  module Cyc
2
- # Author:: Aleksander Pohl (mailto:apohllo@o2.pl)
3
- # License:: MIT License
4
- #
5
2
  # This class is used to capture calls to the Cyc client, to allow
6
3
  # nested calls, like
7
4
  #
@@ -1,8 +1,9 @@
1
1
  require 'net/telnet'
2
+ require 'cyc/exception'
2
3
 
3
4
  module Cyc
4
5
  # Author:: Aleksander Pohl (mailto:apohllo@o2.pl)
5
- # License:: MIT License
6
+ # License:: MIT/X11 License
6
7
  #
7
8
  # This class is the implementation of the Cyc server client.
8
9
  class Client
@@ -10,6 +11,7 @@ module Cyc
10
11
  # to standard output
11
12
  attr_accessor :debug
12
13
  attr_reader :host, :port
14
+
13
15
  # Creates new Client.
14
16
  def initialize(host="localhost",port="3601",debug=false)
15
17
  @debug = debug
@@ -34,7 +36,6 @@ module Cyc
34
36
  # If the block is given, the command is guarded by assertion, that
35
37
  # it will be performed, even if the connection was reset.
36
38
  def connection
37
- #puts "#{@pid} #{Process.pid}"
38
39
  if @conn.nil? or @pid != Process.pid
39
40
  reconnect
40
41
  end
@@ -52,6 +53,7 @@ module Cyc
52
53
 
53
54
  protected :connection, :reconnect
54
55
 
56
+ # Clears the microtheory cache.
55
57
  def clear_cache
56
58
  @mts_cache = {}
57
59
  end
@@ -62,32 +64,58 @@ module Cyc
62
64
  @conn = nil
63
65
  end
64
66
 
65
- # Sends message +msg+ directly to the Cyc server and
66
- # returns the parsed answer.
67
+ # Sends message +msg+ to the Cyc server and returns a parsed answer.
67
68
  def talk(msg, options={})
68
69
  send_message(msg)
69
70
  receive_answer(options)
70
71
  end
71
72
 
72
- # Sends message +msg+ directly to the Cyc server and
73
+ # Sends message +msg+ to the Cyc server and
73
74
  # returns the raw answer (i.e. not parsed).
74
75
  def raw_talk(msg, options={})
75
76
  send_message(msg)
76
77
  receive_raw_answer(options)
77
78
  end
78
79
 
79
- # Send the raw message.
80
- def send_message(msg)
81
- @last_message = msg
82
- puts "Send: #{msg}" if @debug
83
- connection{|c| c.puts(msg)}
80
+ # Scans the :message: to find out if the parenthesis are matched.
81
+ # Raises UnbalancedClosingParenthesis exception if there is not matched closing
82
+ # parenthesis. The message of the exception contains the string with the
83
+ # unmatched parenthesis highlighted.
84
+ # Raises UnbalancedOpeningParenthesis exception if there is not matched opening
85
+ # parenthesis.
86
+ def check_parenthesis(message)
87
+ count = 0
88
+ position = 0
89
+ message.scan(/./) do |char|
90
+ position += 1
91
+ next if char !~ /\(|\)/
92
+ count += (char == "(" ? 1 : -1)
93
+ if count < 0
94
+ raise UnbalancedClosingParenthesis.
95
+ new((position > 1 ? message[0..position-2] : "") +
96
+ "<error>)</error>" + message[position..-1])
97
+ end
98
+ end
99
+ raise UnbalancedOpeningParenthesis.new(count) if count > 0
100
+ end
101
+
102
+ # Sends a raw message to the Cyc server. The user is
103
+ # responsible for receiving the answer by calling
104
+ # +receive_answer+ or +receive_raw_answer+.
105
+ def send_message(message)
106
+ position = 0
107
+ check_parenthesis(message)
108
+ @last_message = message
109
+ puts "Send: #{message}" if @debug
110
+ connection{|c| c.puts(message)}
84
111
  end
85
112
 
113
+ # Receives and parses an answer for a message from the Cyc server.
86
114
  def receive_answer(options={})
87
115
  receive_raw_answer do |answer|
88
116
  begin
89
117
  result = @parser.parse(answer,options[:stack])
90
- rescue Parser::ContinueParsing => ex
118
+ rescue ContinueParsing => ex
91
119
  result = ex.stack
92
120
  current_result = result
93
121
  last_message = @last_message
@@ -97,20 +125,23 @@ module Cyc
97
125
  current_result = receive_answer(options) || []
98
126
  result.concat(current_result)
99
127
  end
128
+ rescue CycError => ex
129
+ puts ex.to_s
130
+ return nil
100
131
  end
101
132
  return result
102
133
  end
103
134
  end
104
135
 
105
- # Receive raw answer from server. If a +block+ is given
106
- # the answer is yield to the block, otherwise the naswer is returned.
136
+ # Receives raw answer from server. If a +block+ is given
137
+ # the answer is yield to the block, otherwise the answer is returned.
107
138
  def receive_raw_answer(options={})
108
139
  answer = connection{|c| c.waitfor(/./)}
109
140
  puts "Recv: #{answer}" if @debug
110
141
  if answer.nil?
111
- raise "Unknwon error occured. " +
142
+ raise CycError.new("Unknwon error occured. " +
112
143
  "Check the submitted query in detail:\n" +
113
- @last_message
144
+ @last_message)
114
145
  end
115
146
  while not answer =~ /\n/ do
116
147
  next_answer = connection{|c| c.waitfor(/./)}
@@ -133,16 +164,45 @@ module Cyc
133
164
  end
134
165
  else
135
166
  unless $2.nil?
136
- puts $2.sub(/^"/,"").sub(/"$/,"") + "\n" +
137
- @last_message
167
+ raise CycError.new($2.sub(/^"/,"").sub(/"$/,"") + "\n" + @last_message)
138
168
  else
139
- puts "Unknown error! #{answer}"
169
+ raise CycError.new("Unknown error! #{answer}")
140
170
  end
141
171
  nil
142
172
  end
143
173
  end
144
174
 
145
-
175
+ # This hook allows for direct call on the Client class, that
176
+ # are translated into corresponding calls for Cyc server.
177
+ #
178
+ # E.g. if users initializes the client and calls some Ruby method
179
+ # cyc = Cyc::Client.new
180
+ # cyc.genls? :Dog, :Animal
181
+ #
182
+ # He/She returns a parsed answer from the server:
183
+ # => "T"
184
+ #
185
+ # Since dashes are not allowed in Ruby method names they are replaced
186
+ # with underscores:
187
+ #
188
+ # cyc.min_genls :Dog
189
+ #
190
+ # is translated into:
191
+ #
192
+ # (min-genls #$Dog)
193
+ #
194
+ # As you see the Ruby symbols are translated into Cyc terms (not Cyc symbols!).
195
+ #
196
+ # It is also possible to nest the calls to build more complex functions:
197
+ #
198
+ # cyc.with_any_mt do |cyc|
199
+ # cyc.min_genls :Dog
200
+ # end
201
+ #
202
+ # is translated into:
203
+ #
204
+ # (with-any-mt (min-genls #$Dog))
205
+ #
146
206
  def method_missing(name,*args,&block)
147
207
  @builder.reset
148
208
  @builder.send(name,*args,&block)
@@ -1,4 +1,8 @@
1
1
  module Cyc
2
+ # Author:: Aleksander Pohl (mailto:apohllo@o2.pl)
3
+ # License:: MIT/X11 License
4
+ #
5
+ # This class is used to represent Cyc collections.
2
6
  class Collection
3
7
  attr_reader :symbol
4
8
 
@@ -0,0 +1,43 @@
1
+ module Cyc
2
+ # Author:: Aleksander Pohl (mailto:apohllo@o2.pl)
3
+ # License:: MIT/X11 License
4
+ #
5
+ # Base class for exceptions raised by the library.
6
+ class CycError < RuntimeError
7
+ end
8
+
9
+ # Error raised if the message sent to the server has
10
+ # more opening parentheses than closing parentheses.
11
+ class UnbalancedOpeningParenthesis < CycError
12
+ # The number of unbalanced opening parentheses.
13
+ attr_reader :count
14
+
15
+ # Initialize the exception with the +count+ of unbalanced
16
+ # opening parentheses.
17
+ def initialize(count)
18
+ super("There are #{count} unbalanced opening parentheses")
19
+ @count = count
20
+ end
21
+ end
22
+
23
+ # Error raised if the message sent to the server has
24
+ # more closing parentheses than opening parentheses.
25
+ class UnbalancedClosingParenthesis < CycError
26
+ end
27
+
28
+ # Exception raised by the parser if there is contents
29
+ # that cannot be parsed.
30
+ class ParserError < CycError
31
+ end
32
+
33
+ # Exception raised when there is a continuation sign,
34
+ # at the end of the parsed message.
35
+ class ContinueParsing < ParserError
36
+ attr_reader :stack
37
+
38
+ def initialize(stack)
39
+ @stack = stack
40
+ end
41
+ end
42
+
43
+ end
File without changes
@@ -1,20 +1,15 @@
1
1
  module Cyc
2
+ # Author:: Aleksander Pohl (mailto:apohllo@o2.pl)
3
+ # License:: MIT/X11 License
4
+ #
5
+ # The class used to parse the answer of the Cyc server.
2
6
  class Parser
3
- # Exception raised when there is a continuation sign,
4
- # at the end of the parsed message.
5
- class ContinueParsing < RuntimeError
6
- attr_reader :stack
7
-
8
- def initialize(stack)
9
- @stack = stack
10
- end
11
- end
12
-
13
7
  def initialize
14
8
  @lexer = SExpressionLexer.new
15
9
  end
16
10
 
17
- # Parses message received from server. +Message+ to parse.
11
+ # Parses message received from server. Accepts
12
+ # +message+ to parse and a +stack+ with a partial parse result.
18
13
  def parse(message,stack=nil)
19
14
  @lexer.scan_str(message)
20
15
  stack ||= [[]]
@@ -27,12 +22,18 @@ module Cyc
27
22
  top = stack.pop
28
23
  stack[-1].push top
29
24
  when :atom
30
- # FIXME find way to differentiate strings and atoms
31
- stack[-1] << token[1]
25
+ if token[1] == "T"
26
+ stack[-1] << true
27
+ else
28
+ # FIXME find way to differentiate strings and atoms
29
+ stack[-1] << token[1]
30
+ end
32
31
  when :cyc_symbol
32
+ stack[-1] << ::Cyc::Symbol.new(token[1][1..-1])
33
+ when :variable
34
+ stack[-1] << ::Cyc::Variable.new(token[1][1..-1])
35
+ when :term
33
36
  stack[-1] << token[1][2..-1].to_sym
34
- when :symbol
35
- stack[-1] << token[1][3..-1].to_sym
36
37
  when :string
37
38
  stack[-1] << token[1]
38
39
  when :open_as
@@ -57,9 +58,7 @@ module Cyc
57
58
  rescue ContinueParsing => ex
58
59
  raise
59
60
  rescue Exception => ex
60
- puts "Error occured while parsing message:\n#{message}"
61
- puts ex
62
- nil
61
+ raise ParserError.new("Exception #{ex} occurred when parsing message '#{message}'.")
63
62
  end
64
63
  end
65
64
  end
@@ -7,8 +7,9 @@ macro
7
7
  LINE_TERMINATOR \r|\n|\r\n
8
8
  INPUT_CHARACTER [^\r\n\"\(\):& ]
9
9
  WHITE_SPACE [\ \t\f\r\n] | \r\n
10
- SYMBOL :[^<>\r\n\"\(\):&\#\ ]+
11
- CYC_SYMBOL \#\$[a-zA-Z0-9:_-]+
10
+ CYC_SYMBOL :[^<>\r\n\"\(\):&\?\#\ ]+
11
+ VARIABLE \?[^<>\r\n\"\(\):&\?\#\ ]+
12
+ TERM \#\$[a-zA-Z0-9:_-]+
12
13
  ATOM [^\r\n\"\(\):&\ ]+
13
14
  OPEN_PAR \(
14
15
  CLOSE_PAR \)
@@ -27,13 +28,14 @@ rule
27
28
  {CLOSE_LIST_QUOTE} { [:close_quote,text] }
28
29
  {DOT}{DOT}{DOT} { [:continuation] }
29
30
  # keywords
30
- {OPEN_PAR} { [:open_par,text] }
31
- {CLOSE_PAR} { [:close_par,text] }
32
- NIL { [:nil,text] }
31
+ {OPEN_PAR} { [:open_par,text] }
32
+ {CLOSE_PAR} { [:close_par,text] }
33
+ NIL { [:nil,text] }
33
34
  # identifiers
34
- {SYMBOL} { [:symbol,text] }
35
- {CYC_SYMBOL} { [:cyc_symbol,text] }
36
- {ATOM} { [:atom,text] }
35
+ {CYC_SYMBOL} { [:cyc_symbol,text] }
36
+ {VARIABLE} { [:variable,text] }
37
+ {TERM} { [:term,text] }
38
+ {ATOM} { [:atom,text] }
37
39
  # literals
38
40
  {QUOTE} { state = :STRING; @str = ""; [:in_string] }
39
41
  {ASSERTION_SEP} { [:assertion_sep]}
@@ -73,11 +73,14 @@ class SExpressionLexer
73
73
  when (text = ss.scan(/NIL/))
74
74
  @rex_tokens.push action { [:nil,text] }
75
75
 
76
- when (text = ss.scan(/:[^<>\r\n\"\(\):&\#\ ]+/))
77
- @rex_tokens.push action { [:symbol,text] }
76
+ when (text = ss.scan(/:[^<>\r\n\"\(\):&\?\#\ ]+/))
77
+ @rex_tokens.push action { [:cyc_symbol,text] }
78
+
79
+ when (text = ss.scan(/\?[^<>\r\n\"\(\):&\?\#\ ]+/))
80
+ @rex_tokens.push action { [:variable,text] }
78
81
 
79
82
  when (text = ss.scan(/\#\$[a-zA-Z0-9:_-]+/))
80
- @rex_tokens.push action { [:cyc_symbol,text] }
83
+ @rex_tokens.push action { [:term,text] }
81
84
 
82
85
  when (text = ss.scan(/[^\r\n\"\(\):&\ ]+/))
83
86
  @rex_tokens.push action { [:atom,text] }
data/lib/cyc/symbol.rb ADDED
@@ -0,0 +1,31 @@
1
+ module Cyc
2
+ # Author:: Aleksander Pohl (mailto:apohllo@o2.pl)
3
+ # License:: MIT/X11 License
4
+ #
5
+ # This class represent the Cyc symbol.
6
+ class Symbol
7
+ # The name of the symbol.
8
+ attr_reader :name
9
+
10
+ # Initialize the symbol with its +name+.
11
+ def initialize(name)
12
+ @name = name
13
+ end
14
+
15
+ # String representation of the symbol.
16
+ def to_s
17
+ self.to_cyc
18
+ end
19
+
20
+ # Representation of the symbol understandable by Cyc.
21
+ def to_cyc(raw=false)
22
+ ":#{@name}"
23
+ end
24
+
25
+ # Two symbols are equal if they have the same name.
26
+ def ==(other)
27
+ return false if other.class != self.class
28
+ self.name == other.name
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ module Cyc
2
+ # Author:: Aleksander Pohl (mailto:apohllo@o2.pl)
3
+ # License:: MIT/X11 License
4
+ #
5
+ # This class represent the Cyc variable.
6
+ class Variable
7
+ # The name of the variable.
8
+ attr_reader :name
9
+
10
+ # Initialize the variable with its +name+.
11
+ def initialize(name)
12
+ @name = name
13
+ end
14
+
15
+ # String representation of the variable.
16
+ def to_s
17
+ self.to_cyc
18
+ end
19
+
20
+ # Representation of the variable understandable by Cyc.
21
+ def to_cyc(raw=false)
22
+ "?#{@name}"
23
+ end
24
+
25
+ # Two variables are equal if they have the same name.
26
+ def ==(other)
27
+ return false if other.class != self.class
28
+ self.name == other.name
29
+ end
30
+ end
31
+ end
data/lib/cycr.rb CHANGED
@@ -1 +1,10 @@
1
- Dir.glob(File.join(File.dirname(__FILE__), 'cycr/**.rb')).each { |f| require f }
1
+ require 'cyc/exception'
2
+ require 'cyc/assertion'
3
+ require 'cyc/builder'
4
+ require 'cyc/client'
5
+ require 'cyc/collection'
6
+ require 'cyc/extensions'
7
+ require 'cyc/parser'
8
+ require 'cyc/sexpr.rex'
9
+ require 'cyc/symbol'
10
+ require 'cyc/variable'
data/spec/parser.rb ADDED
@@ -0,0 +1,44 @@
1
+ $:.unshift "lib"
2
+ require 'cycr'
3
+
4
+ describe Cyc::Parser do
5
+ before(:all) do
6
+ @parser = Cyc::Parser.new
7
+ end
8
+
9
+ it "should parse an empty list" do
10
+ @parser.parse('()').should == []
11
+ end
12
+
13
+ it "should parse a Cyc term" do
14
+ @parser.parse('#$Dog').should == :Dog
15
+ end
16
+
17
+ it "should parse nested lists" do
18
+ @parser.parse('(())').should == [[]]
19
+ end
20
+
21
+ it "should raise continuation exception if the message contains continuation" do
22
+ lambda {@parser.parse('(#$Dog ...)')}.should raise_exception(Cyc::ContinueParsing)
23
+ end
24
+
25
+ it "should raise parse error if the message is invalid" do
26
+ lambda {@parser.parse('(#$Dog ))')}.should raise_exception(Cyc::ParserError)
27
+ end
28
+
29
+ it "should parse an assertion" do
30
+ @parser.parse('#<AS:(#$equals):#$BaseKB>').should == Cyc::Assertion.new([:equals],:BaseKB)
31
+ end
32
+
33
+ it "should parse a Cyc symbol" do
34
+ @parser.parse(':BACKWARD').should == Cyc::Symbol.new("BACKWARD")
35
+ end
36
+
37
+ it "should parse a variable" do
38
+ @parser.parse('?OBJ').should == Cyc::Variable.new("OBJ")
39
+ end
40
+
41
+ it "should parse true value" do
42
+ @parser.parse('T').should == true
43
+ end
44
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: cycr
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.8
5
+ version: 0.1.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Aleksander Pohl
@@ -10,8 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-15 00:00:00 +02:00
14
- default_executable:
13
+ date: 2012-02-13 00:00:00 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: rspec
@@ -31,32 +30,35 @@ executables: []
31
30
  extensions: []
32
31
 
33
32
  extra_rdoc_files:
34
- - README.txt
33
+ - README.rdoc
35
34
  files:
36
35
  - .gitignore
37
- - README.txt
36
+ - README.rdoc
38
37
  - Rakefile
39
38
  - changelog.txt
40
39
  - cycr.gemspec
40
+ - integration/assertion.rb
41
+ - integration/client.rb
42
+ - lib/cyc/assertion.rb
43
+ - lib/cyc/builder.rb
44
+ - lib/cyc/client.rb
45
+ - lib/cyc/collection.rb
46
+ - lib/cyc/exception.rb
47
+ - lib/cyc/extensions.rb
48
+ - lib/cyc/parser.rb
49
+ - lib/cyc/sexpr.rex
50
+ - lib/cyc/sexpr.rex.rb
51
+ - lib/cyc/symbol.rb
52
+ - lib/cyc/variable.rb
41
53
  - lib/cycr.rb
42
- - lib/cycr/assertion.rb
43
- - lib/cycr/builder.rb
44
- - lib/cycr/client.rb
45
- - lib/cycr/collection.rb
46
- - lib/cycr/extensions.rb
47
- - lib/cycr/parser.rb
48
- - lib/cycr/sexpr.rex
49
- - lib/cycr/sexpr.rex.rb
50
- - spec/assertion.rb
51
- - spec/client.rb
52
- has_rdoc: true
54
+ - spec/parser.rb
53
55
  homepage: http://github.com/apohllo/cycr
54
56
  licenses: []
55
57
 
56
58
  post_install_message:
57
59
  rdoc_options:
58
60
  - --main
59
- - README.txt
61
+ - README.rdoc
60
62
  require_paths:
61
63
  - lib
62
64
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -74,10 +76,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
76
  requirements: []
75
77
 
76
78
  rubyforge_project:
77
- rubygems_version: 1.5.2
79
+ rubygems_version: 1.8.5
78
80
  signing_key:
79
81
  specification_version: 3
80
82
  summary: Ruby client for the (Open)Cyc server
81
83
  test_files:
82
- - spec/client.rb
83
- - spec/assertion.rb
84
+ - spec/parser.rb
85
+ - integration/client.rb
86
+ - integration/assertion.rb
@@ -1,14 +0,0 @@
1
- module Cyc
2
- class Assertion
3
- attr_reader :formula, :microtheory
4
-
5
- def initialize(formula,microtheory)
6
- @formula = formula
7
- @microtheory = microtheory
8
- end
9
-
10
- def to_s
11
- "#{@formula} : #{@microtheory}"
12
- end
13
- end
14
- end
data/spec/assertion.rb DELETED
@@ -1,36 +0,0 @@
1
- $:.unshift "lib"
2
- require 'cycr'
3
-
4
- describe Cyc::Assertion do
5
- before(:all) do
6
- @client = Cyc::Client.new()
7
- #@client.debug = true
8
- end
9
-
10
- after(:all) do
11
- @client.close
12
- end
13
-
14
- it "should parse results with assertions" do
15
- @client.talk("(gather-predicate-extent-index \#$minimizeExtent \#$BaseKB)").should_not == nil
16
- end
17
-
18
- it "should return assertions as results if present in the result" do
19
- @client.talk("(gather-predicate-extent-index \#$minimizeExtent \#$BaseKB)").
20
- first.class.should == Cyc::Assertion
21
- end
22
-
23
- it "should have microtheory assigned" do
24
- @client.talk("(gather-predicate-extent-index \#$minimizeExtent \#$BaseKB)").
25
- first.microtheory.should_not == nil
26
- end
27
-
28
- it "should have formula assigned" do
29
- @client.talk("(gather-predicate-extent-index \#$minimizeExtent \#$BaseKB)").
30
- first.formula.should_not == nil
31
- end
32
-
33
- it "should return many results" do
34
- @client.talk("(gather-predicate-extent-index \#$minimizeExtent)").size.should > 100
35
- end
36
- end