/// <summary> /// </summary> /// <param name="">util /// /// </param> public virtual void compileBinding(Rule.IRule util) { List <object> list = new List <Object>(); for (int idx = 0; idx < slots.Length; idx++) { if (slots[idx].Value is BoundParam) { hasBinding_Renamed_Field = true; list.Add(slots[idx]); BoundParam bp = (BoundParam)slots[idx].Value; Binding bd = util.getBinding(bp.VariableName); if (bd != null) { bp.rowId = bd.LeftRow; bp.column = bd.LeftIndex; } } } if (list.Count > 0) { Slot[] ary = new Slot[list.Count]; list.CopyTo(ary, 0); boundSlots = ary; } }
/// <summary> /// method creates Bindings from the bound constraint and adds them to /// the Rule. /// </summary> /// <param name="cnstr">The CNSTR.</param> /// <param name="templ">The templ.</param> /// <param name="rule">The rule.</param> /// <param name="position">The position.</param> /// <returns></returns> public virtual BaseAlpha2 compileConstraint(BoundConstraint cnstr, ITemplate templ, Rule.IRule rule, int position) { BaseAlpha2 current = null; if (rule.getBinding(cnstr.VariableName) == null) { // if the HashMap doesn't already contain the binding, we create // a new one if (cnstr.IsObjectBinding) { Binding bind = new Binding(); bind.VarName = cnstr.VariableName; bind.LeftRow = position; bind.LeftIndex = -1; bind.IsObjectVar = true; rule.addBinding(cnstr.VariableName, bind); } else { Binding bind = new Binding(); bind.VarName = cnstr.VariableName; bind.LeftRow = position; bind.LeftIndex = templ.getSlot(cnstr.Name).Id; bind.RowDeclared = position; cnstr.FirstDeclaration = true; rule.addBinding(cnstr.VariableName, bind); } } return(current); }
/// <summary> the method is responsible for compiling a TestCE pattern to a testjoin node. /// It uses the globally declared prevCE and prevJoinNode /// </summary> public virtual BaseJoin compileJoin(ICondition condition, int position, Rule.IRule rule) { TestCondition tc = (TestCondition)condition; ShellFunction fn = (ShellFunction)tc.Function; fn.lookUpFunction(ruleCompiler.Engine); IParameter[] oldpm = fn.Parameters; IParameter[] pms = new IParameter[oldpm.Length]; for (int ipm = 0; ipm < pms.Length; ipm++) { if (oldpm[ipm] is ValueParam) { pms[ipm] = ((ValueParam)oldpm[ipm]).cloneParameter(); } else if (oldpm[ipm] is BoundParam) { BoundParam bpm = (BoundParam)oldpm[ipm]; // now we need to resolve and setup the BoundParam Binding b = rule.getBinding(bpm.VariableName); BoundParam newpm = new BoundParam(b.LeftRow, b.LeftIndex, 9, bpm.ObjectBinding); newpm.VariableName = bpm.VariableName; pms[ipm] = newpm; } } BaseJoin joinNode = null; if (tc.Negated) { joinNode = new NTestNode(ruleCompiler.Engine.nextNodeId(), fn.Function, pms); } else { joinNode = new TestNode(ruleCompiler.Engine.nextNodeId(), fn.Function, pms); } ((TestNode)joinNode).lookUpFunction(ruleCompiler.Engine); return(joinNode); }
public virtual void configure(Rete engine, Rule.IRule util) { if (this.engine == null) { this.engine = engine; } for (int idx = 0; idx < params_Renamed.Length; idx++) { if (params_Renamed[idx] is BoundParam) { // we need to set the row value if the binding is a slot or fact BoundParam bp = (BoundParam)params_Renamed[idx]; Binding b1 = util.getBinding(bp.VariableName); if (b1 != null) { bp.Row = b1.LeftRow; if (b1.LeftIndex == -1) { bp.setObjectBinding(true); } } } } }
/// <summary> /// Compiles the constraint. /// </summary> /// <param name="cnstr">The CNSTR.</param> /// <param name="templ">The templ.</param> /// <param name="rule">The rule.</param> /// <param name="position">The position.</param> /// <returns></returns> public virtual BaseAlpha2 compileConstraint(PredicateConstraint cnstr, ITemplate templ, Rule.IRule rule, int position) { BaseAlpha2 current = null; // for now we expect the user to write the predicate in this // way (> ?bind value), where the binding is first. this // needs to be updated so that we look at the order of the // parameters and set the node appropriately // we only create an AlphaNode if the predicate isn't // joining 2 bindings. if (!cnstr.PredicateJoin) { if (ConversionUtils.isPredicateOperatorCode(cnstr.FunctionName)) { int oprCode = ConversionUtils.getOperatorCode(cnstr.FunctionName); Slot sl = (Slot)templ.getSlot(cnstr.Name).Clone(); Object sval = ConversionUtils.convert(sl.ValueType, cnstr.Value); sl.Value = sval; // create the alphaNode if (rule.RememberMatch) { current = new AlphaNode(engine.nextNodeId()); } else { current = new NoMemANode(engine.nextNodeId()); } current.Slot = sl; current.Operator = oprCode; current.incrementUseCount(); // we increment the node use count when when create a new // AlphaNode for the LiteralConstraint templ.getSlot(sl.Id).incrementNodeCount(); } else { // the function isn't a built in predicate function that // returns boolean true/false. We look up the function IFunction f = engine.findFunction(cnstr.FunctionName); if (f != null) { // we create the alphaNode if a function is found and // the return type is either boolean primitive or object if (f.ReturnType == Constants.BOOLEAN_PRIM_TYPE || f.ReturnType != Constants.BOOLEAN_OBJECT) { // TODO - need to implement it } else { // the function doesn't return boolean, so we have to notify // the listeners the condition is not valid CompileMessageEventArgs ce = new CompileMessageEventArgs(this, EventType.FUNCTION_INVALID); ce.Message = INVALID_FUNCTION + " " + f.ReturnType; //$NON-NLS-1$ notifyListener(ce); } } else { // we need to notify listeners the function wasn't found CompileMessageEventArgs ce = new CompileMessageEventArgs(this, EventType.FUNCTION_NOT_FOUND); ce.Message = FUNCTION_NOT_FOUND + " " + cnstr.FunctionName; notifyListener(ce); } } } Binding bind = new Binding(); bind.VarName = cnstr.VariableName; bind.LeftRow = position; bind.LeftIndex = templ.getSlot(cnstr.Name).Id; bind.RowDeclared = position; // we only Add the binding to the map if it doesn't already exist if (rule.getBinding(cnstr.VariableName) == null) { rule.addBinding(cnstr.VariableName, bind); } return(current); }