-
Notifications
You must be signed in to change notification settings - Fork 42
/
rulebook.rb
116 lines (98 loc) · 2.51 KB
/
rulebook.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# This file is part of the Ruleby project (http://ruleby.org)
#
# This application is free software; you can redistribute it and/or
# modify it under the terms of the Ruby license defined in the
# LICENSE.txt file.
#
# Copyright (c) 2007 Joe Kutner and Matt Smith. All rights reserved.
#
# * Authors: Matt Smith, Joe Kutner
#
require 'ruleby'
require 'dsl/ferrari'
require 'dsl/letigre'
require 'dsl/steel'
module Ruleby
class Rulebook
include Ruleby
def initialize(engine, &block)
@engine = engine
yield self if block_given?
end
attr_reader :engine
def assert(fact)
@engine.assert fact
end
def retract(fact)
@engine.retract fact
end
def modify(fact)
@engine.modify fact
end
def rule(*args, &block)
unless args.empty?
name = args[0].kind_of?(Symbol) ? args.shift : GeneratedTag.new
end
if args.empty?
# use steel DSL
r = Steel::RulebookHelper.new @engine
r.rule name, &block
else
i = args[0].kind_of?(Hash) ? 1 : 0
if args[i].kind_of? Array
# use ferrari DSL
r = Ferrari::RulebookHelper.new @engine
r.rule name, *args, &block
elsif args[i].kind_of? String
# use letigre DSL
r = LeTigre::RulebookHelper.new @engine, self
r.rule name, *args, &block
else
raise 'Rule format not recognized.'
end
end
end
def m
Ruleby::Ferrari::MethodBuilder.new
end
def method
m
end
def b(variable_name)
Ruleby::Ferrari::BindingBuilder.new(variable_name)
end
def binding(variable_name)
b
end
def c(&block)
return lambda(&block)
end
def condition(&block)
return lambda(&block)
end
def __eval__(x)
eval(x)
end
end
class GeneratedTag
# this counter is incremented for each UniqueTag created, and is
# appended to the end of the unique_seed in order to create a
# string that is unique for each instance of this class.
@@tag_counter = 0
# every generated tag will be prefixed with this string
@@unique_seed = 'unique_seed'
def initialize()
@@tag_counter += 1
@tag = @@unique_seed + @@tag_counter.to_s
end
attr_reader:tag_counter
attr_reader:unique_seed
attr_reader:tag
def ==(ut)
return ut && ut.kind_of?(GeneratedTag) && @tag == ut.tag
end
def to_s
return @tag.to_s
end
end
end