1 10 package com.hp.hpl.jena.reasoner.rulesys.impl; 11 12 import com.hp.hpl.jena.graph.*; 13 import com.hp.hpl.jena.graph.impl.LiteralLabel; 14 import com.hp.hpl.jena.reasoner.rulesys.*; 15 import com.hp.hpl.jena.reasoner.*; 16 17 import java.util.*; 18 19 28 public class RETEClauseFilter implements RETESourceNode { 29 30 31 protected byte[] instructions; 32 33 34 protected Object [] args; 35 36 37 protected RETESinkNode continuation; 38 39 40 public static final byte TESTValue = 0x01; 41 42 43 public static final byte TESTFunctorName = 0x02; 44 45 46 public static final byte TESTIntraMatch = 0x03; 47 48 49 public static final byte CREATEToken = 0x04; 50 51 52 public static final byte BIND = 0x05; 53 54 55 public static final byte END = 0x06; 56 57 58 public static final byte ADDRSubject = 0x10; 59 60 61 public static final byte ADDRPredicate = 0x20; 62 63 64 public static final byte ADDRObject = 0x30; 65 66 68 public static final byte ADDRFunctorNode = 0x40; 69 70 75 public RETEClauseFilter(byte[] instructions, Object [] args) { 76 this.instructions = instructions; 77 this.args = args; 78 } 79 80 87 public static RETEClauseFilter compile(TriplePattern clause, int envLength, List varList) { 88 byte[] instructions = new byte[300]; 89 byte[] bindInstructions = new byte[100]; 90 ArrayList args = new ArrayList(); 91 int pc = 0; 92 int bpc = 0; 93 94 bindInstructions[bpc++] = CREATEToken; 96 bindInstructions[bpc++] = (byte)envLength; 97 98 Node n = clause.getSubject(); 100 if ( !n.isVariable() ) { 101 instructions[pc++] = TESTValue; 102 instructions[pc++] = ADDRSubject; 103 instructions[pc++] = (byte)args.size(); 104 args.add( n ); 105 } else { 106 bindInstructions[bpc++] = BIND; 107 bindInstructions[bpc++] = ADDRSubject; 108 bindInstructions[bpc++] = (byte)((Node_RuleVariable)n).getIndex(); 109 varList.add(n); 110 } 111 n = clause.getPredicate(); 112 if ( !n.isVariable() ) { 113 instructions[pc++] = TESTValue; 114 instructions[pc++] = ADDRPredicate; 115 instructions[pc++] = (byte)args.size(); 116 args.add( clause.getPredicate() ); 117 } else { 118 bindInstructions[bpc++] = BIND; 119 bindInstructions[bpc++] = ADDRPredicate; 120 bindInstructions[bpc++] = (byte)((Node_RuleVariable)n).getIndex(); 121 varList.add(n); 122 } 123 n = clause.getObject(); 124 if ( !n.isVariable() ) { 125 if (Functor.isFunctor(n)) { 126 Functor f = (Functor)n.getLiteral().getValue(); 128 instructions[pc++] = TESTFunctorName; 129 instructions[pc++] = (byte)args.size(); 130 args.add(f.getName()); 131 Node[] fargs = f.getArgs(); 132 for (int i = 0; i < fargs.length; i++) { 133 Node fn = fargs[i]; 134 byte addr = (byte) (ADDRFunctorNode | (0x0f & i)); 135 if ( !fn.isVariable() ) { 136 instructions[pc++] = TESTValue; 137 instructions[pc++] = addr; 138 instructions[pc++] = (byte)args.size(); 139 args.add( fn ); 140 } else { 141 bindInstructions[bpc++] = BIND; 142 bindInstructions[bpc++] = addr; 143 bindInstructions[bpc++] = (byte)((Node_RuleVariable)fn).getIndex(); 144 varList.add(fn); 145 } 146 } 147 } else { 148 instructions[pc++] = TESTValue; 149 instructions[pc++] = ADDRObject; 150 instructions[pc++] = (byte)args.size(); 151 args.add( n ); 152 } 153 } else { 154 bindInstructions[bpc++] = BIND; 155 bindInstructions[bpc++] = ADDRObject; 156 bindInstructions[bpc++] = (byte)((Node_RuleVariable)n).getIndex(); 157 varList.add(n); 158 } 159 bindInstructions[bpc++] = END; 160 161 byte[] packed = new byte[pc + bpc]; 163 System.arraycopy(instructions, 0, packed, 0, pc); 164 System.arraycopy(bindInstructions, 0, packed, pc, bpc); 165 Object [] packedArgs = args.toArray(); 166 167 return new RETEClauseFilter(packed, packedArgs); 168 } 169 170 173 public void setContinuation(RETESinkNode continuation) { 174 this.continuation = continuation; 175 } 176 177 182 public void fire(Triple triple, boolean isAdd) { 183 184 Functor lastFunctor = null; BindingVector env = null; Node n = null; 188 for (int pc = 0; pc < instructions.length; ) { 189 switch(instructions[pc++]) { 190 191 case TESTValue: 192 if (! getTripleValue(triple, instructions[pc++], lastFunctor) 194 .sameValueAs(args[instructions[pc++]])) return; 195 break; 196 197 case TESTFunctorName: 198 n = triple.getObject(); 202 if ( !n.isLiteral() ) return; 203 LiteralLabel ll = n.getLiteral(); 204 if ( ll.getDatatype() != Functor.FunctorDatatype.theFunctorDatatype) return; 205 lastFunctor = (Functor)ll.getValue(); 206 if ( !lastFunctor.getName().equals(args[instructions[pc++]]) ) return; 207 break; 208 209 case CREATEToken: 210 env = new BindingVector(new Node[instructions[pc++]]); 212 break; 213 214 case BIND: 215 n = getTripleValue(triple, instructions[pc++], lastFunctor); 217 if ( !env.bind(instructions[pc++], n) ) return; 218 break; 219 220 case END: 221 continuation.fire(env, isAdd); 223 } 224 } 225 226 } 227 228 232 private Node getTripleValue(Triple triple, byte address, Functor lastFunctor) { 233 switch (address & 0xf0) { 234 case ADDRSubject: 235 return triple.getSubject(); 236 case ADDRPredicate: 237 return triple.getPredicate(); 238 case ADDRObject: 239 return triple.getObject(); 240 case ADDRFunctorNode: 241 return lastFunctor.getArgs()[address & 0x0f]; 242 } 243 return null; 244 } 245 246 251 public RETENode clone(Map netCopy, RETERuleContext context) { 252 RETEClauseFilter clone = (RETEClauseFilter)netCopy.get(this); 253 if (clone == null) { 254 clone = new RETEClauseFilter(instructions, args); 255 clone.setContinuation((RETESinkNode)continuation.clone(netCopy, context)); 256 netCopy.put(this, clone); 257 } 258 return clone; 259 } 260 261 } 262 263 264 265 | Popular Tags |