/** * Applies the <b>(SEND-SKIP)</b> rule to the <code>pNode</code> using the <code>pContext</code>. * * @param pContext The big step proof pContext. * @param pNode The node to apply the <b>(SEND-SKIP)</b> rule to. */ public void applySendSkip(BigStepProofContext pContext, BigStepProofNode pNode) { Send send = (Send) pNode.getExpression(); Row row = (Row) send.getE(); if (!row.isValue()) { throw new IllegalArgumentException("Can not apply SEND-SKIP"); // $NON-NLS-1$ } Expression[] rowExpressions = row.getExpressions(); Identifier methodName; if (rowExpressions[0] instanceof Method) { Method method = (Method) rowExpressions[0]; methodName = method.getId(); } else if (rowExpressions[0] instanceof CurriedMethod) { CurriedMethod curriedMethod = (CurriedMethod) rowExpressions[0]; methodName = curriedMethod.getIdentifiers()[0]; } else { throw new IllegalArgumentException("Can not apply SEND-SKIP"); // $NON-NLS-1$ } boolean definedLater = false; for (int i = 1; i < row.getExpressions().length; i++) { Expression rowChild = rowExpressions[i]; if ((rowChild instanceof Method) && (((Method) rowChild).getId().equals(send.getId()))) { definedLater = true; break; } else if ((rowChild instanceof CurriedMethod) && (((CurriedMethod) rowChild).getIdentifiers()[0].equals(send.getId()))) { definedLater = true; break; } } if ((definedLater) || (!(send.getId().equals(methodName)))) { pContext.addProofNode(pNode, new Send(row.tailRow(), send.getId())); } else { throw new IllegalArgumentException("Can not apply SEND-SKIP"); // $NON-NLS-1$ } }
/** * Applies the <b>(SEND-EXEC)</b> rule to the <code>pNode</code> using the <code>pContext</code>. * * @param pContext The big step proof pContext. * @param pNode The node to apply the <b>(SEND-EXEC)</b> rule to. */ public void applySendExec(BigStepProofContext pContext, BigStepProofNode pNode) { Send send = (Send) pNode.getExpression(); Row row = (Row) send.getE(); if (!row.isValue()) { throw new IllegalArgumentException("Can not apply SEND-EXEC"); // $NON-NLS-1$ } Expression[] rowExpressions = row.getExpressions(); Identifier methodName; Expression methodExpression; if (rowExpressions[0] instanceof Method) { Method method = (Method) rowExpressions[0]; methodExpression = method.getE(); methodName = method.getId(); } else if (rowExpressions[0] instanceof CurriedMethod) { CurriedMethod curriedMethod = (CurriedMethod) rowExpressions[0]; methodExpression = curriedMethod.getE(); Identifier[] identifiers = curriedMethod.getIdentifiers(); MonoType[] types = curriedMethod.getTypes(); for (int i = identifiers.length - 1; i > 0; i--) { methodExpression = new Lambda(identifiers[i], types[i], methodExpression); } methodName = identifiers[0]; } else { throw new IllegalArgumentException("Can not apply SEND-EXEC"); // $NON-NLS-1$ } if (!(send.getId().equals(methodName))) { throw new IllegalArgumentException("Can not apply SEND-EXEC"); // $NON-NLS-1$ } boolean definedLater = false; for (int i = 1; i < row.getExpressions().length; i++) { Expression rowChild = rowExpressions[i]; if ((rowChild instanceof Method) && (((Method) rowChild).getId().equals(send.getId()))) { definedLater = true; break; } else if ((rowChild instanceof CurriedMethod) && (((CurriedMethod) rowChild).getIdentifiers()[0].equals(send.getId()))) { definedLater = true; break; } } if (!definedLater) { pContext.addProofNode(pNode, methodExpression); } else { throw new IllegalArgumentException("Can not apply SEND-EXEC"); // $NON-NLS-1$ } }
/** * Updates the <code>node</code> to which <b>(METHOD-SUBSUME)</b> was applied previously. * * @param context the minimal typing proof context. * @param pNode the node to update according to <b>(METHOD-SUBSUME)</b>. */ public void updateMethodSubsume(MinimalTypingProofContext context, MinimalTypingProofNode pNode) { MinimalTypingExpressionProofNode node = (MinimalTypingExpressionProofNode) pNode; Row row = (Row) node.getExpression(); if (node.getChildCount() == 1 && node.getFirstChild().isFinished()) { if (row.getExpressions()[0] instanceof Method) { Method method = (Method) row.getExpressions()[0]; // generate new child node context.addProofNode(node, node.getEnvironment(), method.getE()); } else { CurriedMethod curriedMethod = (CurriedMethod) row.getExpressions()[0]; Expression curriedMethodE = curriedMethod.getE(); MonoType[] types = curriedMethod.getTypes(); Identifier[] identifiers = curriedMethod.getIdentifiers(); for (int n = identifiers.length - 1; n > 0; --n) { curriedMethodE = new Lambda(identifiers[n], types[n], curriedMethodE); } // generate new child node context.addProofNode(pNode, node.getEnvironment(), curriedMethodE); } } else if (node.getChildCount() == 2 && node.getChildAt(1).isFinished()) { // Create the tailRow and add it as Expression of a new Child Expression[] expressions = ((Row) node.getExpression()).getExpressions(); Expression[] tailRow = new Expression[expressions.length - 1]; for (int i = 1; i < expressions.length; i++) { tailRow[i - 1] = expressions[i]; } Row newRow = new Row(tailRow); // generate new child node context.addProofNode(node, node.getEnvironment(), newRow); } else if (node.getChildCount() == 3 && node.getChildAt(2).isFinished()) { Expression expression = row.getExpressions()[0]; MonoType type = node.getFirstChild().getType(); // if type is a rec type, unfold to get a object type if (type instanceof RecType) { RecType rec = (RecType) type; type = rec.getTau().substitute(rec.getTypeName(), rec); } ObjectType object = (ObjectType) type; RowType rowType = (RowType) object.getPhi(); Identifier[] identifiers = rowType.getIdentifiers(); MonoType[] types2 = rowType.getTypes(); if (expression instanceof Method) { Identifier m = (expression instanceof Method ? ((Method) expression).getId() : ((CurriedMethod) expression).getIdentifiers()[0]); MonoType tau = null; for (int i = 0; i < identifiers.length; i++) { if (m.equals(identifiers[i])) { tau = types2[i]; break; } } if (tau == null) throw new RuntimeException( MessageFormat.format( Messages.getString("MinimalTypingException.2"), m.toString())); // $NON-NLS-1$ // generate new child node context.addProofNode(node, tau, node.getChildAt(1).getType()); } else { CurriedMethod method = (CurriedMethod) expression; Identifier m = method.getIdentifiers()[0]; type = types2[rowType.getIndexOfIdentifier(m)]; MonoType[] types = method.getTypes(); MonoType childType = node.getChildAt(1).getType(); while (childType instanceof ArrowType) { childType = ((ArrowType) childType).getTau2(); } ArrowType arrow = new ArrowType(types[types.length - 1], childType); for (int i = types.length - 2; i > 1; i--) { arrow = new ArrowType(types[i], arrow); } // generate new child node context.addProofNode(node, arrow, type); } } else if (node.getChildCount() == 4 && node.getChildAt(3).isFinished()) { Expression expression = row.getExpressions()[0]; MonoType type = node.getChildAt(1).getType(); while (type instanceof ArrowType) { type = ((ArrowType) type).getTau2(); } MonoType type2 = (expression instanceof Method ? ((Method) expression).getTau() : ((CurriedMethod) expression).getTypes()[0]); if (type2 != null) // generate new child node context.addProofNode(node, type, type2); else { Identifier[] ids = new Identifier[1]; ids[0] = (expression instanceof Method ? ((Method) expression).getIdentifiers()[0] : ((CurriedMethod) expression).getIdentifiers()[0]); MonoType[] types = {node.getChildAt(1).getType()}; RowType rowType = new RowType(ids, types); RowType phi = (RowType) node.getChildAt(2).getType(); rowType = RowType.union(rowType, phi); // set the type of this node context.setNodeType(node, rowType); } } else if (node.getChildCount() == 5 && node.getChildAt(4).isFinished()) { Expression expression = row.getExpressions()[0]; Identifier[] ids = new Identifier[1]; ids[0] = (expression instanceof Method ? ((Method) expression).getIdentifiers()[0] : ((CurriedMethod) expression).getIdentifiers()[0]); MonoType[] types = {node.getChildAt(1).getType()}; RowType rowType = new RowType(ids, types); RowType phi = (RowType) node.getChildAt(2).getType(); rowType = RowType.union(rowType, phi); // set the type of this node context.setNodeType(node, rowType); } }