// Checks if one of the operands is reducible public boolean isOperandsReducible() { for (Expression o : operands) { if (o.reducible()) { return true; } else if (!IsValue.isValue(o)) { return false; } } return false; }
public Expression oneStep() { if (operator.reducible()) { return new Application(operator.oneStep(), operands); } else if (isOperandsReducible()) { return new Application(operator, reduceOperandsByOneStep()); } else if (allOperandsAreValues()) { if (operator instanceof RecFun) { RecFun operator = ((RecFun) this.operator); Expression body = operator.body; // Substitute occurrences of function name with the function body = body.substitute(operator.funVar, operator); // When we are here, we are sure that the form is // (fun ... end Op1 ... OpN) Vector<String> formals = operator.formals; for (int i = 0; i < formals.size(); i++) { body = body.substitute(formals.get(i), operands.get(i)); } return body; } else if (operator instanceof Fun) { Fun operator = ((Fun) this.operator); Expression body = operator.body; // When we are here, we are sure that the form is // (fun ... end Op1 ... OpN) Vector<String> formals = operator.formals; for (int i = 0; i < formals.size(); i++) { body = body.substitute(formals.get(i), operands.get(i)); } return body; } else { return this; } } return this; }
// Q: When is Function Application reducible? // A: When either its operands or operator is reducible public boolean reducible() { return operator.reducible() || (IsValue.isValue(operator) && isOperandsReducible()) || (IsValue.isValue(operator) && allOperandsAreValues()); }