3131 * and bindings are implemented using a simple byte-coded interpreter.
3232 */
3333public class RETEClauseFilter implements RETESourceNode {
34-
34+
3535 /** Contains the set of byte-coded instructions and argument pointers */
3636 protected byte [] instructions ;
37-
37+
3838 /** Contains the object arguments referenced from the instructions array */
3939 protected Object [] args ;
40-
40+
4141 /** The network node to receive any created tokens */
4242 protected RETESinkNode continuation ;
43-
43+
4444 /** Instruction code: Check triple entry (arg1) against literal value (arg2). */
4545 public static final byte TESTValue = 0x01 ;
46-
46+
4747 /** Instruction code: Check literal value is a functor of name arg1 */
4848 public static final byte TESTFunctorName = 0x02 ;
49-
49+
5050 /** Instruction code: Cross match two triple entries (arg1, arg2) */
5151 public static final byte TESTIntraMatch = 0x03 ;
52-
52+
5353 /** Instruction code: Create a result environment of length arg1. */
5454 public static final byte CREATEToken = 0x04 ;
55-
55+
5656 /** Instruction code: Bind a node (arg1) to a place in the rules token (arg2). */
5757 public static final byte BIND = 0x05 ;
58-
58+
5959 /** Instruction code: Final entry - dispatch to the network. */
6060 public static final byte END = 0x06 ;
61-
61+
6262 /** Argument addressing code: triple subject */
6363 public static final byte ADDRSubject = 0x10 ;
64-
64+
6565 /** Argument addressing code: triple predicate */
6666 public static final byte ADDRPredicate = 0x20 ;
67-
67+
6868 /** Argument addressing code: triple object as a whole */
6969 public static final byte ADDRObject = 0x30 ;
70-
71- /** Argument addressing code: triple object functor node, offset in
70+
71+ /** Argument addressing code: triple object functor node, offset in
7272 * low nibble, only usable after a successful TestFunctorName. */
7373 public static final byte ADDRFunctorNode = 0x40 ;
74-
74+
7575 /**
7676 * Constructor.
7777 * @param instructions the set of byte-coded instructions and argument pointers.
@@ -81,25 +81,25 @@ public RETEClauseFilter(byte[] instructions, Object[] args) {
8181 this .instructions = instructions ;
8282 this .args = args ;
8383 }
84-
84+
8585 /**
8686 * Create a filter node from a rule clause.
8787 * Clause complexity is limited to less than 50 args in a Functor.
8888 * @param clause the rule clause
8989 * @param envLength the size of binding environment that should be created on successful matches
9090 * @param varList a list to which all clause variables will be appended
9191 */
92- public static RETEClauseFilter compile (TriplePattern clause , int envLength , List <Node > varList ) {
92+ public static RETEClauseFilter compile (TriplePattern clause , int envLength , List <Node > varList ) {
9393 byte [] instructions = new byte [300 ];
9494 byte [] bindInstructions = new byte [100 ];
9595 ArrayList <Object > args = new ArrayList <>();
96- int pc = 0 ;
96+ int pc = 0 ;
9797 int bpc = 0 ;
98-
98+
9999 // Pass 0 - prepare env creation statement
100100 bindInstructions [bpc ++] = CREATEToken ;
101101 bindInstructions [bpc ++] = (byte )envLength ;
102-
102+
103103 // Pass 1 - check literal values
104104 Node n = clause .getSubject ();
105105 if ( !n .isVariable () ) {
@@ -162,16 +162,16 @@ public static RETEClauseFilter compile(TriplePattern clause, int envLength, List
162162 varList .add (n );
163163 }
164164 bindInstructions [bpc ++] = END ;
165-
165+
166166 // Pass 4 - Pack instructions
167167 byte [] packed = new byte [pc + bpc ];
168168 System .arraycopy (instructions , 0 , packed , 0 , pc );
169169 System .arraycopy (bindInstructions , 0 , packed , pc , bpc );
170170 Object [] packedArgs = args .toArray ();
171-
171+
172172 return new RETEClauseFilter (packed , packedArgs );
173173 }
174-
174+
175175 /**
176176 * Set the continuation node for this node.
177177 */
@@ -186,50 +186,58 @@ public void setContinuation(RETESinkNode continuation) {
186186 * @param isAdd true if the triple is being added to the working set.
187187 */
188188 public void fire (Triple triple , boolean isAdd ) {
189-
189+
190190 Functor lastFunctor = null ; // bound by TESTFunctorName
191191 BindingVector env = null ; // bound by CREATEToken
192192 Node n = null ; // Temp workspace
193-
193+
194194 for (int pc = 0 ; pc < instructions .length ; ) {
195195 switch (instructions [pc ++]) {
196-
197- case TESTValue :
198- // Check triple entry (arg1) against literal value (arg2)
199- if (! getTripleValue (triple , instructions [pc ++], lastFunctor )
200- .sameValueAs (args [instructions [pc ++]])) return ;
201- break ;
202-
196+
197+ case TESTValue :
198+ // Check triple entry (arg1) against literal value (arg2)
199+ Node arg1 = getTripleValue (triple , instructions [pc ++], lastFunctor );
200+ Object obj2 = args [instructions [pc ++]];
201+ if ( ! ( obj2 instanceof Node arg2 ) )
202+ return ;
203+ if ( ! arg1 .sameValueAs (arg2 ) )
204+ return ;
205+ break ;
206+ // Was:
207+ // when sameValueAs took an Object as argument (a non-node was then false).
208+ // if (! getTripleValue(triple, instructions[pc++], lastFunctor)
209+ // .sameValueAs(args[instructions[pc++]])) return;
210+ // break;
211+
203212 case TESTFunctorName :
204213 // Check literal value is a functor of name arg1.
205- // Side effect: leaves a loop variable pointing to functor
214+ // Side effect: leaves a loop variable pointing to functor
206215 // for possible later functor argument accesses
207216 n = triple .getObject ();
208217 if ( !n .isLiteral () ) return ;
209218 if ( n .getLiteralDatatype () != FunctorDatatype .theFunctorDatatype ) return ;
210219 lastFunctor = (Functor )n .getLiteralValue ();
211220 if ( !lastFunctor .getName ().equals (args [instructions [pc ++]]) ) return ;
212221 break ;
213-
222+
214223 case CREATEToken :
215224 // Create a result environment of length arg1
216225 env = new BindingVector (new Node [instructions [pc ++]]);
217226 break ;
218-
227+
219228 case BIND :
220229 // Bind a node (arg1) to a place in the rules token (arg2)
221230 n = getTripleValue (triple , instructions [pc ++], lastFunctor );
222231 if ( !env .bind (instructions [pc ++], n ) ) return ;
223232 break ;
224-
233+
225234 case END :
226235 // Success, fire the continuation
227236 continuation .fire (env , isAdd );
228237 }
229238 }
230-
231239 }
232-
240+
233241 /**
234242 * Helpful function. Return the node from the argument triple
235243 * corresponding to the byte code address.
@@ -247,7 +255,7 @@ private Node getTripleValue(Triple triple, byte address, Functor lastFunctor) {
247255 }
248256 return null ;
249257 }
250-
258+
251259 /**
252260 * Clone this node in the network.
253261 * @param netCopy a map from RETENode to cloned instance
@@ -263,5 +271,5 @@ public RETENode clone(Map<RETENode, RETENode> netCopy, RETERuleContext context)
263271 }
264272 return clone ;
265273 }
266-
274+
267275}
0 commit comments