/** * Creates an instruction for the specified mnemonic that takes one register and one functor argument. * * @param mnemonic The instruction mnemonic. * @param mode1 The addressing mode to use with the register argument. * @param reg1 The register argument. * @param fn The functor argument. * @param reg1Term The term that is assigned or associated with reg1. */ public WAMInstruction(WAMInstructionSet mnemonic, byte mode1, byte reg1, FunctorName fn, Term reg1Term) { this.mnemonic = mnemonic; this.mode1 = mode1; this.reg1 = reg1; this.fn = fn; // Record the symbol keys of the term that resulted in the creation of the instruction, and are associated // with reg1 of the instruction. symbolKeyReg1 = reg1Term.getSymbolKey(); functorNameReg1 = reg1Term.isFunctor() ? ((Functor) reg1Term).getName() : null; }
/** * Evaluates a term by invoking its {@link Term#getValue()} method (which may cause a recursive evaluation, for * example, in the case of arithmetic expressions), and checks that the result is a fully instantiated numeric * value. * * @param numeric The term to evaluate as a number. * * @return The term as a number. */ static NumericType evaluateAsNumeric(Term numeric) { // Evaluate the expression. Term expressionValue = numeric.getValue(); // Ensure that the result of evaluating the expression is a number. if (expressionValue.isVar()) { throw new IllegalStateException("instantiation_error, 'is' expects a fully instantiated term to unify against."); } if (!expressionValue.isNumber()) { throw new IllegalStateException("arithmetic_error, 'is' expectes a numeric expression to unify against."); } return (NumericType) expressionValue; } }
/** * Reports whether or not this term is an atom. A variable is an atom if it has been assigned a value which is an * atom and not otherwise. * * @return <tt>true</tt> if this variable has been assigned atomic value, <tt>false</tt> otherwise. */ public boolean isAtom() { Term t = getValue(); return (t != this) && t.isAtom(); }
/** * Gets the actual value of a term, which is a numeric type equal in value to the arithmetic operator applied to its * arguments. This method checks that both arguments produce values which are fully instantiated and numeric when * their {@link Term#getValue()} methods are invoked. * * @return A numeric type equal in value to the the arithmetic operator applied to its arguments. */ public Term getValue() { Term firstArgValue = arguments[0].getValue(); Term secondArgValue = arguments[1].getValue(); // Check that the arguments to operate on are both numeric values. if (firstArgValue.isNumber() && secondArgValue.isNumber()) { return evaluate((NumericType) firstArgValue, (NumericType) secondArgValue); } else { return this; } }
/** * Prints a variable binding in the form 'Var = value'. * * @param var The variable to print. * * @return The variable binding in the form 'Var = value'. */ public String printVariableBinding(Term var) { return var.toString(getInterner(), true, false) + " = " + var.getValue().toString(getInterner(), false, true); }
/** {@inheritDoc} */ public boolean proofStep(ResolutionState state) { Functor goalTerm = state.getGoalStack().poll().getFunctor(); Term argument = goalTerm.getArgument(0).getValue(); // Check that the argument is not a free variable. if (argument.isVar()) { throw new IllegalStateException( "instantiation_error, 'call' expects a fully instantiated term to unify against."); } // Check that the argument is callable. if (!argument.isFunctor() && !argument.isAtom()) { throw new IllegalStateException("type_error, callable expected as argument to 'call'."); } // Set up the argument to call as a new goal. state.getGoalStack().offer(state.getBuiltInTransform().apply((Functor) argument)); return true; } }
if (!left.isVar() && !right.isVar() && left.isConstant() && right.isConstant() && left.equals(right)) else if (left.isVar()) else if (right.isVar()) else if (left.isFunctor() && right.isFunctor())
(Integer) symbolTable.get(nextOutermostArg.getSymbolKey(), SymbolTableKeys.SYMKEY_ALLOCATION); if (nextOutermostArg.isVar() && !seenRegisters.contains(allocation)) symbolTable.put(nextOutermostArg.getSymbolKey(), SymbolTableKeys.SYMKEY_VARIABLE_INTRO, VarIntroduction.Put); else if (nextOutermostArg.isVar()) instructions.add(instruction); symbolTable.put(nextOutermostArg.getSymbolKey(), SymbolTableKeys.SYMKEY_VAR_LAST_ARG_FUNCTOR, null); else if (nextOutermostArg.isFunctor()) (Integer) symbolTable.get(nextArg.getSymbolKey(), SymbolTableKeys.SYMKEY_ALLOCATION); addrMode = (byte) ((allocation & 0xff00) >> 8); address = (byte) (allocation & 0xff); if (nextArg.isVar() && !seenRegisters.contains(allocation)) symbolTable.put(nextArg.getSymbolKey(), SymbolTableKeys.SYMKEY_VARIABLE_INTRO, VarIntroduction.Set); (VarIntroduction) symbolTable.get(nextArg.getSymbolKey(), SymbolTableKeys.SYMKEY_VARIABLE_INTRO); symbolTable.put(nextArg.getSymbolKey(), SymbolTableKeys.SYMKEY_VARIABLE_INTRO, null);
/** * Compares this term for structural equality with another. Two terms are structurally equal if they are the same * functor with the same arguments, or are the same unbound variable, or the bound values of the left or right * variable operands are structurally equal. Structural equality is a stronger equality than unification and unlike * unification it does not produce any variable bindings. Two unified terms will always be structurally equal. * * @param term The term to compare with this one for structural equality. * * @return <tt>true</tt> if the two terms are structurally eqaul, <tt>false</tt> otherwise. */ public boolean structuralEquals(Term term) { Term comparator = term.getValue(); Term value = getValue(); // Check if this is an unbound variable in which case the comparator must be the same variable. if (value == this) { return this.equals(comparator); } else { return value.structuralEquals(comparator); } }
/** * Determine whether a term is a functor. * * @param term The term to examine. * * @return <tt>true</tt> if the term is a functor, <tt>false</tt> if it is not. */ public boolean evaluate(Term term) { return term.isVar(); } }
if (argument.isVar()) argument.setReversable(new ContextOperator(contextSymbolTable, createTermOperator(argument, i, functor))); argument.setTermTraverser(this); queue.offer(argument); argument.setReversable(new ContextOperator(contextSymbolTable, i, createTermOperator(argument, i, functor))); argument.setTermTraverser(this); queue.offer(argument);
/** * Determine whether a term is a functor. * * @param term The term to examine. * * @return <tt>true</tt> if the term is a functor, <tt>false</tt> if it is not. */ public boolean evaluate(Term term) { return term.isFunctor(); } }
/** * Checks if a variable is appearing within the last body functor in which it occurs, and only does so within * argument position. * * @param var The variable to check. * @param body The current body functor being processed. * * @return <tt>true</tt> iff this is the last body functor that the variable appears in and does so only in argument * position. */ private boolean isLastBodyTermInArgPositionOnly(Term var, Functor body) { return body == symbolTable.get(var.getSymbolKey(), SymbolTableKeys.SYMKEY_VAR_LAST_ARG_FUNCTOR); } }
/** {@inheritDoc} */ public String toString(VariableAndFunctorInterner interner, boolean printVarName, boolean printBindings) { if (name < 0) { return "internal_built_in"; } String result = interner.getFunctorName(name); if (arity > 0) { result += "("; for (int i = 0; i < arity; i++) { Term nextArg = arguments[i]; result += nextArg.toString(interner, printVarName, printBindings) + ((i < (arity - 1)) ? ", " : ""); } result += ")"; } return result; }
/** * Reports whether or not this term is a number. * * @return <tt>false</tt> always. */ public boolean isNumber() { Term t = getValue(); return (t != this) && t.isNumber(); }
term.setTermTraverser(traverser); term.accept((TermVisitor) traverser); nextTerm.accept(visitor); term.setTermTraverser(null);
/** * Reports whether or not this term is constant (contains no variables). A variable is constant if it has been * assigned a value which is constant, and not otherwise. * * @return <tt>true</tt> if this term is constant, <tt>false</tt> otherwise. */ public boolean isConstant() { Term t = getValue(); return (t != this) && t.isConstant(); }
/** {@inheritDoc} */ public void undoOperator() { super.undoOperator(); if (PositionalTermTraverserImpl.this.contextChangeVisitor != null) { PositionalTermTraverserImpl.this.leavingContext = true; term.accept(PositionalTermTraverserImpl.this.contextChangeVisitor); PositionalTermTraverserImpl.this.leavingContext = false; } contextStack.poll(); }