forked from pinnacol/clipr
-
Notifications
You must be signed in to change notification settings - Fork 1
CLIPS bindings for ruby
License
thinkerbot/clipr
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
= Clipr
{CLIPS}[http://clipsrules.sourceforge.net/] bindings for Ruby.
== Description
The Clipr gem provides {FFI}[http://github.com/ffi/ffi] bindings to the CLIPS
API, and a set of classes which act as wrappers for the various CLIPS
constructs. Clipr allows callbacks to Ruby from CLIPS so that application
logic and rules logic may be kept separate.
==== Notes
{CLIPS}[http://clipsrules.sourceforge.net/] (C Language Integrated Production
System) is an open-source expert system widely used throughout the government,
industry, and academia. CLIPS is powerful and fast, but requires some study
because it uses a programming style that many people will find unusual.
Users are encouraged to consult the {extensive and accessible CLIPS
documentation}[http://clipsrules.sourceforge.net/OnlineDocs.html] for
clarification of what the Clipr constructs are intended to do, as well as a
great deal more information regarding the CLIPS API.
== Usage
=== Clipr::Api
The Api is organized into modules as described in the Advanced Programming
Guide (apg.pdf). All of the methods bind the contextual, environment-aware
forms of the API methods when possible.
require 'clipr/api'
include Clipr::Api
# create an environment
env_ptr = Environment::CreateEnvironment()
# make the function call "(> 1 2)"
obj = DataObject.new
Environment::EnvFunctionCall(env_ptr, ">", "1 2", obj)
# get the result out of the DataObject
node = Struct::SymbolHashNode.new(obj[:value])
node[:contents] # => "FALSE"
# cleanup the environment
Environment::DestroyEnvironment(env_ptr)
Direct usage of the Api requires knowledge of the CLIPS API and an attention
to detail. The rest of Clipr provides a wrapper to make the Api more
accessible.
require 'clipr'
Clipr::Env.open do |env|
env.call(">", "1 2").value # => false
end
=== Clipr
Clipr is built around the Env class which represents a CLIPS environment.
Basic usage is similar to the console:
env = Clipr::Env.new
facts = env.facts
env.assert "(animal-is duck)"
env.build "(defrule duck (animal-is duck) => (assert (sound-is quack)))"
facts.list # => ["(initial-fact)", "(animal-is duck)"]
env.run
facts.list # => ["(initial-fact)", "(animal-is duck)", "(sound-is quack)"]
env.clear
facts.list # => ["(initial-fact)"]
More complex constructs can be defined in Ruby:
class Animal < Clipr::Fact
deftemplate "animal"
slot :sound
end
Animal.construct_str # => "(deftemplate animal (slot sound))"
class Quack < Clipr::Rule
defrule "quack"
lhs.match "animal", :sound => :quack
rhs.assert "(sound-was quack)"
end
Quack.construct_str # => "(defrule quack (animal (sound quack)) => (assert (sound-was quack)))"
env.clear
env.build(Animal)
env.build(Quack)
facts.assert(:animal, {:sound => :quack})
env.run
facts.list # => ["(initial-fact)", "(animal (sound quack))", "(sound-was quack)"]
Clipr provides a callback system that lets CLIPS use blocks written in Ruby.
This is a way of writing an equivalent quack rule (albeit with a very
different CLIPS construct):
class QuackCall < Clipr::Rule
defrule "quack_call"
lhs.match "animal", :sound do |sound|
sound == :quack
end
rhs.callback do |env|
env.assert "(sound-was quack)"
end
end
QuackCall.construct_str # => "(defrule quack_call (animal (sound ?sound)) (test (ruby-call ... ?sound)) => (ruby-call ...))"
env.clear
env.build(Animal)
env.build(QuackCall)
facts.assert(:animal, {:sound => :quack})
env.run
facts.list # => ["(initial-fact)", "(animal (sound quack))", "(sound-was quack)"]
The Fact and Rule DSLs are flexible enough to define almost all CLIPS
constructs.
== Info
Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com]
License:: {MIT-Style}[link:files/License_txt.html]About
CLIPS bindings for ruby
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published
Languages
- C 97.6%
- Ruby 2.4%