cycr 0.0.8 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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