/** * Applies the <b>(OBJECT-WIDTH)</b> rule to the <code>node</code> using the <code>context</code>. * * @param context the minimal typing proof context. * @param pNode the minimal typing proof node. */ public void applyObjectWidth( @SuppressWarnings("unused") MinimalTypingProofContext context, MinimalTypingProofNode pNode) { MinimalTypingTypesProofNode node = (MinimalTypingTypesProofNode) pNode; boolean goOn; ObjectType type = (ObjectType) node.getType(); ObjectType type2 = (ObjectType) node.getType2(); RowType r1 = (RowType) (type).getPhi(); RowType r2 = (RowType) (type2).getPhi(); Identifier[] ids1 = r1.getIdentifiers(); Identifier[] ids2 = r2.getIdentifiers(); MonoType[] types = r1.getTypes(); MonoType[] types2 = r2.getTypes(); for (int i = 0; i < ids2.length; i++) { goOn = false; for (int j = 0; j < ids1.length; j++) { if (ids2[i].equals(ids1[j])) { if (!(types2[i].equals(types[j]))) { throw new RuntimeException(Messages.getString("SubTypingException.5")); // $NON-NLS-1$ } goOn = true; break; } } if (!goOn) { throw new RuntimeException(Messages.getString("SubTypingException.5")); // $NON-NLS-1$ } node.getSeenTypes().add(new DefaultSubType(node.getType(), node.getType2())); } }
/** * Updates the <code>node</code> to which <b>(OBJECT)</b> was applied previously. * * @param context the minimal typing proof context. * @param pNode the node to update according to <b>(OBJECT)</b>. */ public void updateObject(MinimalTypingProofContext context, MinimalTypingProofNode pNode) { MinimalTypingExpressionProofNode node = (MinimalTypingExpressionProofNode) pNode; if (node.getFirstChild().isFinished()) { MinimalTypingExpressionProofNode child = (MinimalTypingExpressionProofNode) node.getFirstChild(); TypeEnvironment environment = child.getEnvironment(); Identifier self = new Identifier("self", Identifier.Set.SELF); // $NON-NLS-1$ ObjectType objectType = (ObjectType) environment.get(self); RowType type = (RowType) objectType.getPhi(); RowType type2 = (RowType) child.getType(); try { // check type <: type2 and type2 <: type // if both true type = type2 subtypeInternal(type, type2); subtypeInternal(type2, type); } catch (Exception e) { throw new RuntimeException( MessageFormat.format( Messages.getString("MinimalTypingException.7"), node.getExpression().toString())); // $NON-NLS-1$ } ObjectType object = new ObjectType(type); // set the type of this node context.setNodeType(node, object); } }
/** * Updates the <code>node</code> to which <b>(DUPL-SUBSUME)</b> was applied previously. * * @param context the minimal typing proof context. * @param pNode the node to update according to <b>(DUPL-SUBSUME)</b>. */ public void updateDuplSubsume(MinimalTypingProofContext context, MinimalTypingProofNode pNode) { MinimalTypingExpressionProofNode node = (MinimalTypingExpressionProofNode) pNode; Duplication duplication = (Duplication) node.getExpression(); if (node.getChildCount() == 1 && node.getLastChild().isFinished()) { // generate new child node context.addProofNode(node, node.getEnvironment(), duplication.getExpressions()[0]); } else if (node.getChildCount() > 1 && node.getLastChild().isFinished()) { // check if a:tau und e:tau' tau'<: tau TypeEnvironment environment = node.getEnvironment(); Identifier id = duplication.getIdentifiers()[node.getChildCount() - 2]; MonoType tau = null; try { tau = (MonoType) environment.get(id); } catch (Exception e) { throw new RuntimeException( MessageFormat.format( Messages.getString("MinimalTypingException.9"), id.toString())); // $NON-NLS-1$ } MonoType tau2 = node.getLastChild().getType(); if (tau == null || tau2 == null) throw new RuntimeException( MessageFormat.format( Messages.getString("MinimalTypingException.2"), "self")); //$NON-NLS-1$ //$NON-NLS-2$ try { subtypeInternal(tau, tau2); subtypeInternal(tau2, tau); } catch (Exception e) { throw new RuntimeException( MessageFormat.format( Messages.getString("MinimalTypingException.2"), "self")); //$NON-NLS-1$ //$NON-NLS-2$ } } if (node.getChildCount() == duplication.getIdentifiers().length + 1) { // set the type of this node context.setNodeType(node, node.getFirstChild().getType()); // all childs added, so nothing more to do return; } // generate new child node context.addProofNode( node, node.getEnvironment(), duplication.getExpressions()[node.getChildCount() - 1]); }
/** * Applies the <b>(EMPTY)</b> rule to the * <code>node</node> using the <code>context</code>. * * @param context the minimal typing proof context. * @param pNode the minimal typing proof node. */ public void applyEmpty(MinimalTypingProofContext context, MinimalTypingProofNode pNode) { MinimalTypingExpressionProofNode node = (MinimalTypingExpressionProofNode) pNode; Row row = (Row) node.getExpression(); Expression[] expressions = row.getExpressions(); if (expressions.length == 0) { // set the type of this node context.setNodeType(node, new RowType(new Identifier[0], new MonoType[0])); return; } throw new IllegalArgumentException( Messages.getString("MinimalTypingException.8")); // $NON-NLS-1$ }
/** * Updates the <code>node</code> to which <b>(OBJECT-DEPTH)</b> was applied previously. * * @param context the minimal typing proof context. * @param pNode the node to update according to <b>(OBJECT-DEPTH)</b>. */ public void updateObjectDepth(MinimalTypingProofContext context, MinimalTypingProofNode pNode) { MinimalTypingTypesProofNode node = (MinimalTypingTypesProofNode) pNode; ObjectType type = (ObjectType) node.getType(); ObjectType type2 = (ObjectType) node.getType2(); RowType r1 = (RowType) (type).getPhi(); RowType r2 = (RowType) (type2).getPhi(); Identifier[] ids1 = r1.getIdentifiers(); MonoType[] types = r1.getTypes(); MonoType[] types2 = r2.getTypes(); if (node.isFinished() && node.getChildCount() < ids1.length) { int index = r2.getIndexOfIdentifier(ids1[node.getChildCount()]); if (index < 0) throw new RuntimeException(Messages.getString("SubTypingException.5")); // $NON-NLS-1$ context.addProofNode(node, types[node.getChildCount()], types2[index]); } }
/** * Updates the <code>node</code> to which <b>(SEND)</b> was applied previously. * * @param context the minimal typing proof context. * @param pNode the node to update according to <b>(SEND)</b>. */ public void updateSend( @SuppressWarnings("unused") MinimalTypingProofContext context, MinimalTypingProofNode pNode) { MinimalTypingExpressionProofNode node = (MinimalTypingExpressionProofNode) pNode; Send send = (Send) node.getExpression(); if (node.getFirstChild().isFinished()) { ObjectType object = (ObjectType) node.getFirstChild().getType(); RowType row = (RowType) object.getPhi(); Identifier id = send.getId(); int index = row.getIndexOfIdentifier(id); // check if identifier of send is in the row type if (index < 0) throw new RuntimeException( MessageFormat.format( Messages.getString("MinimalTypingException.6"), node.getExpression().toString())); // $NON-NLS-1$ // set the type of this node context.setNodeType(node, row.getTypes()[index]); } }
/** * Applies the <b>(OBJECT)</b> rule to the * <code>node</node> using the <code>context</code>. * * @param context the minimal typing proof context. * @param pNode the minimal typing proof node. */ public void applyObject(MinimalTypingProofContext context, MinimalTypingProofNode pNode) { MinimalTypingExpressionProofNode node = (MinimalTypingExpressionProofNode) pNode; ObjectExpr object = (ObjectExpr) node.getExpression(); MonoType tau = object.getTau(); // check if user entered type for self if (tau == null) { throw new RuntimeException( MessageFormat.format( Messages.getString("MinimalTypingException.2"), "self")); // $NON-NLS-1$ //$NON-NLS-2$ } // if type is a rec type, unfold to get a object type if (tau instanceof RecType) { RecType rec = (RecType) tau; tau = rec.getTau().substitute(rec.getTypeName(), rec); } TypeEnvironment environment = node.getEnvironment(); environment = environment.star(); // generate new child node context.addProofNode(node, environment.extend(object.getId(), tau), object.getRow()); }
/** * Applies the <b>(OBJECT-DEPTH)</b> rule to the <code>node</code> using the <code>context</code>. * * @param context the minimal typing proof context. * @param pNode the minimal typing proof node. */ public void applyObjectDepth(MinimalTypingProofContext context, MinimalTypingProofNode pNode) { MinimalTypingTypesProofNode node = (MinimalTypingTypesProofNode) pNode; ObjectType type = (ObjectType) node.getType(); ObjectType type2 = (ObjectType) node.getType2(); RowType r1 = (RowType) (type).getPhi(); RowType r2 = (RowType) (type2).getPhi(); // boolean goOn; Identifier[] ids1 = r1.getIdentifiers(); Identifier[] ids2 = r2.getIdentifiers(); MonoType[] types = r1.getTypes(); MonoType[] types2 = r2.getTypes(); int index = r2.getIndexOfIdentifier(ids1[0]); if (ids1.length == ids2.length && index > -1) { /* * for ( int i = 0; i < ids1.length; i++ ) { goOn = false; for ( int j = * 0; j < ids2.length; j++ ) { if ( ids1[i].equals ( ids2[j] ) ) { // * generate new child node context.addProofNode ( node, types[i], * types2[j] ); goOn = true; } } if ( goOn ) continue; break; } */ context.addProofNode(node, types[0], types2[index]); } else throw new RuntimeException(Messages.getString("SubTypingException.5")); // $NON-NLS-1$ node.getSeenTypes().add(new DefaultSubType(node.getType(), node.getType2())); }
/** * Applies the <b>(TRANS)</b> rule to the <code>node</code> using the <code>context</code>. * * @param context the minimal typing proof context. * @param pNode the minimal typing proof node. */ public void applyTrans(MinimalTypingProofContext context, MinimalTypingProofNode pNode) { MinimalTypingTypesProofNode node = (MinimalTypingTypesProofNode) pNode; try { ObjectType type = (ObjectType) node.getType2(); ObjectType type2 = (ObjectType) node.getType(); ArrayList<Identifier> newIds = new ArrayList<Identifier>(); ArrayList<MonoType> newTypes = new ArrayList<MonoType>(); RowType r1 = (RowType) (type).getPhi(); RowType r2 = (RowType) (type2).getPhi(); Identifier[] ids1 = r1.getIdentifiers(); Identifier[] ids2 = r2.getIdentifiers(); MonoType[] types2 = r2.getTypes(); boolean goOn; for (int i = 0; i < ids1.length; i++) { goOn = false; for (int j = 0; j < ids2.length; j++) { if (ids1[i].equals(ids2[j])) { newIds.add(ids2[j]); newTypes.add(types2[j]); goOn = true; break; } } if (goOn) continue; throw new RuntimeException(Messages.getString("SubTypingException.5")); // $NON-NLS-1$ } Identifier[] tmpIds = new Identifier[newIds.size()]; for (int i = 0; i < newIds.size(); i++) { tmpIds[i] = newIds.get(i); } MonoType[] tmpTypes = new MonoType[newTypes.size()]; for (int i = 0; i < newTypes.size(); i++) { tmpTypes[i] = newTypes.get(i); } // ObjectType newType = new ObjectType ( new RowType ( (Identifier[]) // newIds.toArray ( ),(MonoType[]) newTypes.toArray ( ) ) ); ObjectType newType = new ObjectType(new RowType(tmpIds, tmpTypes)); // generate new child node context.addProofNode(node, type2, newType); // generate new child node context.addProofNode(node, newType, type); } catch (ClassCastException e) { MonoType type = node.getType(); MonoType type2 = node.getType2(); // if both types instance of Primitive Type throw Exception if (type instanceof PrimitiveType && type2 instanceof PrimitiveType) { throw new IllegalArgumentException( Messages.getString("SubTypingException.1")); // $NON-NLS-1$ } // generate new child node context.addProofNode(node, type, type); // generate new child node context.addProofNode(node, type, type2); SubTypingProofNode parent = (SubTypingProofNode) node.getParent(); int count = 0; // check how often the trans rule was applied while (parent != null) { if (parent.getRule().toString().equals("TRANS")) { // $NON-NLS-1$ count++; } else break; parent = (SubTypingProofNode) parent.getParent(); } // if applied 15 times the trans rule throw Exception if (count >= 15) throw new RuntimeException(Messages.getString("SubTypingException.2")); // $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); } }