/** * @param fieldTypes as inferred for the whole relation. * @return The tuple value for this record */ ITuple getTuple(Type fieldTypes) { IValue fieldValues[] = new IValue[rfields.size()]; for (int i = 0; i < rfields.size(); i++) { if (rfields.get(i) == null) { if (fieldTypes.getFieldType(i).isBool()) rfields.set(i, values.bool(false)); else if (fieldTypes.getFieldType(i).isInteger()) rfields.set(i, values.integer(0)); else if (fieldTypes.getFieldType(i).isReal()) rfields.set(i, values.real(0)); else rfields.set(i, values.string("")); } if (fieldTypes.getFieldType(i).isString() && !rfields.get(i).getType().isString()) rfields.set(i, values.string(rfields.get(i).toString())); fieldValues[i] = rfields.get(i); } return values.tuple(fieldValues); }
@Override protected <U extends IValue> Result<U> joinRelation(RelationResult that) { // Note the reverse of arguments, we need "that join this" int arity1 = that.getValue().arity(); Type eltType = getType().getElementType(); Type tupleType = that.getType().getElementType(); Type fieldTypes[] = new Type[arity1 + 1]; for (int i = 0; i < arity1; i++) { fieldTypes[i] = tupleType.getFieldType(i); } fieldTypes[arity1] = eltType; Type resultTupleType = getTypeFactory().tupleType(fieldTypes); ISetWriter writer = getValueFactory().setWriter(resultTupleType); IValue fieldValues[] = new IValue[arity1 + 1]; for (IValue relValue : that.getValue()) { for (IValue setValue : this.getValue()) { for (int i = 0; i < arity1; i++) { fieldValues[i] = ((ITuple) relValue).get(i); } fieldValues[arity1] = setValue; writer.insert(getValueFactory().tuple(fieldValues)); } } Type resultType = getTypeFactory().relTypeFromTuple(resultTupleType); return makeResult(resultType, writer.done(), ctx); }
@Override protected <U extends IValue> Result<U> addTuple(TupleResult that) { // Note reversed args TupleResult left = that; TupleResult right = this; Type leftType = left.getType(); Type rightType = right.getType(); int leftArity = leftType.getArity(); int rightArity = rightType.getArity(); int newArity = leftArity + rightArity; Type fieldTypes[] = new Type[newArity]; String fieldNames[] = new String[newArity]; IValue fieldValues[] = new IValue[newArity]; boolean consistentLabels = true; for (int i = 0; i < leftArity; i++) { fieldTypes[i] = leftType.getFieldType(i); fieldNames[i] = leftType.getFieldName(i); fieldValues[i] = left.getValue().get(i); consistentLabels = fieldNames[i] != null; } for (int i = 0; i < rightArity; i++) { fieldTypes[leftArity + i] = rightType.getFieldType(i); fieldNames[leftArity + i] = rightType.getFieldName(i); fieldValues[leftArity + i] = right.getValue().get(i); consistentLabels = fieldNames[i] != null; if (consistentLabels) { for (int j = 0; j < leftArity; j++) { if (fieldNames[j].equals(fieldNames[i])) { // duplicate field name, so degenerate to unlabeled tuple consistentLabels = false; } } } } Type newTupleType; if (consistentLabels) { newTupleType = getTypeFactory().tupleType(fieldTypes, fieldNames); } else { newTupleType = getTypeFactory().tupleType(fieldTypes); } return makeResult(newTupleType, getValueFactory().tuple(fieldValues), ctx); }
public void testIntersectISet() { ISet empty1 = vf.set(tf.tupleType(tf.integerType())); ISet empty2 = vf.set(tf.tupleType(tf.realType())); try { final ISet intersection = empty1.intersect(empty2); if (!intersection.isEmpty()) { fail("empty intersection failed"); } Type type = intersection.getType(); if (!type.getFieldType(0).isSubtypeOf(tf.numberType())) { fail("intersection should produce lub types"); } } catch (FactTypeUseException e) { fail("intersecting types which have a lub should be possible"); } try { if (!integerRelation.intersect(doubleRelation).isEmpty()) { fail("non-intersecting relations should produce empty intersections"); } ISet oneTwoThree = vf.set(integerTuples[0], integerTuples[1], integerTuples[2]); ISet threeFourFive = vf.set(integerTuples[2], integerTuples[3], integerTuples[4]); ISet result = vf.set(integerTuples[2]); if (!oneTwoThree.intersect(threeFourFive).isEqual(result)) { fail("intersection failed"); } if (!threeFourFive.intersect(oneTwoThree).isEqual(result)) { fail("intersection should be commutative"); } if (!oneTwoThree .intersect(vf.set(tf.tupleType(tf.integerType(), tf.integerType()))) .isEmpty()) { fail("intersection with empty set should produce empty"); } } catch (FactTypeUseException e) { fail("the above should all be type safe"); } }
/* (non-Javadoc) * @see org.rascalmpl.tasks.ITaskRegistry#registerProducer(org.rascalmpl.tasks.ITask) */ @Override public void registerProducer(ITask<Type, IValue, IValue> producer) { lock.lock(); try { for (Type key : producer.getKeys()) { if (key.isTuple()) { Type key1 = key.getFieldType(0); Type key2 = key.getFieldType(1); Map<Type, ITask<Type, IValue, IValue>> map = keyedProducers.get(key1); if (map == null) map = new HashMap<Type, ITask<Type, IValue, IValue>>(); map.put(key2, producer); keyedProducers.put(key1, map); } else { producers.put(key, producer); } } } finally { lock.unlock(); } }
/* (non-Javadoc) * @see org.rascalmpl.tasks.ITaskRegistry#unregisterProducer(org.rascalmpl.tasks.ITask) */ @Override public void unregisterProducer(ITask<Type, IValue, IValue> producer) { lock.lock(); try { for (Type key : producer.getKeys()) { if (key.isTuple()) { Type key1 = key.getFieldType(0); Map<Type, ITask<Type, IValue, IValue>> map = keyedProducers.get(key1); if (map != null) { for (Map.Entry<Type, ITask<Type, IValue, IValue>> entry : map.entrySet()) { if (entry.getValue().equals(producer)) map.remove(entry.getKey()); } if (map.isEmpty()) keyedProducers.remove(key1); else keyedProducers.put(key1, map); } } else { if (producers.get(key) == producer) producers.remove(key); } } } finally { lock.unlock(); } }