1 //////////////////////////////////////////////////////////////////////////////
4 // ADLib, Prop and their related set of tools and documentation are in the
5 // public domain. The author(s) of this software reserve no copyrights on
6 // the source code and any code generated using the tools. You are encouraged
7 // to use ADLib and Prop to develop software, in both academic and commercial
8 // settings, and are welcomed to incorporate any part of ADLib and Prop into
11 // Although you are under no obligation to do so, we strongly recommend that
12 // you give away all software developed using our tools.
14 // We also ask that credit be given to us when ADLib and/or Prop are used in
15 // your programs, and that this notice be preserved intact in all the source
18 // This software is still under development and we welcome(read crave for)
19 // any suggestions and help from the users.
23 //////////////////////////////////////////////////////////////////////////////
26 #include <AD/rete/gen_rete.h> // generalised Rete network
27 #include <AD/rete/alphamem.h> // alpha memory
28 #include <AD/rete/betamem.h> // beta memory
29 #include <AD/memory/boundtag.h> // generic memory manager
30 #include <AD/memory/arena.h> // free list memory manager
32 //////////////////////////////////////////////////////////////////////////////
34 //////////////////////////////////////////////////////////////////////////////
35 ReteInterp:: ReteInterp(int N
, const Node net
[], const NodeId chain
[])
36 : mem (* new BoundaryTag(4096)),
37 alpha_mem (new AlphaMem
[ N
]),
38 beta_mem (new BetaMem
[ N
]),
46 //////////////////////////////////////////////////////////////////////////////
48 //////////////////////////////////////////////////////////////////////////////
49 ReteInterp::~ReteInterp()
55 //////////////////////////////////////////////////////////////////////////////
56 // Method to return the name of the rete network.
57 //////////////////////////////////////////////////////////////////////////////
58 const char * ReteInterp::name_of() const { return "ReteInterp"; }
60 //////////////////////////////////////////////////////////////////////////////
61 // Method to clear all the database, alpha and beta memory
62 //////////////////////////////////////////////////////////////////////////////
63 void ReteInterp::clear()
65 // Since all the memory is allocated from the our memory manager,
66 // we'll simply reset of the manager and reallocate all the alpha
72 alpha_mem
= new AlphaMem
[ number_of_nodes
];
73 beta_mem
= new BetaMem
[ number_of_nodes
];
77 //////////////////////////////////////////////////////////////////////////////
78 // Method to run the inference engine until equilibrium.
79 //////////////////////////////////////////////////////////////////////////////
80 void ReteInterp::infer() { while (! is_stable()) fire(); }
82 //////////////////////////////////////////////////////////////////////////////
83 // Method to insert a fact into the right side of a node
84 //////////////////////////////////////////////////////////////////////////////
85 void ReteInterp::insert_right (NodeId n
, Fact
* fact
)
86 { const Node
& node
= network
[n
];
88 ////////////////////////////////////////////////////////////////////////
89 // Memorize fact in alpha memory and distribute the fact to the
91 ////////////////////////////////////////////////////////////////////////
93 alpha_mem
[n
].add_fact(mem
, fact
);
95 ////////////////////////////////////////////////////////////////////////
96 // Propagate fact into the sub-network
97 ////////////////////////////////////////////////////////////////////////
99 { for (int i
= node
.child
; chain_table
[i
] >= 0; i
++)
100 insert_right(chain_table
[i
], fact
);
103 ////////////////////////////////////////////////////////////////////////
104 // Compute join using linear search
105 ////////////////////////////////////////////////////////////////////////
107 { BetaMem
& b
= beta_mem
[node
.left_input
];
108 for (int i
= b
.size() - 1; i
>= 0; i
--) {
109 Fact
** token
= b
[i
];
110 token
[ node
.left_arity
] = fact
;
111 if (node
.join
== 0 || beta_test(node
.join
, token
))
112 insert_left (node
.child
, token
);
116 ////////////////////////////////////////////////////////////////////////
117 // Compute negation using linear search
118 ////////////////////////////////////////////////////////////////////////
120 { BetaMem
& b
= beta_mem
[node
.left_input
];
121 for (int i
= b
.size() - 1; i
>= 0; i
--) {
122 Fact
** token
= b
[i
];
123 token
[ node
.left_arity
] = fact
;
124 if (node
.join
== 0 || beta_test(node
.join
, token
))
125 if (b
.inc_neg(i
)) remove_left(node
.child
, token
);
129 ////////////////////////////////////////////////////////////////////////
130 // Insert token into the conflict set
131 ////////////////////////////////////////////////////////////////////////
133 activate(node
.child
, 1, &fact
); break;
138 //////////////////////////////////////////////////////////////////////////////
139 // Method to insert a fact into the left side of a node
140 //////////////////////////////////////////////////////////////////////////////
141 void ReteInterp::insert_left (NodeId n
, Fact
* token
[])
142 { const Node
& node
= network
[n
];
148 ////////////////////////////////////////////////////////////////////////
149 // Propagate fact into the sub-network
150 ////////////////////////////////////////////////////////////////////////
152 { for (int i
= node
.child
; chain_table
[i
] >= 0; i
++)
153 insert_left(chain_table
[i
], token
);
156 ////////////////////////////////////////////////////////////////////////
157 // Compute join using linear search
158 ////////////////////////////////////////////////////////////////////////
160 { AlphaMem
& a
= alpha_mem
[ node
.right_input
];
161 for (int i
= a
.size() - 1; i
>= 0; i
--) {
162 token
[ node
.left_arity
] = a
[i
];
163 if (node
.join
== 0 || beta_test(node
.join
, token
))
164 insert_left (node
.child
, token
);
168 ////////////////////////////////////////////////////////////////////////
169 // Compute negation using linear search
170 ////////////////////////////////////////////////////////////////////////
172 { AlphaMem
& a
= alpha_mem
[ node
.right_input
];
176 activate(node
.child
, node
.arity
, token
); break;
181 //////////////////////////////////////////////////////////////////////////////
182 // Method to removes a fact
183 //////////////////////////////////////////////////////////////////////////////
184 void ReteInterp::remove_right (NodeId n
, Fact
* fact
)
185 { const Node
& node
= network
[n
];
192 deactivate(node
.child
, 1, &fact
); break;
197 //////////////////////////////////////////////////////////////////////////////
198 // Method to removes a fact from the left
199 //////////////////////////////////////////////////////////////////////////////
200 void ReteInterp::remove_left (NodeId n
, Fact
* token
[])
201 { const Node
& node
= network
[n
];
208 deactivate(node
.child
, node
.arity
, token
); break;