diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..824792cdb
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,24 @@
+# Editor configuration, see http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+max_line_length = 80
+
+[*.sh]
+end_of_line = lf
+
+[*.java]
+indent_size = 4
+max_line_length = 120
+
+
+[*.yaml]
+indent_size = 2
+
+[*.yml]
+indent_size = 2
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 000000000..cf1b98867
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,13 @@
+# Run this command to always ignore formatting commits in `git blame`
+# git config blame.ignoreRevsFile .git-blame-ignore-revs
+
+# replaced tabs with spaces
+8efd5a7227658bbcc5b46ba647d15edf42dc0302
+
+# removed trailing whitespace
+63917fec5f518cd66ebbf56903d5167ac1c815ab
+
+# normalize indentation
+4ca06f1346d13d6e275d891de918cc6bae85c3d8
+f3301743a5e4ca39b415e4f1fa32c66a39ef37b5
+
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 5159b4edb..3261f8267 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -25,6 +25,30 @@ jobs:
name: Event File
path: ${{ github.event_path }}
+
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.head.sha }} # run it on the PR, not on the merged commit, for better line numbers
+
+ - uses: actions/setup-java@v4
+ with:
+ java-version: 11
+ distribution: 'temurin'
+ cache: 'maven'
+ - name: Run checkstyle and print errors
+ run: mvn -B checkstyle:checkstyle checkstyle:check
+ - name: Report build results
+ uses: gmazzo/publish-report-annotations@v1 # target latest major
+ if: ${{ !cancelled() }}
+ with:
+ testsSummary: off
+ reports: "target/checkstyle-result.xml"
+
+
+
test:
if: ${{ !(github.ref == 'refs/heads/main' && contains(github.event.head_commit.message, '[maven-release-plugin]')) }}
strategy:
@@ -39,7 +63,7 @@ jobs:
java-version: 11
distribution: 'temurin'
cache: 'maven'
-
+
- name: test
run: mvn -B clean test
@@ -49,7 +73,7 @@ jobs:
with:
name: Unit Test Results (${{ matrix.os }})
path: target/surefire-reports/**/*.xml
-
+
checker-framework:
if: ${{ !(github.ref == 'refs/heads/main' && contains(github.event.head_commit.message, '[maven-release-plugin]')) }}
runs-on: ubuntu-latest
diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 000000000..d950a751d
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 0300485c8..717ca578e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -164,6 +164,14 @@
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 3.5.0
+
+ checkstyle.xml
+
+
diff --git a/src/main/java/io/usethesource/vallang/IBool.java b/src/main/java/io/usethesource/vallang/IBool.java
index 1b7ac29ae..813b7359d 100644
--- a/src/main/java/io/usethesource/vallang/IBool.java
+++ b/src/main/java/io/usethesource/vallang/IBool.java
@@ -13,7 +13,7 @@
import io.usethesource.vallang.visitors.IValueVisitor;
public interface IBool extends IValue {
- @Override
+ @Override
default int getMatchFingerprint() {
if (getValue()) {
return 3569038; /* "true".hashCode() */
@@ -23,17 +23,17 @@ default int getMatchFingerprint() {
}
}
- boolean getValue();
- String getStringRepresentation();
- IBool and(IBool other);
- IBool or(IBool other);
- IBool xor(IBool other);
- IBool not();
- IBool implies(IBool other);
- IBool equivalent(IBool other);
-
- @Override
- default T accept(IValueVisitor v) throws E {
- return v.visitBoolean(this);
- }
+ boolean getValue();
+ String getStringRepresentation();
+ IBool and(IBool other);
+ IBool or(IBool other);
+ IBool xor(IBool other);
+ IBool not();
+ IBool implies(IBool other);
+ IBool equivalent(IBool other);
+
+ @Override
+ default T accept(IValueVisitor v) throws E {
+ return v.visitBoolean(this);
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/ICollection.java b/src/main/java/io/usethesource/vallang/ICollection.java
index 75b46233b..9479c144e 100644
--- a/src/main/java/io/usethesource/vallang/ICollection.java
+++ b/src/main/java/io/usethesource/vallang/ICollection.java
@@ -15,19 +15,19 @@ public interface ICollection> extends IValue, Iterable<
public default Type getElementType() {
return getType().getElementType();
}
-
+
/**
* @return true iff this container has no elements
*/
public boolean isEmpty();
-
+
/**
* @return an empty collection
*/
public default T empty() {
return writer().done();
}
-
+
/**
* @return an empty writer for this collection kind
*/
@@ -37,20 +37,20 @@ public default T empty() {
* @return the arity of the collection (the number of elements in it)
*/
public int size();
-
+
/**
* @return this collection with an IRelation interface
* @throws IllegalOperationException when the container does not contain all tuples of the same arity
*/
public IRelation asRelation();
-
+
/**
* @return true iff the collection contains only tuples of a fixed width, if any.
*/
public default boolean isRelation() {
return getElementType().isFixedWidth();
}
-
+
/**
* Computes the Cartesian product of two collections
* @param that is another collection
@@ -62,7 +62,7 @@ public default T product(T that) {
if (that.isEmpty()) {
return that;
}
-
+
for (IValue t1 : this) {
for (IValue t2 : that) {
w.appendTuple(t1, t2);
@@ -71,11 +71,11 @@ public default T product(T that) {
return w.done();
}
-
+
/**
* Computes the union of two collections, ignoring duplicates. The original duplicates in the receiver and the given container will dissappear as well.
- *
- * @param that is the other collection
+ *
+ * @param that is the other collection
* @return a collection containing both the elements of the receiver and those of the given container, without introducing duplicates.
*/
public default T union(T that) {
@@ -84,7 +84,7 @@ public default T union(T that) {
w.appendAll(that);
return w.done();
}
-
+
/**
* @return a stream of IValues from the current collection
*/
diff --git a/src/main/java/io/usethesource/vallang/IConstructor.java b/src/main/java/io/usethesource/vallang/IConstructor.java
index 13566ca61..78cff7a12 100644
--- a/src/main/java/io/usethesource/vallang/IConstructor.java
+++ b/src/main/java/io/usethesource/vallang/IConstructor.java
@@ -8,7 +8,7 @@
* Contributors:
*
* * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI
- * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
+ * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
*******************************************************************************/
package io.usethesource.vallang;
@@ -25,118 +25,118 @@
*/
public interface IConstructor extends INode {
- @Override
- default int getMatchFingerprint() {
- return getName().hashCode() + 131 * arity();
- }
-
- /**
- * @return the specific ConstructorType of this constructor
- */
- public Type getConstructorType();
-
- /**
+ @Override
+ default int getMatchFingerprint() {
+ return getName().hashCode() + 131 * arity();
+ }
+
+ /**
+ * @return the specific ConstructorType of this constructor
+ */
+ public Type getConstructorType();
+
+ /**
* @return the specific ConstructorType of this constructor but before instantiating
* type parameters. This is needed for serialization purposes.
*/
- public Type getUninstantiatedConstructorType();
-
- /**
- * Get a child from a labeled position in the tree.
- * @param label the name of the child
- * @return a value at the position indicated by the label.
- */
- public IValue get(String label);
-
- /**
- * Replace a child at a labeled position in the tree.
- * @param label the label of the position
- * @param newChild the new value of the child
- * @return a new tree node that is the same as the receiver except for
- * the fact that at the labeled position the new value has replaced the old value.
- * All keyword fields remain equal.
- *
- * @throws FactTypeUseException when this label does not exist for the given tree node, or
- * when the given value has a type that is not a sub-type of the declared type
- * of the child with this label.
- */
- public IConstructor set(String label, IValue newChild);
-
- /**
- * Find out whether this constructor has a field a given name
- * @param label name of the field
- *
- * @return true iff this constructor has this field name
- */
- public boolean has(String label);
-
- /**
- * Replace a child at an indexed position in the tree.
- * @param label the label of the position
- * @param newChild the new value of the child
- * @return a new tree node that is the same as the receiver except for
- * the fact that at the labeled position the new value has replaced the old value.
- * All keyword fields remain equal.
- *
- * @throws FactTypeUseException when the index is greater than the arity of this tree node, or
- * when the given value has a type that is not a sub-type of the declared type
- * of the child at this index.
- */
- @Override
- public IConstructor set(int index, IValue newChild);
-
- /**
- * @return a tuple type representing the children types of this node/
- */
- public Type getChildrenTypes();
-
- /*
- * (non-Javadoc)
- * @see IValue#asWithKeywordParameters()
- */
- @Override
- public IWithKeywordParameters extends IConstructor> asWithKeywordParameters();
-
- @Override
- default boolean match(IValue value) {
- if(value == this) return true;
- if(value == null) return false;
-
- if (value instanceof IConstructor){
- IConstructor otherTree = (IConstructor) value;
-
- if (getConstructorType() != otherTree.getConstructorType()) {
- return false;
- }
-
- final Iterator it1 = iterator();
- final Iterator it2 = otherTree.iterator();
-
- while (it1.hasNext() && it2.hasNext()) {
- // call to IValue.isEqual(IValue)
- if (!it1.next().match(it2.next())) {
- return false;
- }
- }
-
- return true;
- }
-
- return false;
- }
-
- @Override
+ public Type getUninstantiatedConstructorType();
+
+ /**
+ * Get a child from a labeled position in the tree.
+ * @param label the name of the child
+ * @return a value at the position indicated by the label.
+ */
+ public IValue get(String label);
+
+ /**
+ * Replace a child at a labeled position in the tree.
+ * @param label the label of the position
+ * @param newChild the new value of the child
+ * @return a new tree node that is the same as the receiver except for
+ * the fact that at the labeled position the new value has replaced the old value.
+ * All keyword fields remain equal.
+ *
+ * @throws FactTypeUseException when this label does not exist for the given tree node, or
+ * when the given value has a type that is not a sub-type of the declared type
+ * of the child with this label.
+ */
+ public IConstructor set(String label, IValue newChild);
+
+ /**
+ * Find out whether this constructor has a field a given name
+ * @param label name of the field
+ *
+ * @return true iff this constructor has this field name
+ */
+ public boolean has(String label);
+
+ /**
+ * Replace a child at an indexed position in the tree.
+ * @param label the label of the position
+ * @param newChild the new value of the child
+ * @return a new tree node that is the same as the receiver except for
+ * the fact that at the labeled position the new value has replaced the old value.
+ * All keyword fields remain equal.
+ *
+ * @throws FactTypeUseException when the index is greater than the arity of this tree node, or
+ * when the given value has a type that is not a sub-type of the declared type
+ * of the child at this index.
+ */
+ @Override
+ public IConstructor set(int index, IValue newChild);
+
+ /**
+ * @return a tuple type representing the children types of this node/
+ */
+ public Type getChildrenTypes();
+
+ /*
+ * (non-Javadoc)
+ * @see IValue#asWithKeywordParameters()
+ */
+ @Override
+ public IWithKeywordParameters extends IConstructor> asWithKeywordParameters();
+
+ @Override
+ default boolean match(IValue value) {
+ if(value == this) return true;
+ if(value == null) return false;
+
+ if (value instanceof IConstructor){
+ IConstructor otherTree = (IConstructor) value;
+
+ if (getConstructorType() != otherTree.getConstructorType()) {
+ return false;
+ }
+
+ final Iterator it1 = iterator();
+ final Iterator it2 = otherTree.iterator();
+
+ while (it1.hasNext() && it2.hasNext()) {
+ // call to IValue.isEqual(IValue)
+ if (!it1.next().match(it2.next())) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
default T accept(IValueVisitor v) throws E {
return v.visitConstructor(this);
}
-
- static boolean assertTypeCorrectConstructorApplication(Type cons, IValue[] children) {
+
+ static boolean assertTypeCorrectConstructorApplication(Type cons, IValue[] children) {
assert cons.getArity() == children.length : cons + " has arity " + cons.getArity() + " while " + children.length + " arguments are provided.";
-
+
for (int i = 0; i < cons.getArity(); i++) {
assert children[i].getType().isSubtypeOf(cons.getFieldType(i)) : "Constructing " + cons + ", expected argument " + i + " of type " + cons.getFieldType(i) + " but got " + children[i].getType();
}
-
+
return true;
}
}
diff --git a/src/main/java/io/usethesource/vallang/IDateTime.java b/src/main/java/io/usethesource/vallang/IDateTime.java
index 6a68cf701..66d16c222 100644
--- a/src/main/java/io/usethesource/vallang/IDateTime.java
+++ b/src/main/java/io/usethesource/vallang/IDateTime.java
@@ -18,121 +18,121 @@
* date, time, or datetime.
*/
public interface IDateTime extends IValue, Comparable {
- /**
- * Retrieve the date and time as an instant, defined as the number of
- * milliseconds from 1970-01-01T00:00Z. This is compatible with the
- * concept of an instant in the Java standard datetime libraries and
- * in libraries such as Joda Time.
- *
- * @return the number of milliseconds from 1970-01-01T00:00Z
- */
- public long getInstant();
-
- /**
- * Get the century. If isTime() == true, this value is undefined.
- *
- * @return the century (all but the last 2 digits of the year)
- */
- public int getCentury();
-
- /**
- * Get the year. If isTime() == true, this value is undefined.
- *
- * @return the year
- */
- public int getYear();
-
- /**
- * Get the month of year. If isTime() == true, this value is undefined.
- *
- * @return the month of year
- */
- public int getMonthOfYear();
-
- /**
- * Get the day of month. If isTime() == true, this value is undefined.
- *
- * @return the day of month
- */
- public int getDayOfMonth();
-
- /**
- * Get the hour of day value. Hours should be based on a 24 hour
- * clock, as this interface does not provide am/pm information.
- * If isDate() == true, this value is undefined.
- *
- * @return the hour of the day
- */
- public int getHourOfDay();
-
- /**
- * Get the minute of hour value. If isDate() == true, this value is
- * undefined.
- *
- * @return the minute of the hour
- */
- public int getMinuteOfHour();
-
- /**
- * Get the second of minute value. If isDate() == true, this value
- * is undefined.
- *
- * @return the second of the minute
- */
- public int getSecondOfMinute();
-
- /**
- * Get the milliseconds of second value. If isDate() == true, this
- * value is undefined.
- *
- * @return the milliseconds of the second
- */
- public int getMillisecondsOfSecond();
-
- /**
- * Get the signed numeric value representing the hour offset from
- * UTC for the time, based on the timezone assigned to the time.
- * If isDate() == true, this value is undefined.
- *
- * @return the hour offset from UTC for the timezone of the time
- */
- public int getTimezoneOffsetHours();
-
- /**
- * Get the value representing the minute offset from UTC for the time,
- * based on the timezone assigned to the time. This should be positive
- * unless getTimezoneOffsetHours() == 0.
- * If isDate() == true, this value is undefined.
- *
- * @return the minute offset from UTC for the timezone of the time
- */
- public int getTimezoneOffsetMinutes();
-
- /**
- * Indicates if this DateTime represents just a date (with no time).
- *
- * @return true if this is just a date, false otherwise
- */
- public boolean isDate();
-
- /**
- * Indicates if this DateTime represents just a time (with no date).
- *
- * @return true if this is just a time, false otherwise
- */
- public boolean isTime();
-
- /**
- * Indicates if this DateTime represents a date and time.
- *
- * @return true if this is a datetime, false otherwise
- */
- public boolean isDateTime();
-
- @Override
- default T accept(IValueVisitor v) throws E {
- return v.visitDateTime(this);
- }
-
- IString format(String format);
+ /**
+ * Retrieve the date and time as an instant, defined as the number of
+ * milliseconds from 1970-01-01T00:00Z. This is compatible with the
+ * concept of an instant in the Java standard datetime libraries and
+ * in libraries such as Joda Time.
+ *
+ * @return the number of milliseconds from 1970-01-01T00:00Z
+ */
+ public long getInstant();
+
+ /**
+ * Get the century. If isTime() == true, this value is undefined.
+ *
+ * @return the century (all but the last 2 digits of the year)
+ */
+ public int getCentury();
+
+ /**
+ * Get the year. If isTime() == true, this value is undefined.
+ *
+ * @return the year
+ */
+ public int getYear();
+
+ /**
+ * Get the month of year. If isTime() == true, this value is undefined.
+ *
+ * @return the month of year
+ */
+ public int getMonthOfYear();
+
+ /**
+ * Get the day of month. If isTime() == true, this value is undefined.
+ *
+ * @return the day of month
+ */
+ public int getDayOfMonth();
+
+ /**
+ * Get the hour of day value. Hours should be based on a 24 hour
+ * clock, as this interface does not provide am/pm information.
+ * If isDate() == true, this value is undefined.
+ *
+ * @return the hour of the day
+ */
+ public int getHourOfDay();
+
+ /**
+ * Get the minute of hour value. If isDate() == true, this value is
+ * undefined.
+ *
+ * @return the minute of the hour
+ */
+ public int getMinuteOfHour();
+
+ /**
+ * Get the second of minute value. If isDate() == true, this value
+ * is undefined.
+ *
+ * @return the second of the minute
+ */
+ public int getSecondOfMinute();
+
+ /**
+ * Get the milliseconds of second value. If isDate() == true, this
+ * value is undefined.
+ *
+ * @return the milliseconds of the second
+ */
+ public int getMillisecondsOfSecond();
+
+ /**
+ * Get the signed numeric value representing the hour offset from
+ * UTC for the time, based on the timezone assigned to the time.
+ * If isDate() == true, this value is undefined.
+ *
+ * @return the hour offset from UTC for the timezone of the time
+ */
+ public int getTimezoneOffsetHours();
+
+ /**
+ * Get the value representing the minute offset from UTC for the time,
+ * based on the timezone assigned to the time. This should be positive
+ * unless getTimezoneOffsetHours() == 0.
+ * If isDate() == true, this value is undefined.
+ *
+ * @return the minute offset from UTC for the timezone of the time
+ */
+ public int getTimezoneOffsetMinutes();
+
+ /**
+ * Indicates if this DateTime represents just a date (with no time).
+ *
+ * @return true if this is just a date, false otherwise
+ */
+ public boolean isDate();
+
+ /**
+ * Indicates if this DateTime represents just a time (with no date).
+ *
+ * @return true if this is just a time, false otherwise
+ */
+ public boolean isTime();
+
+ /**
+ * Indicates if this DateTime represents a date and time.
+ *
+ * @return true if this is a datetime, false otherwise
+ */
+ public boolean isDateTime();
+
+ @Override
+ default T accept(IValueVisitor v) throws E {
+ return v.visitDateTime(this);
+ }
+
+ IString format(String format);
}
diff --git a/src/main/java/io/usethesource/vallang/IExternalValue.java b/src/main/java/io/usethesource/vallang/IExternalValue.java
index 193641392..561e52365 100644
--- a/src/main/java/io/usethesource/vallang/IExternalValue.java
+++ b/src/main/java/io/usethesource/vallang/IExternalValue.java
@@ -31,37 +31,37 @@
* interfaces but do need to integrate with them.
*
* Note that implementations of IExternalValues are obliged to have a type that subclasses
- * ExternalType and that they all implement encodeAsConstructor.
+ * ExternalType and that they all implement encodeAsConstructor.
* If you do not do this, (de)serialization will not work.
*
* Note that NORMAL USE OF THE PDB DOES NOT REQUIRE IMPLEMENTING THIS INTERFACE
*/
public interface IExternalValue extends IValue {
- /**
+ /**
* External values must re-think their pattern match fingerprint,
* instead of returning `IValue.hashCode()` automatically.
*/
@Override
int getMatchFingerprint();
- /**
- * @return an ExternalType
- */
- @Override
- Type getType();
-
- public default IConstructor encodeAsConstructor() {
+ /**
+ * @return an ExternalType
+ */
+ @Override
+ Type getType();
+
+ public default IConstructor encodeAsConstructor() {
return new IConstructor() {
@Override
public Type getConstructorType() {
return TypeFactory.getInstance().constructor(new TypeStore(), getType(), getName());
}
-
+
@Override
public INode setChildren(IValue[] childArray) {
return this;
}
-
+
@Override
public Type getType() {
return TypeFactory.getInstance().valueType();
@@ -111,57 +111,57 @@ public boolean mayHaveKeywordParameters() {
public INode replace(int first, int second, int end, IList repl) {
return this;
}
-
+
@Override
public int arity() {
return 0;
}
-
+
@Override
public IValue get(int i) {
throw new IndexOutOfBoundsException(Integer.toString(i));
}
-
+
@Override
public Iterable getChildren() {
return Collections.emptyList();
}
-
-
+
+
@Override
public Iterator iterator() {
return Collections.emptyIterator();
}
-
+
@Override
public IWithKeywordParameters asWithKeywordParameters() {
- return new AbstractDefaultWithKeywordParameters(this, AbstractSpecialisedImmutableMap.mapOf()) {
- @Override
- protected IConstructor wrap(IConstructor content, io.usethesource.capsule.Map.Immutable parameters) {
- return new ConstructorWithKeywordParametersFacade(content, parameters);
- }
-
- @Override
- public boolean hasParameters() {
- return false;
- }
-
- @Override
- public java.util.Set getParameterNames() {
- return Collections.emptySet();
- }
-
- @Override
- public Map getParameters() {
- return Collections.unmodifiableMap(parameters);
- }
- };
- }
- };
+ return new AbstractDefaultWithKeywordParameters(this, AbstractSpecialisedImmutableMap.mapOf()) {
+ @Override
+ protected IConstructor wrap(IConstructor content, io.usethesource.capsule.Map.Immutable parameters) {
+ return new ConstructorWithKeywordParametersFacade(content, parameters);
+ }
+
+ @Override
+ public boolean hasParameters() {
+ return false;
+ }
+
+ @Override
+ public java.util.Set getParameterNames() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Map getParameters() {
+ return Collections.unmodifiableMap(parameters);
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ default T accept(IValueVisitor v) throws E {
+ return v.visitExternal(this);
}
-
- @Override
- default T accept(IValueVisitor v) throws E {
- return v.visitExternal(this);
- }
}
diff --git a/src/main/java/io/usethesource/vallang/IInteger.java b/src/main/java/io/usethesource/vallang/IInteger.java
index 5fd7e6d63..66e9bb212 100644
--- a/src/main/java/io/usethesource/vallang/IInteger.java
+++ b/src/main/java/io/usethesource/vallang/IInteger.java
@@ -25,24 +25,24 @@ default int getMatchFingerprint() {
}
}
- /**
- * @return this + other;
- */
+ /**
+ * @return this + other;
+ */
@Override
public IInteger add(IInteger other);
-
+
/**
* @return this - other;
*/
@Override
public IInteger subtract(IInteger other);
-
+
/**
* @return this * other;
*/
@Override
public IInteger multiply(IInteger other);
-
+
/**
* @return this / other;
*/
@@ -58,93 +58,93 @@ default int getMatchFingerprint() {
* This may be a negative number.
*/
public IInteger remainder(IInteger other);
-
+
/**
* @return -1 * this;
*/
@Override
public IInteger negate();
-
+
/**
* @return this % other, which is always a positive IInteger
*/
public IInteger mod(IInteger other);
-
+
/**
* @return an IReal that is equal to this IInteger
*/
@Override
public IReal toReal(int precision);
-
+
/**
* @return true iff this < other
*/
@Override
public IBool less(IInteger other);
-
+
/**
* @return true iff this > other
*/
@Override
public IBool greater(IInteger other);
-
+
/**
* @return true iff this <= other
*/
@Override
public IBool lessEqual(IInteger other);
-
+
/**
* @return true iff this >= other
*/
@Override
public IBool greaterEqual(IInteger other);
-
+
/**
* @return the value of the IInteger represent as a string of decimal numbers in ASCII encoding.
*/
public String getStringRepresentation();
-
+
/**
* @return the two's complement representation of this integer in the minimum
- * amount of required bytes and in big-endian order.
+ * amount of required bytes and in big-endian order.
*/
public byte[] getTwosComplementRepresentation();
-
+
/**
* Converts this IInteger to an int. If it
* does not fit an ArithmeticException is thrown.
- *
+ *
* Use doubleValue() instead, if you are not sure if the
* result will fit in an int.
- *
+ *
*/
public int intValue() throws ArithmeticException;
-
+
/**
- * Converts this IInteger to a long.
+ * Converts this IInteger to a long.
* If it does not fit an ArithmeticException is thrown.
*
* Use doubleValue() instead, if you are not sure if the
* result will fit in a long.
- *
+ *
*/
public long longValue() throws ArithmeticException;
-
+
/**
- * Converts this IInteger to a double.
+ * Converts this IInteger to a double.
* The conversion may lose precision, and will yield +/- Inf
* if the magnitude is too large for a double.
*/
public double doubleValue();
-
+
/**
* Compares two integers
* @param other
* @return -1 if receiver is less than other, 0 is receiver is equal, 1 if receiver is larger
*/
public int compare(IInteger other);
-
+
/**
* @return return -1, 0 or 1 iff this integer is less than, equal to or greater than zero.
*/
@@ -156,9 +156,9 @@ default int getMatchFingerprint() {
*/
@Override
public IInteger abs();
-
- @Override
- public default T accept(IValueVisitor v) throws E {
- return v.visitInteger(this);
- }
+
+ @Override
+ public default T accept(IValueVisitor v) throws E {
+ return v.visitInteger(this);
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/IList.java b/src/main/java/io/usethesource/vallang/IList.java
index 7335d7554..36c88d22b 100644
--- a/src/main/java/io/usethesource/vallang/IList.java
+++ b/src/main/java/io/usethesource/vallang/IList.java
@@ -22,7 +22,7 @@
import io.usethesource.vallang.visitors.IValueVisitor;
public interface IList extends ICollection {
-
+
@Override
default int getMatchFingerprint() {
return 3322014; // "list".hashCode()
@@ -35,12 +35,12 @@ default int getMatchFingerprint() {
public default int size() {
return length();
}
-
+
/**
* Return the length of the list == size();
*/
public int length();
-
+
/**
* @return a new list with all elements in reverse order
*/
@@ -51,7 +51,7 @@ public default IList reverse() {
}
return w.done();
}
-
+
/**
* @param rand the random generator to use for the shuffling. If the same seed is set, the same shuffling should happen.
* @return a new list with all the elements randomly shuffled.
@@ -66,16 +66,16 @@ public default IList shuffle(Random rand) {
}
return w.done();
}
-
+
/**
* @return an IListWriter for the current list implementation
*/
@Override
public IListWriter writer();
-
+
/**
* Appends an element to the end of the list
- *
+ *
* @param e the new element
* @return a new list with the element at the end
*/
@@ -86,7 +86,7 @@ default IList append(IValue e) {
return w.done();
}
-
+
/**
* Inserts an element in front of the list
* @param e the new element
@@ -99,11 +99,11 @@ default IList insert(IValue e) {
return w.done();
}
-
+
/**
* Concatenates this list with another
* @param o another list
- * @return a concatenated list with the elements of the
+ * @return a concatenated list with the elements of the
* receiver before the elements of o.
*/
default IList concat(IList o) {
@@ -112,7 +112,7 @@ default IList concat(IList o) {
w.appendAll(o);
return w.done();
}
-
+
/**
* Replaces the value of the ith element in the list with a new value
* @param i index to replace a value at.
@@ -127,7 +127,7 @@ public default IList put(int i, IValue e) {
w.replaceAt(i, e);
return w.done();
}
-
+
/**
* Replaces the value of the elements first, second ... end in the list with the elements in the list r
* Expected:
@@ -210,19 +210,19 @@ public default IList replace(int first, int second, int end, IList repl) {
return result.done();
}
-
+
/**
* Return the ith element of the list.
- *
+ *
* @param i
* @return the ith element of the list
* @throws IndexOutOfBoundsException when i < 0 or i >= IList.length
*/
public IValue get(int i) throws IndexOutOfBoundsException;
-
+
/**
* Compute a sublist.
- *
+ *
* @param offset inclusive start index of the sublist
* @param length number of elements in the resulting list
* @return a new list that contains this[offset] until this[offset+length-1].
@@ -231,19 +231,19 @@ default IList sublist(int offset, int length) {
if (offset < 0 || length < 0 || offset + length > length()) {
throw new IndexOutOfBoundsException();
}
-
+
IListWriter w = writer();
for (int i = offset; i < offset + length; i++) {
w.append(get(i));
}
return w.done();
}
-
+
/**
* @return true iff the list is non-empty
*/
public boolean isEmpty();
-
+
/**
* @param e
* @return true iff e is an element of the list
@@ -256,7 +256,7 @@ public default boolean contains(IValue e) {
}
return false;
}
-
+
/**
* Removes the first occurrence of an element, i.e. the
* element with the lowest index that is present in the list,
@@ -268,7 +268,7 @@ public default IList delete(IValue v) {
IListWriter w = writer();
boolean deleted = false;
-
+
for (IValue e : this) {
if (!deleted && e.equals(v)) {
deleted = true; // skip first occurrence
@@ -281,7 +281,7 @@ public default IList delete(IValue v) {
/**
* Removes the element at index i
.
- *
+ *
* @param i
* @return a new list with one element removed.
*/
@@ -290,7 +290,7 @@ public default IList delete(int index) {
int currentIndex = 0;
boolean deleted = false;
-
+
for (Iterator iterator = iterator(); iterator.hasNext(); currentIndex++) {
IValue e = iterator.next();
@@ -302,10 +302,10 @@ public default IList delete(int index) {
}
return w.done();
}
-
+
/**
* Carthesian product of two lists.
- *
+ *
* @param l
* @return a new list relation containing the product
*/
@@ -321,7 +321,7 @@ public default IList product(IList l) {
return w.done();
}
-
+
/**
* Intersection of two lists
* @param l
@@ -338,7 +338,7 @@ public default IList intersect(IList l) {
return w.done();
}
-
+
/**
* Difference of two lists
* @param l
@@ -355,13 +355,13 @@ public default IList subtract(IList l) {
}
return w.done();
}
-
+
@Override
public default boolean match(IValue other) {
if (other == this) {
return true;
}
-
+
if (other == null) {
return false;
}
@@ -387,7 +387,7 @@ public default boolean match(IValue other) {
return false;
}
-
+
/**
* @return true if this list is a sublist of list l
*/
@@ -412,7 +412,7 @@ public default boolean defaultEquals(@Nullable Object other) {
if (other == this) {
return true;
}
-
+
if (other == null) {
return false;
}
@@ -423,7 +423,7 @@ public default boolean defaultEquals(@Nullable Object other) {
if (isEmpty() && list2.isEmpty()) {
return true;
}
-
+
if (getType() != list2.getType())
return false;
@@ -449,7 +449,7 @@ public default boolean defaultEquals(@Nullable Object other) {
return false;
}
-
+
default int defaultHashCode() {
int hash = 0;
@@ -459,18 +459,18 @@ default int defaultHashCode() {
return hash;
}
-
+
@Override
default T accept(IValueVisitor v) throws E {
return v.visitList(this);
}
-
+
@Override
default IRelation asRelation() {
if (!getType().isListRelation()) {
throw new UnsupportedOperationException(getType() + " is not a relation");
}
-
+
return new IRelation() {
@Override
public String toString() {
@@ -481,11 +481,11 @@ public String toString() {
public IList asContainer() {
return IList.this;
}
-
+
@Override
public IWriter writer() {
- return IList.this.writer();
+ return IList.this.writer();
}
};
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/io/usethesource/vallang/IListWriter.java b/src/main/java/io/usethesource/vallang/IListWriter.java
index 130ebf2b1..f51f41b07 100644
--- a/src/main/java/io/usethesource/vallang/IListWriter.java
+++ b/src/main/java/io/usethesource/vallang/IListWriter.java
@@ -18,46 +18,46 @@
* This interface allows to gather the elements of a list efficiently and in a specific order.
* When all elements have been gathered the done() method can be used to obtain an immutable IList
* with the gathered elements in the specified order.
- *
+ *
* Note: implementations are not required to guarantee thread-safe access to the writer object.
*/
public interface IListWriter extends IWriter {
-
+
/**
- * Inserts elements at a specific position, keeping the argument in order of appearance.
- *
- * @param index
- * @param value an array of elements to insert .
- * @throws FactTypeUseException when done() was called before or when the elements have an incompatible type.
- * @throws IndexOutOfBoundsException
- */
+ * Inserts elements at a specific position, keeping the argument in order of appearance.
+ *
+ * @param index
+ * @param value an array of elements to insert .
+ * @throws FactTypeUseException when done() was called before or when the elements have an incompatible type.
+ * @throws IndexOutOfBoundsException
+ */
public void insertAt(int index, IValue... value);
-
+
/**
- * Inserts elements in front, keeping the argument in order of appearance.
- *
- * @param elems an array of elements to insert
- * @param start index to start copying elements from
- * @param length amount of elements to copy from the array
- *
- * @throws FactTypeUseException when done() was called before or when the elements have an incompatible type.
- * @throws IndexOutOfBoundsException
- */
+ * Inserts elements in front, keeping the argument in order of appearance.
+ *
+ * @param elems an array of elements to insert
+ * @param start index to start copying elements from
+ * @param length amount of elements to copy from the array
+ *
+ * @throws FactTypeUseException when done() was called before or when the elements have an incompatible type.
+ * @throws IndexOutOfBoundsException
+ */
public void insert(IValue[] elems, int start, int length);
-
+
/**
- * Inserts elements at a specific position, keeping the argument in order of appearance.
- *
- * @param index place to insert elements at
- * @param elems an array of elements to insert
- * @param start index to start copying elements from
- * @param length amount of elements to copy from the array
- *
- * @throws FactTypeUseException when done() was called before or when the elements have an incompatible type.
- * @throws IndexOutOfBoundsException
- */
+ * Inserts elements at a specific position, keeping the argument in order of appearance.
+ *
+ * @param index place to insert elements at
+ * @param elems an array of elements to insert
+ * @param start index to start copying elements from
+ * @param length amount of elements to copy from the array
+ *
+ * @throws FactTypeUseException when done() was called before or when the elements have an incompatible type.
+ * @throws IndexOutOfBoundsException
+ */
public void insertAt(int index, IValue[] elems, int start, int length);
-
+
/**
* Replaces an existing element at index in the list.
* @param index the location where to replace the element
@@ -67,10 +67,10 @@ public interface IListWriter extends IWriter {
* @returns the replaced element
*/
public IValue replaceAt(int index, IValue elem);
-
+
/**
* Return the ith element of the list.
- *
+ *
* @param i
* @return the ith element of the list
* @throws IndexOutOfBoundsException when i < 0 or i >= IList.length
@@ -81,4 +81,4 @@ public interface IListWriter extends IWriter {
* @return the number of elements in the list
*/
public int length();
-}
+}
diff --git a/src/main/java/io/usethesource/vallang/IMap.java b/src/main/java/io/usethesource/vallang/IMap.java
index 5af85c1cd..b6f1180c7 100644
--- a/src/main/java/io/usethesource/vallang/IMap.java
+++ b/src/main/java/io/usethesource/vallang/IMap.java
@@ -8,7 +8,7 @@
* Contributors:
*
* * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI
- * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
+ * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
*******************************************************************************/
package io.usethesource.vallang;
@@ -34,7 +34,7 @@ default int getMatchFingerprint() {
/**
* Adds a new entry to the map, mapping the key to value. If the
* key existed before, the old value will be lost.
- * @param key
+ * @param key
* @param value
* @return a copy of the map with the new key/value mapping
*/
@@ -44,10 +44,10 @@ public default IMap put(IValue key, IValue value) {
sw.put(key, value);
return sw.done();
}
-
+
/**
* Remove the values with the given key.
- *
+ *
* @param key
* @return a map without entries that are isEqual to the key
*/
@@ -68,7 +68,7 @@ public default IMap put(IValue key, IValue value) {
@EnsuresNonNullIf(expression="get(#1)", result=true)
@SuppressWarnings({"contracts.conditional.postcondition"})
public boolean containsKey(IValue key);
-
+
@EqualsMethod
public default boolean defaultEquals(@Nullable Object other){
if (other == null) {
@@ -93,21 +93,21 @@ public default boolean defaultEquals(@Nullable Object other){
if (size() == map2.size()) {
outer:for (IValue k1 : map2) {
-
+
// the loop might seem weird but due to the (deprecated)
// semantics of node annotations we must check each element
// for _deep_ equality. This is a big source of inefficiency
// and one of the reasons why the semantics of annotations is
// deprecated for "keyword parameters".
-
+
for (IValue cursor : this) {
if (cursor.equals(k1)) {
// key was found, now check the value
IValue val2 = map2.get(k1);
- if (val2 != null && !val2.equals(get(k1))) {
+ if (val2 != null && !val2.equals(get(k1))) {
return false;
}
-
+
continue outer;
}
}
@@ -117,9 +117,9 @@ public default boolean defaultEquals(@Nullable Object other){
}
}
- return false;
+ return false;
}
-
+
public default int defaultHashCode() {
int hash = 0;
@@ -131,7 +131,7 @@ public default int defaultHashCode() {
return hash;
}
-
+
@Override
public default boolean match(IValue other) {
if (other == this) {
@@ -146,7 +146,7 @@ public default boolean match(IValue other) {
IValue v1 = get(k1);
assert v1 != null : "@AssumeAssertion(nullness)";
-
+
for (Iterator iterator = map2.iterator(); iterator.hasNext();) {
IValue k2 = iterator.next();
if (k2.match(k1)) {
@@ -164,16 +164,16 @@ public default boolean match(IValue other) {
return false; // no matching key found for k1
}
- return true;
+ return true;
}
}
return false;
}
-
+
/**
* Determine whether a certain value exists in this map.
- * @param value
+ * @param value
* @return true iff there is at least one key that maps to the given value.
*/
public default boolean containsValue(IValue value) {
@@ -182,7 +182,7 @@ public default boolean containsValue(IValue value) {
return true;
}
}
-
+
return false;
}
@@ -192,14 +192,14 @@ public default boolean containsValue(IValue value) {
public default Type getKeyType() {
return getType().getKeyType();
}
-
+
/**
* @return the value type for this map
*/
public default Type getValueType() {
return getType().getValueType();
}
-
+
/**
* Adds all key value pairs of the other map to this map (constructing a new one).
* The values of the other map overwrite the values of this map.
@@ -212,7 +212,7 @@ public default IMap join(IMap other) {
sw.putAll(other);
return sw.done();
}
-
+
/**
* Removes all key-value pairs from this map where a key exists in the other map.
* @param other
@@ -220,16 +220,16 @@ public default IMap join(IMap other) {
*/
public default IMap remove(IMap other) {
IMapWriter sw = writer();
-
+
for (Entry entry : (Iterable>) () -> entryIterator()) {
if (!other.containsKey(entry.getKey())) {
sw.put(entry.getKey(), entry.getValue());
}
}
-
+
return sw.done();
}
-
+
/**
* If the value type of this map is a sub-type of the key type of the other, construct
* a new map that represents the composition which maps keys of this map to values of
@@ -249,15 +249,15 @@ public default IMap compose(IMap other) {
return w.done();
}
-
+
@Override
public IMapWriter writer();
-
+
/**
* Compute the common map (intersection) between this map and another. Any key-value
* pair that is not present in the other will not be present in the result. This
* means that if a key exists in both maps, but with a different value, the key
- * will not be present in the result.
+ * will not be present in the result.
* @param other
* @return a new map containing the common pairs between the two maps.
*/
@@ -268,31 +268,31 @@ public default IMap common(IMap other) {
IValue thisKey = entry.getKey();
IValue thisValue = entry.getValue();
IValue otherValue = other.get(thisKey);
-
+
if (otherValue != null && thisValue.equals(otherValue)) {
sw.put(thisKey, thisValue);
}
}
-
+
return sw.done();
}
-
+
/**
- * Checks if the other
map is defined for every key that is
- * present in the receiver object.
- *
- * @param other
- * @return true iff all for every key of the receiver there exists an entry
- * in the other map.
- */
+ * Checks if the other
map is defined for every key that is
+ * present in the receiver object.
+ *
+ * @param other
+ * @return true iff all for every key of the receiver there exists an entry
+ * in the other map.
+ */
public default boolean isSubMap(IMap other) {
for (Entry entry : (Iterable>) () -> entryIterator()) {
IValue key = entry.getKey();
-
+
if (!other.containsKey(key)) {
return false;
}
-
+
if (!other.get(key).equals(entry.getValue())) {
return false;
}
@@ -300,31 +300,31 @@ public default boolean isSubMap(IMap other) {
return true;
}
-
+
/**
* Repeated here for documentation purposes, this iterator
* returns only the keys of the map, not its values.
- *
- * @return an iterator over the keys of the map
+ *
+ * @return an iterator over the keys of the map
*/
@Override
public Iterator iterator();
-
+
/**
* @return an iterator over the values of the map
*/
public Iterator valueIterator();
-
+
/**
* @return an iterator over the keys-value pairs of the map
*/
public Iterator> entryIterator();
-
+
@Override
default T accept(IValueVisitor v) throws E {
return v.visitMap(this);
}
-
+
@Override
/**
* a map should stream key/value tuples
diff --git a/src/main/java/io/usethesource/vallang/IMapWriter.java b/src/main/java/io/usethesource/vallang/IMapWriter.java
index 96d51bbc2..98ebc20b7 100644
--- a/src/main/java/io/usethesource/vallang/IMapWriter.java
+++ b/src/main/java/io/usethesource/vallang/IMapWriter.java
@@ -28,7 +28,7 @@ public interface IMapWriter extends IWriter {
* @throws FactTypeUseException
*/
void put(IValue key, IValue value);
-
+
/**
* Merge an entire map into the writer. Existing keys
* will be overwritten by the new map
@@ -36,7 +36,7 @@ public interface IMapWriter extends IWriter {
* @throws FactTypeUseException
*/
void putAll(IMap map);
-
+
/**
* Merge an entire java.util.Map into the writer. Existing
* keys will be overwritten by the new map.
@@ -44,14 +44,14 @@ public interface IMapWriter extends IWriter {
* @throws FactTypeUseException
*/
void putAll(Map map);
-
+
/**
* Lookup a given key into the state of the current map-to-be
* @param key
* @return null if no value exists with this key, otherwise the respective value.
*/
@Nullable IValue get(IValue key);
-
+
/**
* The map writer collects key/value tuples
*/
diff --git a/src/main/java/io/usethesource/vallang/INode.java b/src/main/java/io/usethesource/vallang/INode.java
index 2d0afcf3c..b1cca5764 100644
--- a/src/main/java/io/usethesource/vallang/INode.java
+++ b/src/main/java/io/usethesource/vallang/INode.java
@@ -1,5 +1,5 @@
/*******************************************************************************
-* Copyright (c) CWI 2008
+* Copyright (c) CWI 2008
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -25,63 +25,63 @@
/**
- * Untyped node representation (a container that has a limited amount of children and a name),
+ * Untyped node representation (a container that has a limited amount of children and a name),
* can iterate over the list of children. This data construct can be used to make trees by applying
* it recursively.
*/
public interface INode extends IValue, Iterable {
- @Override
- default int getMatchFingerprint() {
- int hash = getName().hashCode();
-
- if (hash == 0) {
- hash = 3386882 /* "node".hashCode() */;
- }
-
- return hash + 131 * arity();
- }
-
- /**
- * Get a child
- * @param i the zero based index of the child
- * @return a value
- * @throws IndexOutOfBoundsException
- */
- public IValue get(int i);
-
- /**
- * Change this tree to have a different child at a certain position.
- *
- * @param i the zero based index of the child to be replaced
- * @param newChild the new value for the child
- * @return an untyped tree with the new child at position i, if the receiver was untyped,
- * or a typed tree node if it was typed.
- * @throws IndexOutOfBoundsException
- */
- public INode set(int i, IValue newChild);
-
- /**
- * @return the (fixed) number of children of this node (excluding keyword arguments)
- */
- public int arity();
-
- /**
- * @return the name of this node (an identifier)
- */
- public String getName();
-
- /**
- * @return an iterator over the direct children, equivalent to 'this'.
- */
- public Iterable getChildren();
-
- /**
- * @return an iterator over the direct children.
- */
- public Iterator iterator();
-
- /**
+ @Override
+ default int getMatchFingerprint() {
+ int hash = getName().hashCode();
+
+ if (hash == 0) {
+ hash = 3386882 /* "node".hashCode() */;
+ }
+
+ return hash + 131 * arity();
+ }
+
+ /**
+ * Get a child
+ * @param i the zero based index of the child
+ * @return a value
+ * @throws IndexOutOfBoundsException
+ */
+ public IValue get(int i);
+
+ /**
+ * Change this tree to have a different child at a certain position.
+ *
+ * @param i the zero based index of the child to be replaced
+ * @param newChild the new value for the child
+ * @return an untyped tree with the new child at position i, if the receiver was untyped,
+ * or a typed tree node if it was typed.
+ * @throws IndexOutOfBoundsException
+ */
+ public INode set(int i, IValue newChild);
+
+ /**
+ * @return the (fixed) number of children of this node (excluding keyword arguments)
+ */
+ public int arity();
+
+ /**
+ * @return the name of this node (an identifier)
+ */
+ public String getName();
+
+ /**
+ * @return an iterator over the direct children, equivalent to 'this'.
+ */
+ public Iterable getChildren();
+
+ /**
+ * @return an iterator over the direct children.
+ */
+ public Iterator iterator();
+
+ /**
* Replaces the value of the children first, second ... end with the elements in the list r
* Expected:
* - support for negative indices
@@ -94,111 +94,111 @@ default int getMatchFingerprint() {
* @throws FactTypeUseException when the type of the element is not a subtype of the element type
* @throws IndexOutOfBoundsException when the b < 0 or b >= INode.arity() or e < 0 or e > INOde.arity()
*/
- public default INode replace(int first, int second, int end, IList repl) {
- ArrayList newChildren = new ArrayList<>();
- int rlen = repl.length();
- int increment = Math.abs(second - first);
- if (first < end) {
- int childIndex = 0;
- // Before begin
- while (childIndex < first) {
- newChildren.add(this.get(childIndex++));
- }
- int replIndex = 0;
- boolean wrapped = false;
- // Between begin and end
- while (childIndex < end) {
- newChildren.add(repl.get(replIndex++));
- if (replIndex == rlen) {
- replIndex = 0;
- wrapped = true;
- }
- childIndex++; //skip the replaced element
- for (int j = 1; j < increment && childIndex < end; j++) {
- newChildren.add(this.get(childIndex++));
- }
- }
- if (!wrapped) {
- while (replIndex < rlen) {
- newChildren.add(repl.get(replIndex++));
- }
- }
- // After end
- int dlen = this.arity();
- while (childIndex < dlen) {
- newChildren.add(this.get(childIndex++));
- }
- } else {
- // Before begin (from right to left)
- int childIndex = this.arity() - 1;
- while (childIndex > first) {
- newChildren.add(0, this.get(childIndex--));
- }
- // Between begin (right) and end (left)
- int replIndex = 0;
- boolean wrapped = false;
- while (childIndex > end) {
- newChildren.add(0, repl.get(replIndex++));
- if (replIndex == repl.length()) {
- replIndex = 0;
- wrapped = true;
- }
- childIndex--; //skip the replaced element
- for (int j = 1; j < increment && childIndex > end; j++) {
- newChildren.add(0, this.get(childIndex--));
- }
- }
- if (!wrapped) {
- while (replIndex < rlen) {
- newChildren.add(0, repl.get(replIndex++));
- }
- }
- // Left of end
- while (childIndex >= 0) {
- newChildren.add(0, this.get(childIndex--));
- }
- }
-
- IValue[] childArray = new IValue[newChildren.size()];
- newChildren.toArray(childArray);
-
- return setChildren(childArray);
- }
-
- /**
- * Replace all children with a new array of children, keeping only
- * the name of the original node.
- * @param childArray
- * @return a new node with the same name, yet new children.
- */
- public INode setChildren(IValue[] childArray);
+ public default INode replace(int first, int second, int end, IList repl) {
+ ArrayList newChildren = new ArrayList<>();
+ int rlen = repl.length();
+ int increment = Math.abs(second - first);
+ if (first < end) {
+ int childIndex = 0;
+ // Before begin
+ while (childIndex < first) {
+ newChildren.add(this.get(childIndex++));
+ }
+ int replIndex = 0;
+ boolean wrapped = false;
+ // Between begin and end
+ while (childIndex < end) {
+ newChildren.add(repl.get(replIndex++));
+ if (replIndex == rlen) {
+ replIndex = 0;
+ wrapped = true;
+ }
+ childIndex++; //skip the replaced element
+ for (int j = 1; j < increment && childIndex < end; j++) {
+ newChildren.add(this.get(childIndex++));
+ }
+ }
+ if (!wrapped) {
+ while (replIndex < rlen) {
+ newChildren.add(repl.get(replIndex++));
+ }
+ }
+ // After end
+ int dlen = this.arity();
+ while (childIndex < dlen) {
+ newChildren.add(this.get(childIndex++));
+ }
+ } else {
+ // Before begin (from right to left)
+ int childIndex = this.arity() - 1;
+ while (childIndex > first) {
+ newChildren.add(0, this.get(childIndex--));
+ }
+ // Between begin (right) and end (left)
+ int replIndex = 0;
+ boolean wrapped = false;
+ while (childIndex > end) {
+ newChildren.add(0, repl.get(replIndex++));
+ if (replIndex == repl.length()) {
+ replIndex = 0;
+ wrapped = true;
+ }
+ childIndex--; //skip the replaced element
+ for (int j = 1; j < increment && childIndex > end; j++) {
+ newChildren.add(0, this.get(childIndex--));
+ }
+ }
+ if (!wrapped) {
+ while (replIndex < rlen) {
+ newChildren.add(0, repl.get(replIndex++));
+ }
+ }
+ // Left of end
+ while (childIndex >= 0) {
+ newChildren.add(0, this.get(childIndex--));
+ }
+ }
+
+ IValue[] childArray = new IValue[newChildren.size()];
+ newChildren.toArray(childArray);
+
+ return setChildren(childArray);
+ }
+
+ /**
+ * Replace all children with a new array of children, keeping only
+ * the name of the original node.
+ * @param childArray
+ * @return a new node with the same name, yet new children.
+ */
+ public INode setChildren(IValue[] childArray);
@Override
public default T accept(IValueVisitor v) throws E {
- return v.visitNode(this);
- }
-
+ return v.visitNode(this);
+ }
+
@Override
public default boolean mayHaveKeywordParameters() {
- return true;
+ return true;
}
-
+
@Override
public default IWithKeywordParameters extends INode> asWithKeywordParameters() {
- return new AbstractDefaultWithKeywordParameters(this, AbstractSpecialisedImmutableMap.mapOf()) {
- @Override
- protected INode wrap(INode content, Map.Immutable parameters) {
- return new NodeWithKeywordParametersFacade(content, parameters);
- }
- };
+ return new AbstractDefaultWithKeywordParameters(this, AbstractSpecialisedImmutableMap.mapOf()) {
+ @Override
+ protected INode wrap(INode content, Map.Immutable parameters) {
+ return new NodeWithKeywordParametersFacade(content, parameters);
+ }
+ };
}
-
+
@Override
public default boolean match(IValue value) {
if(value == this) {
return true;
}
-
+
if(value == null) {
return false;
}
diff --git a/src/main/java/io/usethesource/vallang/INumber.java b/src/main/java/io/usethesource/vallang/INumber.java
index 1d605ea32..7af65f9ba 100644
--- a/src/main/java/io/usethesource/vallang/INumber.java
+++ b/src/main/java/io/usethesource/vallang/INumber.java
@@ -11,27 +11,27 @@
package io.usethesource.vallang;
public abstract interface INumber extends IValue {
- /**
- * Returns an integer if both arguments are integer, and a real otherwise
- * @return this + other
- */
+ /**
+ * Returns an integer if both arguments are integer, and a real otherwise
+ * @return this + other
+ */
public INumber add(INumber other);
-
+
/**
- * @return this + other
- */
+ * @return this + other
+ */
public IReal add(IReal other);
-
+
/**
- * Returns an integer if both arguments are integer, and a real otherwise
- * @return this + other
- */
+ * Returns an integer if both arguments are integer, and a real otherwise
+ * @return this + other
+ */
public INumber add(IInteger other);
/**
- * Returns a rational if both arguments are rationals or integers, and a real otherwise
- * @return this + other
- */
+ * Returns a rational if both arguments are rationals or integers, and a real otherwise
+ * @return this + other
+ */
public INumber add(IRational other);
/**
@@ -39,18 +39,18 @@ public abstract interface INumber extends IValue {
* @return this - other;
*/
public INumber subtract(INumber other);
-
+
/**
* @return this - other;
*/
public INumber subtract(IReal other);
-
+
/**
* Returns an integer if both arguments are integer, and a real otherwise
* @return this - other;
*/
public INumber subtract(IInteger other);
-
+
/**
* @return this - other;
*/
@@ -61,12 +61,12 @@ public abstract interface INumber extends IValue {
* @return this * other;
*/
public INumber multiply(INumber other);
-
+
/**
* @return this * other;
*/
public IReal multiply(IReal other);
-
+
/**
* Returns an integer if both arguments are integer, and a real otherwise
* @return this * other;
@@ -81,25 +81,25 @@ public abstract interface INumber extends IValue {
/**
* Integer division if both the receiver and the argument are integers, and real division otherwise
- * @return this / other
+ * @return this / other
*/
public INumber divide(INumber other, int precision);
-
+
/**
- * @return this / other
+ * @return this / other
*/
public IReal divide(IReal other, int precision);
-
+
/**
* Integer division if both the receiver and the argument are integers, and real division otherwise
- * @return this / other
+ * @return this / other
*/
public INumber divide(IInteger other, int precision);
/**
- * Rational division if both the receiver and the argument are integers/rationals,
+ * Rational division if both the receiver and the argument are integers/rationals,
* real division otherwise
- * @return this / other
+ * @return this / other
*/
public INumber divide(IRational other, int precision);
@@ -108,13 +108,13 @@ public abstract interface INumber extends IValue {
* @return -1 * this;
*/
public INumber negate();
-
+
/**
* @param precision the precision of the result. This parameter may be ignored if another source of an accurate precision is available.
* @return an IReal that is equal to this INumber
*/
public IReal toReal(int precision);
-
+
/**
* @return an IInteger (truncated if it was a real value)
*/
@@ -129,32 +129,32 @@ public abstract interface INumber extends IValue {
* @return true iff the numbers are equal
*/
public IBool equal(INumber other);
-
+
/**
* @return true iff the numbers are equal
*/
public IBool equal(IInteger other);
-
+
/**
* @return true iff the numbers are equal
*/
public IBool equal(IReal other);
-
+
/**
* @return true iff the numbers are equal
*/
public IBool equal(IRational other);
-
+
/**
* @return true iff this < other
*/
public IBool less(INumber other);
-
+
/**
* @return true iff this < other
*/
public IBool less(IReal other);
-
+
/**
* @return true iff this < other
*/
@@ -169,12 +169,12 @@ public abstract interface INumber extends IValue {
* @return true iff this > other
*/
public IBool greater(INumber other);
-
+
/**
* @return true iff this > other
*/
public IBool greater(IReal other);
-
+
/**
* @return true iff this > other
*/
@@ -189,12 +189,12 @@ public abstract interface INumber extends IValue {
* @return true iff this <= other
*/
public IBool lessEqual(INumber other);
-
+
/**
* @return true iff this <= other
*/
public IBool lessEqual(IReal other);
-
+
/**
* @return true iff this <= other
*/
@@ -209,12 +209,12 @@ public abstract interface INumber extends IValue {
* @return true iff this >= other
*/
public IBool greaterEqual(INumber other);
-
+
/**
* @return true iff this >= other
*/
public IBool greaterEqual(IReal other);
-
+
/**
* @return true iff this >= other
*/
@@ -224,20 +224,20 @@ public abstract interface INumber extends IValue {
* @return true iff this >= other
*/
public IBool greaterEqual(IRational other);
-
+
/**
* Returns an integer if the receiver was an integer, and a real otherwise
* @return absolute value of this number
*/
public INumber abs();
-
- /**
+
+ /**
* Compares two numbers
* @param other
* @return -1 if receiver is less than other, 0 is receiver is equal, 1 if receiver is larger
*/
public int compare(INumber other);
-
+
/**
* @return return -1, 0 or 1 iff this integer is less than, equal to or greater than zero.
*/
diff --git a/src/main/java/io/usethesource/vallang/IRational.java b/src/main/java/io/usethesource/vallang/IRational.java
index 4d8dd0c01..3960d15b8 100644
--- a/src/main/java/io/usethesource/vallang/IRational.java
+++ b/src/main/java/io/usethesource/vallang/IRational.java
@@ -14,46 +14,46 @@
import io.usethesource.vallang.visitors.IValueVisitor;
public interface IRational extends INumber {
- /**
- * @return this + other;
- */
+ /**
+ * @return this + other;
+ */
@Override
public IRational add(IRational other);
-
+
/**
* @return this - other;
*/
@Override
public IRational subtract(IRational other);
-
+
/**
* @return this * other;
*/
@Override
public IRational multiply(IRational other);
-
+
/**
* @return this / other;
*/
public IRational divide(IRational other);
-
+
/**
* @return this / other;
*/
public IRational divide(IInteger other);
-
+
/**
* @return this rem other, which is the remainder after dividing this by other.
* This may be a negative number.
*/
public IRational remainder(IRational other);
-
+
/**
* @return -1 * this;
*/
@Override
public IRational negate();
-
+
/**
* @return an IReal that approximates this IRational
*/
@@ -80,35 +80,35 @@ public interface IRational extends INumber {
*/
@Override
public IBool less(IRational other);
-
+
/**
* @return true iff this > other
*/
@Override
public IBool greater(IRational other);
-
+
/**
* @return true iff this <= other
*/
@Override
public IBool lessEqual(IRational other);
-
+
/**
* @return true iff this >= other
*/
@Override
public IBool greaterEqual(IRational other);
-
+
/**
* @return the value of the IRational represent as a string of decimal numbers in ASCII encoding.
*/
public String getStringRepresentation();
-
+
/**
* @return The rational's numerator
*/
public IInteger numerator();
-
+
/**
* @return The rational's denominator
*/
@@ -116,7 +116,7 @@ public interface IRational extends INumber {
/**
* numerator() == (toInteger() * denominator()) + remainder()
- *
+ *
* @return numerator() % denominator()
*/
public IInteger remainder();
@@ -127,7 +127,7 @@ public interface IRational extends INumber {
* @return -1 if receiver is less than other, 0 is receiver is equal, 1 if receiver is larger
*/
public int compare(IRational other);
-
+
/**
* @return return -1, 0 or 1 iff this rational is less than, equal to or greater than zero.
*/
@@ -139,21 +139,21 @@ public interface IRational extends INumber {
*/
@Override
public IRational abs();
-
+
/**
* @return this number rounded down to the nearest integer number that is
* less than this number.
*/
public IInteger floor();
-
+
/**
* @return this number rounded to the nearest integer number.
*/
public IInteger round();
-
+
@Override
default T accept(IValueVisitor v) throws E {
return v.visitRational(this);
}
-
+
}
diff --git a/src/main/java/io/usethesource/vallang/IReal.java b/src/main/java/io/usethesource/vallang/IReal.java
index b22352382..78bd852cc 100644
--- a/src/main/java/io/usethesource/vallang/IReal.java
+++ b/src/main/java/io/usethesource/vallang/IReal.java
@@ -22,91 +22,91 @@ default int getMatchFingerprint() {
return hash == 0 ? 3496350 /* "real".hashCode() */ : hash;
}
- /**
- * @return this + other;
- */
+ /**
+ * @return this + other;
+ */
@Override
public IReal add(IReal other);
-
+
/**
* @return this - other;
*/
@Override
public IReal subtract(IReal other);
-
+
/**
* @return this * other;
*/
@Override
public IReal multiply(IReal other);
-
+
/**
* Divides a real with a specific precision
- *
+ *
* @return this / other;
*/
@Override
public IReal divide(IReal other, int precision);
-
+
/**
* @return this number rounded down to the nearest integer number that is
* less than this number.
*/
public IReal floor();
-
+
/**
* @return this number rounded to the nearest integer number.
*/
public IReal round();
-
+
/**
* @return the integer value nearest to this number
*/
@Override
public IInteger toInteger();
-
+
/**
* @return true iff this < other
*/
@Override
public IBool less(IReal other);
-
+
/**
* @return true iff this > other
*/
@Override
public IBool greater(IReal other);
-
+
/**
* @return true iff this <= other
*/
@Override
public IBool lessEqual(IReal other);
-
+
/**
* @return true iff this >= other
*/
@Override
public IBool greaterEqual(IReal other);
-
+
/**
* @return this real represented as a string of decimal characters in scientific notation
*/
public String getStringRepresentation();
-
+
/**
* @return -1 * this
*/
@Override
public IReal negate();
-
+
/**
* Compares two doubles
* @param other
* @return -1 if receiver is less than other, 0 is receiver is equal, 1 if receiver is larger
*/
public int compare(IReal other);
-
+
/**
* Converts this IReal to a double. Precision may be less.
* If the number does not fit, it will return
@@ -122,24 +122,24 @@ default int getMatchFingerprint() {
* when the number is smaller or larger, respectively.
*/
public float floatValue();
-
+
/**
* @return the number of digits in this.{@link #unscaled()}
*/
public int precision();
-
+
/**
* The scale is the exponent of 10 with which the base is multiplied
* as in scientific notation. I.e. in 1 * 103, the scale is 3.
- *
+ *
* @return the scale of the real
*/
public int scale();
-
+
/**
* Returns the unscaled value of this real as an integer. This is useful
* for serialization purposes among other things.
- *
+ *
* @return this * 10this.scale()
*/
public IInteger unscaled();
@@ -150,65 +150,65 @@ default int getMatchFingerprint() {
@Override
public IReal abs();
- /**
- * @return logbase(this)
- */
+ /**
+ * @return logbase(this)
+ */
public IReal log(IInteger base, int precision);
-
- /**
- * @return logbase(this)
- */
- public IReal log(IReal base, int precision);
-
- /**
- * @return natural log of this
- */
- public IReal ln(int precision);
-
- /**
- * @return square root of this
- */
- public IReal sqrt(int precision);
-
- /**
- * @return n-th root of this
- */
- public IReal nroot(IInteger n, int precision);
-
- /**
- * @return ethis
- */
- public IReal exp(int precision);
-
- /**
- * @return thispower
- */
- public IReal pow(IInteger power);
-
- /**
- * @return thispower but for non natural numbers
- */
- public IReal pow(IReal power, int precision);
-
- /**
- * @return tan(this)
- */
- public IReal tan(int precision);
-
- /**
- * @return sin(this)
- */
- public IReal sin(int precision);
-
- /**
- * @return cos(this)
- */
-
- public IReal cos(int precision);
-
- @Override
- default T accept(IValueVisitor v) throws E {
- return v.visitReal(this);
- }
+
+ /**
+ * @return logbase(this)
+ */
+ public IReal log(IReal base, int precision);
+
+ /**
+ * @return natural log of this
+ */
+ public IReal ln(int precision);
+
+ /**
+ * @return square root of this
+ */
+ public IReal sqrt(int precision);
+
+ /**
+ * @return n-th root of this
+ */
+ public IReal nroot(IInteger n, int precision);
+
+ /**
+ * @return ethis
+ */
+ public IReal exp(int precision);
+
+ /**
+ * @return thispower
+ */
+ public IReal pow(IInteger power);
+
+ /**
+ * @return thispower but for non natural numbers
+ */
+ public IReal pow(IReal power, int precision);
+
+ /**
+ * @return tan(this)
+ */
+ public IReal tan(int precision);
+
+ /**
+ * @return sin(this)
+ */
+ public IReal sin(int precision);
+
+ /**
+ * @return cos(this)
+ */
+
+ public IReal cos(int precision);
+
+ @Override
+ default T accept(IValueVisitor v) throws E {
+ return v.visitReal(this);
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/IRelation.java b/src/main/java/io/usethesource/vallang/IRelation.java
index 834a37d90..f3d87c9aa 100644
--- a/src/main/java/io/usethesource/vallang/IRelation.java
+++ b/src/main/java/io/usethesource/vallang/IRelation.java
@@ -1,252 +1,252 @@
-/*******************************************************************************
-* Copyright (c) 2019 NWO-I CWI
-* All rights reserved. This program and the accompanying materials
-* are made available under the terms of the Eclipse Public License v1.0
-* which accompanies this distribution, and is available at
-* http://www.eclipse.org/legal/epl-v10.html
-*
-* Contributors:
-* Jurgen J. Vinju - initial implementation
-*******************************************************************************/
-package io.usethesource.vallang;
-
-import java.util.Iterator;
-import java.util.function.Function;
-
-import io.usethesource.vallang.exceptions.IllegalOperationException;
-import io.usethesource.vallang.type.Type;
-
-/**
- * Provides Relational Calculus operators to an existing ICollection.
- * This interface provides a generic implementation for all operators,
- * which should be specialized by implementations that know how to optimize
- * these operations with specialized data-structures.
- *
- * @param a collection value type like ISet or IList
- */
-public interface IRelation> extends Iterable {
-
- @Override
- default Iterator iterator() {
- return asContainer().iterator();
- }
-
- /**
- * Relational composition works only on binary relations. It matches the second column
- * of the receiver with the first column of the given relation.
- * TODO: generalize to n-ary. Implementing classes should specialize
- * this generic implementation for more efficiency.
- *
- * @param that is the given relation
- * @return a new binary relation with first column of the accepting relation and the second column
- * of the given relation, containing only tuples where the last column of the receiver
- * matches the first column of the given relation.
- */
- public default C compose(IRelation that) {
- C thisContainer = this.asContainer();
- C thatContainer = that.asContainer();
- Type thisElementType = thisContainer.getElementType();
- Type thatElementType = thatContainer.getElementType();
-
- if (thisElementType.isBottom()) {
- return thisContainer;
- }
-
- if (thatElementType.isBottom()) {
- return thatContainer;
- }
-
- if (thisElementType.getArity() != 2 || thatElementType.getArity() != 2) {
- throw new IllegalOperationException("Incompatible types for composition.", thisElementType, thatElementType);
- }
-
- if (!thisElementType.getFieldType(1).comparable(thatElementType.getFieldType(0))) {
- return asContainer().empty();
- }
-
- IWriter w = writer();
-
- for (IValue elem1 : this) {
- ITuple tuple1 = (ITuple) elem1;
- for (IValue elem2 : that) {
- ITuple tuple2 = (ITuple) elem2;
- if (tuple1.get(1).equals(tuple2.get(0))) {
- w.appendTuple(tuple1.get(0), tuple2.get(1));
- }
- }
- }
-
- return w.done();
- }
-
- /**
- * @return the transitive non-reflexive closure of a binary relation
- * @throws UnsupportedOperationException when the receiver is not a binary relation
- */
- public default C closure() {
- if (!isBinary()) {
- throw new UnsupportedOperationException("relation is not binary");
- }
-
- C next = this.asContainer();
- IRelation result;
-
- do {
- result = next.asRelation();
- next = result.compose(result).union(next);
- } while (!next.equals(result.asContainer()));
-
- return next;
- }
-
- /**
- * @return the transitive reflexive closure of a binary relation
- * @throws UnsupportedOperationException when the receiver is not a binary relation
- */
- public default C closureStar() {
- IWriter w = writer();
-
- for (IValue val : carrier()) {
- w.appendTuple(val, val);
- }
- w.appendAll(closure());
-
- return w.done();
- }
-
- /**
- * @return the number of columns in the relation
- */
- default int arity() {
- return asContainer().getElementType().getArity();
- }
-
- /**
- * @return a new empty relation with the current factory
- */
- default C empty() {
- return asContainer().empty();
- }
-
- /**
- * Reduces an n-ary relation to fewer columns, given by the fields to select.
- * @param fields to select from the relation, index starts at 0
- * @return a new relation with only the columns selected by the fields parameter
- */
- default C project(int... fields) {
- IWriter w = writer();
-
- for (IValue v : this) {
- w.append(((ITuple) v).select(fields));
- }
-
- return w.done();
- }
-
- /**
- * Compute the carrier set of an n-ary relation.
- * @return a container with all the elements of all tuples in the relation.
- */
- public default C carrier() {
- IWriter w = writer().unique();
-
- for (IValue t : this) {
- w.appendAll((ITuple) t);
- }
-
- return w.done();
- }
-
- /**
- * @return a container with the first elements of all tuples in the relation
- */
- public default C domain() {
- IWriter w = asContainer().writer();
-
- for (IValue elem : this) {
- w.insert(((ITuple) elem).get(0));
- }
-
- return w.done();
- }
-
- /**
- * @return a container with the last elements of all tuples in the relation
- */
- public default C range() {
- int columnIndex = arity() - 1;
- IWriter w = writer();
-
- for (IValue elem : this) {
- w.insert(((ITuple) elem).get(columnIndex));
- }
-
- return w.done();
- }
-
- /**
- * Lookup the values by the first column in the relation
- * @return a set of the second elements of all tuples where the first column is
- * equal to the given key, without the first column.
- *
- * TODO: generalize to producing n-ary tuples.
- */
- public default C index(IValue key) {
- C set1 = asContainer();
- Type elementType = getElementType();
-
- if (elementType.isBottom()) {
- return set1.empty();
- }
-
- int valueArity = elementType.getArity() - 1;
-
- Function mapper;
- if (valueArity == 0) {
- mapper = t -> t.get(1);
- }
- else {
- int[] newTupleIndex = new int[valueArity];
- for (int k = 1; k <= valueArity; k++) {
- newTupleIndex[k - 1] = k;
- }
- mapper = t -> t.select(newTupleIndex);
- }
-
- IWriter result = writer();
- for (IValue val : this) {
- ITuple tup = (ITuple) val;
- if (tup.get(0).equals(key)) {
- result.insert(mapper.apply(tup));
- }
- }
-
- return result.done();
- }
-
- /**
- * @return the original container this IRelation is wrapping.
- */
- public C asContainer();
-
- /**
- * @return a fresh writer for the kind of container this IRelation is wrapping
- */
- public default IWriter writer() {
- return asContainer().writer();
- }
-
- /**
- * @return the element type of the container this IRelation is wrapping
- */
- public default Type getElementType() {
- return asContainer().getElementType();
- }
-
- /**
- * @return true iff the current relation is binary (has two columns)
- */
- default boolean isBinary() {
- return getElementType().isBottom() || getElementType().getArity() == 2;
- }
-}
+/*******************************************************************************
+* Copyright (c) 2019 NWO-I CWI
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Jurgen J. Vinju - initial implementation
+*******************************************************************************/
+package io.usethesource.vallang;
+
+import java.util.Iterator;
+import java.util.function.Function;
+
+import io.usethesource.vallang.exceptions.IllegalOperationException;
+import io.usethesource.vallang.type.Type;
+
+/**
+ * Provides Relational Calculus operators to an existing ICollection.
+ * This interface provides a generic implementation for all operators,
+ * which should be specialized by implementations that know how to optimize
+ * these operations with specialized data-structures.
+ *
+ * @param a collection value type like ISet or IList
+ */
+public interface IRelation> extends Iterable {
+
+ @Override
+ default Iterator iterator() {
+ return asContainer().iterator();
+ }
+
+ /**
+ * Relational composition works only on binary relations. It matches the second column
+ * of the receiver with the first column of the given relation.
+ * TODO: generalize to n-ary. Implementing classes should specialize
+ * this generic implementation for more efficiency.
+ *
+ * @param that is the given relation
+ * @return a new binary relation with first column of the accepting relation and the second column
+ * of the given relation, containing only tuples where the last column of the receiver
+ * matches the first column of the given relation.
+ */
+ public default C compose(IRelation that) {
+ C thisContainer = this.asContainer();
+ C thatContainer = that.asContainer();
+ Type thisElementType = thisContainer.getElementType();
+ Type thatElementType = thatContainer.getElementType();
+
+ if (thisElementType.isBottom()) {
+ return thisContainer;
+ }
+
+ if (thatElementType.isBottom()) {
+ return thatContainer;
+ }
+
+ if (thisElementType.getArity() != 2 || thatElementType.getArity() != 2) {
+ throw new IllegalOperationException("Incompatible types for composition.", thisElementType, thatElementType);
+ }
+
+ if (!thisElementType.getFieldType(1).comparable(thatElementType.getFieldType(0))) {
+ return asContainer().empty();
+ }
+
+ IWriter w = writer();
+
+ for (IValue elem1 : this) {
+ ITuple tuple1 = (ITuple) elem1;
+ for (IValue elem2 : that) {
+ ITuple tuple2 = (ITuple) elem2;
+ if (tuple1.get(1).equals(tuple2.get(0))) {
+ w.appendTuple(tuple1.get(0), tuple2.get(1));
+ }
+ }
+ }
+
+ return w.done();
+ }
+
+ /**
+ * @return the transitive non-reflexive closure of a binary relation
+ * @throws UnsupportedOperationException when the receiver is not a binary relation
+ */
+ public default C closure() {
+ if (!isBinary()) {
+ throw new UnsupportedOperationException("relation is not binary");
+ }
+
+ C next = this.asContainer();
+ IRelation result;
+
+ do {
+ result = next.asRelation();
+ next = result.compose(result).union(next);
+ } while (!next.equals(result.asContainer()));
+
+ return next;
+ }
+
+ /**
+ * @return the transitive reflexive closure of a binary relation
+ * @throws UnsupportedOperationException when the receiver is not a binary relation
+ */
+ public default C closureStar() {
+ IWriter w = writer();
+
+ for (IValue val : carrier()) {
+ w.appendTuple(val, val);
+ }
+ w.appendAll(closure());
+
+ return w.done();
+ }
+
+ /**
+ * @return the number of columns in the relation
+ */
+ default int arity() {
+ return asContainer().getElementType().getArity();
+ }
+
+ /**
+ * @return a new empty relation with the current factory
+ */
+ default C empty() {
+ return asContainer().empty();
+ }
+
+ /**
+ * Reduces an n-ary relation to fewer columns, given by the fields to select.
+ * @param fields to select from the relation, index starts at 0
+ * @return a new relation with only the columns selected by the fields parameter
+ */
+ default C project(int... fields) {
+ IWriter w = writer();
+
+ for (IValue v : this) {
+ w.append(((ITuple) v).select(fields));
+ }
+
+ return w.done();
+ }
+
+ /**
+ * Compute the carrier set of an n-ary relation.
+ * @return a container with all the elements of all tuples in the relation.
+ */
+ public default C carrier() {
+ IWriter w = writer().unique();
+
+ for (IValue t : this) {
+ w.appendAll((ITuple) t);
+ }
+
+ return w.done();
+ }
+
+ /**
+ * @return a container with the first elements of all tuples in the relation
+ */
+ public default C domain() {
+ IWriter w = asContainer().writer();
+
+ for (IValue elem : this) {
+ w.insert(((ITuple) elem).get(0));
+ }
+
+ return w.done();
+ }
+
+ /**
+ * @return a container with the last elements of all tuples in the relation
+ */
+ public default C range() {
+ int columnIndex = arity() - 1;
+ IWriter w = writer();
+
+ for (IValue elem : this) {
+ w.insert(((ITuple) elem).get(columnIndex));
+ }
+
+ return w.done();
+ }
+
+ /**
+ * Lookup the values by the first column in the relation
+ * @return a set of the second elements of all tuples where the first column is
+ * equal to the given key, without the first column.
+ *
+ * TODO: generalize to producing n-ary tuples.
+ */
+ public default C index(IValue key) {
+ C set1 = asContainer();
+ Type elementType = getElementType();
+
+ if (elementType.isBottom()) {
+ return set1.empty();
+ }
+
+ int valueArity = elementType.getArity() - 1;
+
+ Function mapper;
+ if (valueArity == 0) {
+ mapper = t -> t.get(1);
+ }
+ else {
+ int[] newTupleIndex = new int[valueArity];
+ for (int k = 1; k <= valueArity; k++) {
+ newTupleIndex[k - 1] = k;
+ }
+ mapper = t -> t.select(newTupleIndex);
+ }
+
+ IWriter result = writer();
+ for (IValue val : this) {
+ ITuple tup = (ITuple) val;
+ if (tup.get(0).equals(key)) {
+ result.insert(mapper.apply(tup));
+ }
+ }
+
+ return result.done();
+ }
+
+ /**
+ * @return the original container this IRelation is wrapping.
+ */
+ public C asContainer();
+
+ /**
+ * @return a fresh writer for the kind of container this IRelation is wrapping
+ */
+ public default IWriter writer() {
+ return asContainer().writer();
+ }
+
+ /**
+ * @return the element type of the container this IRelation is wrapping
+ */
+ public default Type getElementType() {
+ return asContainer().getElementType();
+ }
+
+ /**
+ * @return true iff the current relation is binary (has two columns)
+ */
+ default boolean isBinary() {
+ return getElementType().isBottom() || getElementType().getArity() == 2;
+ }
+}
diff --git a/src/main/java/io/usethesource/vallang/ISet.java b/src/main/java/io/usethesource/vallang/ISet.java
index 851585369..7b3aba3c4 100644
--- a/src/main/java/io/usethesource/vallang/ISet.java
+++ b/src/main/java/io/usethesource/vallang/ISet.java
@@ -20,14 +20,14 @@
import io.usethesource.vallang.visitors.IValueVisitor;
public interface ISet extends ICollection {
-
+
@Override
default int getMatchFingerprint() {
return 113762; // "set".hashCode()
}
/**
- * Add an element to the set.
+ * Add an element to the set.
* @param element
* @return a relation if the element type is a tuple type, a set otherwise
*/
@@ -58,7 +58,7 @@ public default ISet delete(IValue elem) {
}
return w.done();
}
-
+
/**
* Computes the Cartesian product of two sets
* @param set
@@ -76,13 +76,13 @@ public default ISet product(ISet that) {
return w.done();
}
-
+
@Override
public default boolean match(IValue other) {
if (other == this) {
return true;
}
-
+
if (other == null) {
return false;
}
@@ -105,7 +105,7 @@ public default boolean match(IValue other) {
return false;
}
-
+
/**
* Compute the union of two sets. To be overridden
* by implementations who know how to do this more efficiently.
@@ -130,7 +130,7 @@ public default ISet union(ISet that) {
w.insertAll(that);
return w.done();
}
-
+
/**
* Compute the intersection of two sets. To be overridden
* by implementations who know how to do this more efficiently.
@@ -159,7 +159,7 @@ public default ISet intersect(ISet that) {
return w.done();
}
-
+
/**
* Compute the difference of two sets by removing the elements of `that`
* from the receiver. To be implemented more efficiently if possible
@@ -188,13 +188,13 @@ public default ISet subtract(ISet that) {
return sw.done();
}
-
+
/**
* @param element
* @return true if this is an element of the set
*/
public boolean contains(IValue e);
-
+
/**
* @param element
* @return true if this set contains an element that matches (IValue.match) an element in this set
@@ -207,7 +207,7 @@ public default boolean containsMatch(IValue e) {
}
return false;
}
-
+
/**
* @param that other set to check for subset relation
* @return true if all elements of this set are elements of the other.
@@ -235,13 +235,13 @@ public default int defaultHashCode() {
return hash;
}
-
+
@EqualsMethod
public default boolean defaultEquals(@Nullable Object that) {
if (that == this) {
return true;
}
-
+
if (that == null) {
return false;
}
@@ -270,23 +270,23 @@ public default boolean defaultEquals(@Nullable Object that) {
return false;
}
-
+
@Override
default T accept(IValueVisitor v) throws E {
return v.visitSet(this);
}
-
+
@Override
default IRelation asRelation() {
if (!getType().isRelation()) {
throw new UnsupportedOperationException(getType() + " is not a relation");
}
-
+
return new IRelation() {
@Override
public String toString() {
return ISet.this.toString();
- }
+ }
@Override
public ISet asContainer() {
diff --git a/src/main/java/io/usethesource/vallang/ISourceLocation.java b/src/main/java/io/usethesource/vallang/ISourceLocation.java
index 9e677b9b3..828697bd1 100644
--- a/src/main/java/io/usethesource/vallang/ISourceLocation.java
+++ b/src/main/java/io/usethesource/vallang/ISourceLocation.java
@@ -22,82 +22,82 @@
*
* The part of the file is indicated by a character offset and length, as well as a
* line and column region. The reason for the redundancy is that each representation
- * can not be computed from the other without processing the entire file.
+ * can not be computed from the other without processing the entire file.
* The goal of this representation is to allow different kinds and implementations
- * of tools, such as editors, to easily jump to source locations.
+ * of tools, such as editors, to easily jump to source locations.
*/
public interface ISourceLocation extends IValue {
- /**
- * The {@link #top() top} method is preferred.
- * @return exact url where the source is located. The particular encoding of
- * the URL is not specified.
- */
+ /**
+ * The {@link #top() top} method is preferred.
+ * @return exact url where the source is located. The particular encoding of
+ * the URL is not specified.
+ */
public URI getURI();
/**
* @return the scheme of the URI
*/
public String getScheme();
-
+
/**
* @return the authority of the URI or "" if it does not exist
*/
- public String getAuthority();
-
- /**
- * @return the path of the URI or "" if it does not exist
- */
- public String getPath();
-
- /**
- * @return the fragment of the URI or "" if it does not exist
- */
- public String getFragment();
-
- /**
- * @return the query part of the URI or "" if it does not exist
- */
- public String getQuery();
-
- /**
- * @return true iff the URI has an authority part
- */
- public boolean hasAuthority();
-
- /**
+ public String getAuthority();
+
+ /**
+ * @return the path of the URI or "" if it does not exist
+ */
+ public String getPath();
+
+ /**
+ * @return the fragment of the URI or "" if it does not exist
+ */
+ public String getFragment();
+
+ /**
+ * @return the query part of the URI or "" if it does not exist
+ */
+ public String getQuery();
+
+ /**
+ * @return true iff the URI has an authority part
+ */
+ public boolean hasAuthority();
+
+ /**
* @return true iff the URI has an path part
*/
- public boolean hasPath();
-
- /**
+ public boolean hasPath();
+
+ /**
* @return true iff the URI has an fragment part
*/
- public boolean hasFragment();
-
- /**
+ public boolean hasFragment();
+
+ /**
* @return true iff the URI has a query part
*/
- public boolean hasQuery();
-
-
+ public boolean hasQuery();
+
+
/**
* @return true iff the source location has offset/length information stored with it.
*/
public boolean hasOffsetLength();
-
+
/**
- * @return true iff the source location has start/end line/column info. true implies that hasOffsetLength() will also
+ * @return true iff the source location has start/end line/column info. true implies that hasOffsetLength() will also
* return true.
*/
public boolean hasLineColumn();
-
+
/**
- * @return the character offset starting from the beginning of the file located
+ * @return the character offset starting from the beginning of the file located
* at the given url. Offsets start at 0 (zero).
* @throws UnsupportedOperationException
*/
public int getOffset();
-
+
/**
* @return the character length of the location (the amount characters).
* @throws UnsupportedOperationException
@@ -110,7 +110,7 @@ public interface ISourceLocation extends IValue {
* @throws UnsupportedOperationException
*/
public int getBeginLine();
-
+
/**
* @return the (exclusive) line where the location ends
* @throws UnsupportedOperationException
@@ -123,7 +123,7 @@ public interface ISourceLocation extends IValue {
* @throws UnsupportedOperationException
*/
public int getBeginColumn();
-
+
/**
* @return the (exclusive) column number where the location ends.
* @throws UnsupportedOperationException
@@ -134,7 +134,7 @@ public interface ISourceLocation extends IValue {
* @return the source location without any offset & length information.
*/
public ISourceLocation top();
-
+
@Override
default T accept(IValueVisitor v) throws E {
return v.visitSourceLocation(this);
diff --git a/src/main/java/io/usethesource/vallang/IString.java b/src/main/java/io/usethesource/vallang/IString.java
index 924790be7..cee3ef897 100644
--- a/src/main/java/io/usethesource/vallang/IString.java
+++ b/src/main/java/io/usethesource/vallang/IString.java
@@ -30,56 +30,56 @@ default int getMatchFingerprint() {
}
}
- /**
- * @return the Java string that this string represents
- */
+ /**
+ * @return the Java string that this string represents
+ */
public String getValue();
-
+
/**
* Concatenates two strings
*/
public IString concat(IString other);
-
+
/**
* Reverses a string
*/
public IString reverse();
/**
- * Computes the length of the string
- * @return amount of Unicode characters
+ * Computes the length of the string
+ * @return amount of Unicode characters
*/
public int length();
-
+
/**
* Computes a substring
- *
+ *
* @param start the inclusive start index
* @param end the exclusive end index
*/
public IString substring(int start, int end);
-
+
/**
* Computes a substring
- *
+ *
* @param start the inclusive start index
*/
public IString substring(int start);
-
+
/**
* Compares two strings lexicographically
* @param other
* @return -1 if receiver is less than other, 0 is receiver is equal, 1 if receiver is larger
*/
public int compare(IString other);
-
+
/**
* Returns the Unicode character at the given index.
* @param index an index into the string
* @return the Unicode character (in UTF-32)
*/
public int charAt(int index);
-
+
/**
* Replace the characters first, second ... end.
* Expected:
@@ -87,38 +87,38 @@ default int getMatchFingerprint() {
* - support for the case begin > end
* @param first inclusive index of first element
* @param second index of second element
- * @param end exclusive end index
- * @param repl the replacement string
+ * @param end exclusive end index
+ * @param repl the replacement string
* @param start the inclusive start index
* @return
*/
public IString replace(int first, int second, int end, IString repl);
-
+
/**
* Writes (in a streaming fashion) the content of this string to a character writer.
*/
public void write(Writer w) throws IOException;
-
+
/**
* Build an iterator which generates the Unicode UTF-32 codepoints of the IString one-by-one.
* @see Character for more information on Unicode UTF-32 codepoints.
*/
@Override
public OfInt iterator();
-
- /**
+
+ /**
* Indent all the non-empty lines in this string with the given whitespace. That means that
* after every newline character which is not immediately followed by another newline character
- * or the end of string, the whitespace string is inserted into the string.
- *
+ * or the end of string, the whitespace string is inserted into the string.
+ *
* Implementations of IString should ensure that indent itself is in O(1) and the constructed string
- * will {@link #write(Writer)} in O(n) where n is the length of the string.
+ * will {@link #write(Writer)} in O(n) where n is the length of the string.
* @param whiteSpace a non-empty string which certainly does not contain any \n characters, and expectedly only whitespace characters such as spaces and tabs
- * @param indentFirstLine indicates whether or not to indent the first line of the string. If true the line will be indented.
+ * @param indentFirstLine indicates whether or not to indent the first line of the string. If true the line will be indented.
* @return the current string indented with the given whitespace
*/
public IString indent(IString whitespace, boolean indentFirstLine);
-
+
@Override
default T accept(IValueVisitor v) throws E {
return v.visitString(this);
diff --git a/src/main/java/io/usethesource/vallang/ITuple.java b/src/main/java/io/usethesource/vallang/ITuple.java
index 37b715ce1..4d61d967a 100644
--- a/src/main/java/io/usethesource/vallang/ITuple.java
+++ b/src/main/java/io/usethesource/vallang/ITuple.java
@@ -23,46 +23,46 @@ default int getMatchFingerprint() {
/**
* Retrieve the given field at the given index.
- *
+ *
* @param i the index of the field, starting at 0
* @return the value at the given label in the tuple
* @throws IndexOutOfBoundsException
*/
public IValue get(int i);
-
+
@Deprecated
/**
* Retrieve the given field at the given label.
- *
+ *
* @param label the name of the field
* @return the value at the given label in the tuple
- *
- * TODO: this method will dissappear when field names will no longer be recorded
+ *
+ * TODO: this method will dissappear when field names will no longer be recorded
* the vallang library. This is necessary to be able to provide canonical types
* and use reference equality for type equality; a major factor in CPU performance.
*/
public IValue get(String label);
-
+
/**
* Replace the given field by a new value.
- *
+ *
* @param i the index of the field
* @param arg the new value
* @return
* @throws IndexOutOfBoundsException
*/
public ITuple set(int i, IValue arg);
-
+
@Deprecated
/**
* Replace the given field by a new value.
- *
+ *
* @param label the name of the field
* @param arg the new value
* @return
* @throws FactTypeUseException
- *
- * TODO: this method will dissappear when field names will no longer be recorded
+ *
+ * TODO: this method will dissappear when field names will no longer be recorded
* the vallang library. This is necessary to be able to provide canonical types
* and use reference equality for type equality; a major factor in CPU performance.
*/
@@ -79,19 +79,19 @@ default int getMatchFingerprint() {
* @return a new tuple with only the fields selected by the fields parameter
*/
public IValue select(int... fields) throws IndexOutOfBoundsException;
-
+
@Deprecated
/**
* Reduces an n-ary tuple to fewer fields, given by the field names to select.
* @param fields to select from the tuple
* @return a new tuple with only the fields selected by the fields parameter
- *
- * TODO: this method will dissappear when field names will no longer be recorded
+ *
+ * TODO: this method will dissappear when field names will no longer be recorded
* the vallang library. This is necessary to be able to provide canonical types
* and use reference equality for type equality; a major factor in CPU performance.
*/
public IValue selectByFieldNames(String... fields) throws FactTypeUseException;
-
+
@Override
public default boolean match(IValue o) {
if (this == o) {
@@ -118,7 +118,7 @@ public default boolean match(IValue o) {
}
return false;
}
-
+
@Override
default T accept(IValueVisitor v) throws E {
return v.visitTuple(this);
diff --git a/src/main/java/io/usethesource/vallang/IValue.java b/src/main/java/io/usethesource/vallang/IValue.java
index ba4674b51..b615a55f6 100644
--- a/src/main/java/io/usethesource/vallang/IValue.java
+++ b/src/main/java/io/usethesource/vallang/IValue.java
@@ -23,10 +23,10 @@
public interface IValue {
public static final TypeFactory TF = TypeFactory.getInstance();
-
- /**
- * @return the {@link Type} of a value
- */
+
+ /**
+ * @return the {@link Type} of a value
+ */
public Type getType();
/**
@@ -34,7 +34,7 @@ public interface IValue {
* or by the Rascal interpreter. The returned integer codes are opaque, although stable.
* If you need to know what kind of value you have, use the IValueVisitor or the ITypeVisitor
* interfaces and the `accept` methods on IValue and Type.
- *
+ *
* @return an integer code that:
* * accurate reflects the identity of the top-level structure of this value
* * such that if pattern.match(this) ===> pattern.getPatternMatchFingerprint() == this.getPatternMatchFingerprint()
@@ -44,10 +44,10 @@ public interface IValue {
default int getMatchFingerprint() {
return hashCode();
}
-
+
/**
* This method is used exclusively by code generated by the Rascal compiler,
- *
+ *
* @return an integer code that:
* * is guaranteed to be different from `getMatchFingerPrint`
* * is guaranteed to be constant
@@ -59,84 +59,84 @@ static int getDefaultMatchFingerprint() {
/**
* Execute the {@link IValueVisitor} on the current node
- *
+ *
* @param v the visitor to dispatch to
*/
public T accept(IValueVisitor v) throws E;
-
+
/**
* This method computes logical equality between IValues. That means that it
- * may equalize objects implemented by different classes implementing the
+ * may equalize objects implemented by different classes implementing the
* same interface. It does uphold Java's equals/hashCode contract, nevertheless.
- *
+ *
* In particular, lazy intermediate representations of IList, ISet or IString would
* lead to IValue objects being equal even though their internal structure differs greatly.
* Implementors should think hard how to uphold equals/hashCode contract in such cases.
- *
+ *
* A note on subtitutability: given that IValue's are immutable, and this equals method
* implements an equivalence relation and that it upholds the hashCode/equals contract:
* if equals(a,b) then a is substitutable for b and vice versa in _any_ context. This implies
- * full referential transparancy as well.
- *
+ * full referential transparancy as well.
+ *
* On the computational complexity of equals: although equality is worst case linear,
- * implementations are expected to fail fast, and succeed fast. In particular the implementations
- * based on persistent and shared data-structures are expected to test for reference equality at every
- * level in a value. The expected/average complexity of equals should be around log(size), as a result.
- *
+ * implementations are expected to fail fast, and succeed fast. In particular the implementations
+ * based on persistent and shared data-structures are expected to test for reference equality at every
+ * level in a value. The expected/average complexity of equals should be around log(size), as a result.
+ *
* @param other object to compare to
* @return true iff the other value is logically equal to the receiver object
*/
@Override
public boolean equals(@Nullable Object other);
-
+
/**
* Another notion of equality which ignores secondary information:
- * namely, keyword parameters (either top-level or deeply nested).
- *
+ * namely, keyword parameters (either top-level or deeply nested).
+ *
* The intention is for this notion of equality to match what the notion of pattern
* matching is in the Rascal language. In this case the receiver acts
* as a "pattern" for the argument.
- *
+ *
* The following theories hold:
- *
+ *
*
- . a.equals(b) ==> a.match(b) // and not the inverse
* - match() is an equivalence relation
*
- *
+ *
* Note that the match() algorithm is linear in the size of the smallest of the
* two values, but implementations are expected to fail fast and succeed fast where
* possible (checking for reference equality on the way).
- *
+ *
* @param other value to compare to
* @return true iff the other value is equal to the other value, while
- * ignoring all "non-structural" details such the presence of keyword
+ * ignoring all "non-structural" details such the presence of keyword
* parameters.
*/
public default boolean match(IValue other) {
return equals(other);
}
-
+
/**
* Prints the value to a string using the {@link StandardTextWriter}
*/
public String toString();
-
+
/**
* @return if this {@link IValue} object may have keyword parameters
*/
public default boolean mayHaveKeywordParameters() {
return false;
}
-
+
/**
- * Creates a view that exposes the {@link IWithKeywordParameters} annotation API.
- *
- * @return an {@link IWithKeywordParameters} view on this {@link IValue} object
+ * Creates a view that exposes the {@link IWithKeywordParameters} annotation API.
+ *
+ * @return an {@link IWithKeywordParameters} view on this {@link IValue} object
*/
public default IWithKeywordParameters extends IValue> asWithKeywordParameters() {
throw new UnsupportedOperationException(getType() + " does not support keyword parameters.");
}
-
+
/**
* This is how all IValue implementations should be printed.
* @return the literal expression format of the value as a string
diff --git a/src/main/java/io/usethesource/vallang/IValueFactory.java b/src/main/java/io/usethesource/vallang/IValueFactory.java
index f126af417..1653b8614 100644
--- a/src/main/java/io/usethesource/vallang/IValueFactory.java
+++ b/src/main/java/io/usethesource/vallang/IValueFactory.java
@@ -26,607 +26,607 @@
* class should guarantee that the values returned are immutable. For batch
* construction of container classes there should be implementations of the
* I{List,Set,Relation,Map}Writer interfaces.
- *
+ *
* @author jurgen@vinju.org
* @author rfuhrer@watson.ibm.com
- *
+ *
*/
public interface IValueFactory {
- /**
- * Constructs an integer from the decimal representation.
- *
- * @param i
- * integer as a string of decimal digits
- * @return a new integer
- * @throws NumberFormatException
- */
- public IInteger integer(String i) throws NumberFormatException;
-
- /**
- * @param i
- * @return a value representing the integer i, with type IntegerType
- */
- public IInteger integer(int i);
-
- /**
- * @param i
- * @return a value representing the integer i, with type IntegerType
- */
- public IInteger integer(long i);
-
- /**
- * Construct an integer from the two's complement big-endian representation
- *
- * @param a
- * @return a value representing the two's complement notation in a
- */
- public IInteger integer(byte[] a);
-
- /**
- * @param a
- * @param b
- * @return a value representing the rational a/b, with type RationalType
- */
- public IRational rational(int a, int b);
-
- /**
- * @param a
- * @param b
- * @return a value representing the rational a/b, with type RationalType
- */
- public IRational rational(long a, long b);
-
- /**
- * @param a
- * @param b
- * @return a value representing the rational a/b, with type RationalType
- */
- public IRational rational(IInteger a, IInteger b);
-
- /**
- * @param rat
- * @return a value representing the rational rat, with type RationalType
- */
- public IRational rational(String rat) throws NumberFormatException;
-
- /**
- * Construct a real from the mathematical notation.
- *
- * @param s
- * real as a string in decimal mathematical notation.
- * @return the corresponding real
- * @throws NumberFormatException
- */
- public IReal real(String s) throws NumberFormatException;
-
- /**
- * Construct a real from the mathematical notation.
- *
- * @param s
- * real as a string in decimal mathematical notation.
- * @param p
- * precision
- * @return the corresponding real
- * @throws NumberFormatException
- */
- public IReal real(String s, int p) throws NumberFormatException;
-
- /**
- * @param d
- * @return a value representing the double d, with type RealType
- */
- public IReal real(double d);
-
- /**
- * @param d
- * @param p
- * precision
- * @return a value representing the double d, with type RealType
- */
- public IReal real(double d, int p);
-
- /**
- * @return the global precision for reals
- */
- public int getPrecision();
-
- /**
- * Set the global precision for reals
- *
- * @param p
- * @return the previous global precision
- */
- public int setPrecision(int p);
-
- /**
- * @param precision
- * (max of 1000)
- * @return PI with a higher precision than standard Math.PI
- */
- public IReal pi(int precision);
-
- /**
- * @param precision
- * (max of 1000)
- * @return E with a higher precision than standard Math.E
- */
- public IReal e(int precision);
-
- /**
- * @param s
- * @return a value representing the string s, with type StringType
- */
- public IString string(String s);
-
- /**
- * Build a string from an array of unicode characters.
- *
- * @param chars
- * array of unicode characters
- * @throws IllegalArgumentException
- * if one of the characters in chars is not a valid codePoint
- */
- public IString string(int[] chars) throws IllegalArgumentException;
-
- /**
- * Build a string from a unicode character.
- *
- * @param ch
- * unicode character
- * @throws IllegalArgumentException
- * when ch is not a valid codePoint
- */
- public IString string(int ch) throws IllegalArgumentException;
-
- /**
- * Create an exact reference to a source location.
- *
- * @param uri
- * exact uri where the source is located.
- * @param offset
- * the character offset starting from the beginning of the file
- * located at the given url. Offsets start at 0 (zero).
- * @param length
- * the character length of the location (the amount characters).
- * @param beginLine
- * the (inclusive) line number where the location begins. The
- * first line is always line number 1.
- * @param endLine
- * the (exclusive) line where the location ends
- * @param beginCol
- * the (inclusive) column number where the location begins. The
- * first column is always column number 0 (zero).
- * @param endCol
- * the (exclusive) column number where the location ends.
- * @return a value representing a source location, with type
- * SourceLocationType
- * @deprecated please use the overload with a ISourceLocation
- */
- @Deprecated
- public ISourceLocation sourceLocation(URI uri, int offset, int length,
- int beginLine, int endLine, int beginCol, int endCol);
-
- /**
- * Create an exact reference to a source location.
- *
- * @param loc
- * where the source is located. (only the location part of the source location is used)
- * @param offset
- * the character offset starting from the beginning of the file
- * located at the given url. Offsets start at 0 (zero).
- * @param length
- * the character length of the location (the amount characters).
- * @param beginLine
- * the (inclusive) line number where the location begins. The
- * first line is always line number 1.
- * @param endLine
- * the (exclusive) line where the location ends
- * @param beginCol
- * the (inclusive) column number where the location begins. The
- * first column is always column number 0 (zero).
- * @param endCol
- * the (exclusive) column number where the location ends.
- * @return a value representing a source location, with type
- * SourceLocationType
- */
- public ISourceLocation sourceLocation(ISourceLocation loc, int offset,
- int length, int beginLine, int endLine, int beginCol, int endCol);
-
- /**
- * Create an exact reference to a source location.
- *
- * @param uri
- * exact uri where the source is located.
- * @param offset
- * the character offset starting from the beginning of the file
- * located at the given url. Offsets start at 0 (zero).
- * @param length
- * the character length of the location (the amount characters).
- *
- * @return a value representing a source location, with type
- * SourceLocationType
- * @deprecated please use the overload with a ISourceLocation
- */
- @Deprecated
- public ISourceLocation sourceLocation(URI uri, int offset, int length);
-
- /**
- * Create an exact reference to a source location.
- *
- * @param loc
- * where the source is located. (only the location part of the source location is used)
- * @param offset
- * the character offset starting from the beginning of the file
- * located at the given url. Offsets start at 0 (zero).
- * @param length
- * the character length of the location (the amount characters).
- *
- * @return a value representing a source location, with type
- * SourceLocationType
- */
- public ISourceLocation sourceLocation(ISourceLocation loc, int offset, int length);
-
- /**
- * Create an exact reference to a source location.
- *
- * @param path
- * exact (absolute) path where the source is located.
- * @param offset
- * the character offset starting from the beginning of the file
- * located at the given url. Offsets start at 0 (zero).
- * @param length
- * the character length of the location (the amount characters).
- * @param beginLine
- * the (inclusive) line number where the location begins. The
- * first line is always line number 1.
- * @param endLine
- * the (exclusive) line where the location ends
- * @param beginCol
- * the (inclusive) column number where the location begins. The
- * first column is always column number 0 (zero).
- * @param endCol
- * the (exclusive) column number where the location ends.
- * @return a value representing a source location, with type
- * SourceLocationType
- */
- public ISourceLocation sourceLocation(String path, int offset, int length,
- int beginLine, int endLine, int beginCol, int endCol);
-
- /**
- * Create an exact reference to a source location.
- *
- * @param uri
- * exact uri where the source is located.
- * @return a value representing a source location, with type
- * SourceLocationType
- */
- public ISourceLocation sourceLocation(URI uri);
-
- /**
- * Create an exact reference to a source location
- *
- * note that we assume non-encoded input
- *
- * @param scheme
- * the scheme part of an source location
- * @param authority
- * the authority part of an source location
- * @param path
- * the path part of an source location
- * @return
- */
- public ISourceLocation sourceLocation(String scheme, String authority, String path) throws URISyntaxException;
-
- /**
- * Create an exact reference to a source location
- *
- * note that we assume non-encoded input
- *
- * @param scheme
- * the scheme part of an source location
- * @param authority
- * the authority part of an source location
- * @param path
- * the path part of an source location
- * @param query
- * the query part of an source location
- * @param fragment
- * the fragment part of an source location
- * @return
- */
- public ISourceLocation sourceLocation(String scheme, String authority,
- String path, @Nullable String query, @Nullable String fragment)
- throws URISyntaxException;
-
- /**
- * Create an exact reference to a source location.
- *
- * @param path
- * exact (absolute) path where the source is located.
- * @return a value representing a source location, with type
- * SourceLocationType
- */
- public ISourceLocation sourceLocation(String path);
-
- /**
- * Construct the nullary tuple
- *
- * @return the nullary tuple
- */
- public ITuple tuple();
-
- /**
- * Construct a tuple
- *
- * @param args
- * a variable length argument list or an array of IValue
- * @return a tuple with as many children as there are args
- */
- public ITuple tuple(IValue... args);
-
- /**
- * Construct a nullary generic tree node
- *
- * @param name
- * the name of the tree node
- * @return a new tree value
- */
- public INode node(String name);
-
- /**
- * Construct a node
- *
- * @param name
- * the name of the node
- * @param children
- * the edges (children) of the node
- * @return a new tree node
- */
- public INode node(String name, IValue... children);
-
- /**
- * Construct a node with keyword arguments
- *
- * @param name
- * the name of the node
- * @param keyArgValues
- * to immediately put on the constructor
- * @param keyArgValues
- * the keyword parameters with their values
- * @param children
- * an array or variable length argument list of children
- * @return a new tree value
- * @throws FactTypeUseException
- * if the children are not of the expected types for this node
- * type
- */
- public INode node(String name, IValue[] children, Map keyArgValues);
-
- /**
- * Make a nullary constructor (a typed nullary node)
- *
- * @param constructor
- * the constructor to use
- * @return a new constructor value
- */
- public IConstructor constructor(Type constructor);
-
- /**
- * Make a constructor value.
- *
- * @param constructor
- * the constructor to use
- * @param children
- * an array or variable length argument list of children
- * @return a new tree value
- * @throws FactTypeUseException
- * if the children are not of the expected types for this node
- * type
- */
- public IConstructor constructor(Type constructor, IValue... children);
-
- /**
- * Make a constructor value with keyword parameters
- *
- * @param constructor
- * the constructor to use
- * @param children
- * an array or variable length argument list of children
- * @param kwParams keyword parameters
- * @return a new tree value
- * @throws FactTypeUseException
- * if the children are not of the expected types for this node
- * type
- */
- public IConstructor constructor(Type constructor, IValue[] children, Map kwParams);
-
- /**
- * Get a set writer of which the element type will be the least upper bound
- * of the element types
- *
- * @return a set writer
- */
- public ISetWriter setWriter();
-
- /**
- * Construct a set with a fixed number of elements in it. If the elements
- * are compatible tuples, this will construct a relation.
- *
- * @param elems
- * an array or variable argument list of values
- * @return a set containing all the elements
- */
- public ISet set(IValue... elems);
-
- /**
- * Get a list writer of which the element type will be the least upper bound
- * of the element types
- *
- * @return a list writer
- */
- public IListWriter listWriter();
-
- /**
- * Construct a list with a fixed number of elements in it.
- *
- * @param elems
- * the elements to put in the list
- * @return a list [a] of type list[a.getType()]
- */
- public IList list(IValue... elems);
-
- /**
- * Get a map writer of which the key and value types will be the least upper
- * bound of the keys and values that are put in.
- *
- * @return a list writer
- */
- public IMapWriter mapWriter();
-
- /**
- * @return an empty map
- */
- public default IMap map() {
- return mapWriter().done();
- }
-
- /**
- * Create a boolean with a certain value
- *
- * @return a boolean
- */
- public IBool bool(boolean value);
-
- /**
- * Create a new DateTime representing a date with the given date fields
- *
- * @param year
- * the year of the date
- * @param month
- * the month of the date
- * @param day
- * the day of the date
- *
- * @return a DateTime date with the provided year, month, and day
- */
- public IDateTime date(int year, int month, int day);
-
- /**
- * Create a new DateTime representing a time with the given time fields
- *
- * @param hour
- * the hour of the time
- * @param minute
- * the minute of the time
- * @param second
- * the second of the time
- * @param millisecond
- * the millisecond of the time
- *
- * @return a DateTime time with the provided hour, minute, second, and
- * milliseconds
- */
- public IDateTime time(int hour, int minute, int second, int millisecond);
-
- /**
- * Create a new DateTime representing a time with the given time fields
- *
- * @param hour
- * the hour of the time
- * @param minute
- * the minute of the time
- * @param second
- * the second of the time
- * @param millisecond
- * the millisecond of the time
- * @param hourOffset
- * the hour offset of the timezone for this time (can be
- * negative)
- * @param minuteOffset
- * the minute offset of the timezone for this time (can be
- * negative if the hourOffset is 0)
- *
- * @return a DateTime time with the provided hour, minute, second,
- * milliseconds, and timezone offset
- */
- public IDateTime time(int hour, int minute, int second, int millisecond,
- int hourOffset, int minuteOffset);
-
- /**
- * Create a new DateTime with the given date and time fields
- *
- * @param year
- * the year of the date
- * @param month
- * the month of the date
- * @param day
- * the day of the date
- * @param hour
- * the hour of the time
- * @param minute
- * the minute of the time
- * @param second
- * the second of the time
- * @param millisecond
- * the millisecond of the time
- *
- * @return a DateTime with the values for year, month, etc provided in the
- * parameters
- */
- public IDateTime datetime(int year, int month, int day, int hour,
- int minute, int second, int millisecond);
-
- /**
- * Create a new DateTime with the given date and time fields
- *
- * @param year
- * the year of the date
- * @param month
- * the month of the date
- * @param day
- * the day of the date
- * @param hour
- * the hour of the time
- * @param minute
- * the minute of the time
- * @param second
- * the second of the time
- * @param millisecond
- * the millisecond of the time
- * @param hourOffset
- * the hour offset of the timezone for this time (can be
- * negative)
- * @param minuteOffset
- * the minute offset of the timezone for this time (can be
- * negative if the hourOffset is 0)
- *
- * @return a DateTime with the values for year, month, etc provided in the
- * parameters
- */
- public IDateTime datetime(int year, int month, int day, int hour,
- int minute, int second, int millisecond, int hourOffset,
- int minuteOffset);
-
- /**
- * Create a new DateTime representing the given instant.
- *
- * @param instant
- * the instant in time, according to the Java epoch
- *
- * @return a DateTime set to the given instant in time
- */
- public IDateTime datetime(long instant);
-
- /**
- * Create a new DateTime representing the given instant.
- *
- * @param instant
- * the instant in time, according to the Java epoch
- * @param timezoneHours The hour offset for the new object's timezone
- * @param timezoneMinutes The minute offset for the new object's timezone
- *
- * @return a DateTime set to the given instant in time
- */
- public IDateTime datetime(long instant, int timezoneHours, int timezoneMinutes);
+ /**
+ * Constructs an integer from the decimal representation.
+ *
+ * @param i
+ * integer as a string of decimal digits
+ * @return a new integer
+ * @throws NumberFormatException
+ */
+ public IInteger integer(String i) throws NumberFormatException;
+
+ /**
+ * @param i
+ * @return a value representing the integer i, with type IntegerType
+ */
+ public IInteger integer(int i);
+
+ /**
+ * @param i
+ * @return a value representing the integer i, with type IntegerType
+ */
+ public IInteger integer(long i);
+
+ /**
+ * Construct an integer from the two's complement big-endian representation
+ *
+ * @param a
+ * @return a value representing the two's complement notation in a
+ */
+ public IInteger integer(byte[] a);
+
+ /**
+ * @param a
+ * @param b
+ * @return a value representing the rational a/b, with type RationalType
+ */
+ public IRational rational(int a, int b);
+
+ /**
+ * @param a
+ * @param b
+ * @return a value representing the rational a/b, with type RationalType
+ */
+ public IRational rational(long a, long b);
+
+ /**
+ * @param a
+ * @param b
+ * @return a value representing the rational a/b, with type RationalType
+ */
+ public IRational rational(IInteger a, IInteger b);
+
+ /**
+ * @param rat
+ * @return a value representing the rational rat, with type RationalType
+ */
+ public IRational rational(String rat) throws NumberFormatException;
+
+ /**
+ * Construct a real from the mathematical notation.
+ *
+ * @param s
+ * real as a string in decimal mathematical notation.
+ * @return the corresponding real
+ * @throws NumberFormatException
+ */
+ public IReal real(String s) throws NumberFormatException;
+
+ /**
+ * Construct a real from the mathematical notation.
+ *
+ * @param s
+ * real as a string in decimal mathematical notation.
+ * @param p
+ * precision
+ * @return the corresponding real
+ * @throws NumberFormatException
+ */
+ public IReal real(String s, int p) throws NumberFormatException;
+
+ /**
+ * @param d
+ * @return a value representing the double d, with type RealType
+ */
+ public IReal real(double d);
+
+ /**
+ * @param d
+ * @param p
+ * precision
+ * @return a value representing the double d, with type RealType
+ */
+ public IReal real(double d, int p);
+
+ /**
+ * @return the global precision for reals
+ */
+ public int getPrecision();
+
+ /**
+ * Set the global precision for reals
+ *
+ * @param p
+ * @return the previous global precision
+ */
+ public int setPrecision(int p);
+
+ /**
+ * @param precision
+ * (max of 1000)
+ * @return PI with a higher precision than standard Math.PI
+ */
+ public IReal pi(int precision);
+
+ /**
+ * @param precision
+ * (max of 1000)
+ * @return E with a higher precision than standard Math.E
+ */
+ public IReal e(int precision);
+
+ /**
+ * @param s
+ * @return a value representing the string s, with type StringType
+ */
+ public IString string(String s);
+
+ /**
+ * Build a string from an array of unicode characters.
+ *
+ * @param chars
+ * array of unicode characters
+ * @throws IllegalArgumentException
+ * if one of the characters in chars is not a valid codePoint
+ */
+ public IString string(int[] chars) throws IllegalArgumentException;
+
+ /**
+ * Build a string from a unicode character.
+ *
+ * @param ch
+ * unicode character
+ * @throws IllegalArgumentException
+ * when ch is not a valid codePoint
+ */
+ public IString string(int ch) throws IllegalArgumentException;
+
+ /**
+ * Create an exact reference to a source location.
+ *
+ * @param uri
+ * exact uri where the source is located.
+ * @param offset
+ * the character offset starting from the beginning of the file
+ * located at the given url. Offsets start at 0 (zero).
+ * @param length
+ * the character length of the location (the amount characters).
+ * @param beginLine
+ * the (inclusive) line number where the location begins. The
+ * first line is always line number 1.
+ * @param endLine
+ * the (exclusive) line where the location ends
+ * @param beginCol
+ * the (inclusive) column number where the location begins. The
+ * first column is always column number 0 (zero).
+ * @param endCol
+ * the (exclusive) column number where the location ends.
+ * @return a value representing a source location, with type
+ * SourceLocationType
+ * @deprecated please use the overload with a ISourceLocation
+ */
+ @Deprecated
+ public ISourceLocation sourceLocation(URI uri, int offset, int length,
+ int beginLine, int endLine, int beginCol, int endCol);
+
+ /**
+ * Create an exact reference to a source location.
+ *
+ * @param loc
+ * where the source is located. (only the location part of the source location is used)
+ * @param offset
+ * the character offset starting from the beginning of the file
+ * located at the given url. Offsets start at 0 (zero).
+ * @param length
+ * the character length of the location (the amount characters).
+ * @param beginLine
+ * the (inclusive) line number where the location begins. The
+ * first line is always line number 1.
+ * @param endLine
+ * the (exclusive) line where the location ends
+ * @param beginCol
+ * the (inclusive) column number where the location begins. The
+ * first column is always column number 0 (zero).
+ * @param endCol
+ * the (exclusive) column number where the location ends.
+ * @return a value representing a source location, with type
+ * SourceLocationType
+ */
+ public ISourceLocation sourceLocation(ISourceLocation loc, int offset,
+ int length, int beginLine, int endLine, int beginCol, int endCol);
+
+ /**
+ * Create an exact reference to a source location.
+ *
+ * @param uri
+ * exact uri where the source is located.
+ * @param offset
+ * the character offset starting from the beginning of the file
+ * located at the given url. Offsets start at 0 (zero).
+ * @param length
+ * the character length of the location (the amount characters).
+ *
+ * @return a value representing a source location, with type
+ * SourceLocationType
+ * @deprecated please use the overload with a ISourceLocation
+ */
+ @Deprecated
+ public ISourceLocation sourceLocation(URI uri, int offset, int length);
+
+ /**
+ * Create an exact reference to a source location.
+ *
+ * @param loc
+ * where the source is located. (only the location part of the source location is used)
+ * @param offset
+ * the character offset starting from the beginning of the file
+ * located at the given url. Offsets start at 0 (zero).
+ * @param length
+ * the character length of the location (the amount characters).
+ *
+ * @return a value representing a source location, with type
+ * SourceLocationType
+ */
+ public ISourceLocation sourceLocation(ISourceLocation loc, int offset, int length);
+
+ /**
+ * Create an exact reference to a source location.
+ *
+ * @param path
+ * exact (absolute) path where the source is located.
+ * @param offset
+ * the character offset starting from the beginning of the file
+ * located at the given url. Offsets start at 0 (zero).
+ * @param length
+ * the character length of the location (the amount characters).
+ * @param beginLine
+ * the (inclusive) line number where the location begins. The
+ * first line is always line number 1.
+ * @param endLine
+ * the (exclusive) line where the location ends
+ * @param beginCol
+ * the (inclusive) column number where the location begins. The
+ * first column is always column number 0 (zero).
+ * @param endCol
+ * the (exclusive) column number where the location ends.
+ * @return a value representing a source location, with type
+ * SourceLocationType
+ */
+ public ISourceLocation sourceLocation(String path, int offset, int length,
+ int beginLine, int endLine, int beginCol, int endCol);
+
+ /**
+ * Create an exact reference to a source location.
+ *
+ * @param uri
+ * exact uri where the source is located.
+ * @return a value representing a source location, with type
+ * SourceLocationType
+ */
+ public ISourceLocation sourceLocation(URI uri);
+
+ /**
+ * Create an exact reference to a source location
+ *
+ * note that we assume non-encoded input
+ *
+ * @param scheme
+ * the scheme part of an source location
+ * @param authority
+ * the authority part of an source location
+ * @param path
+ * the path part of an source location
+ * @return
+ */
+ public ISourceLocation sourceLocation(String scheme, String authority, String path) throws URISyntaxException;
+
+ /**
+ * Create an exact reference to a source location
+ *
+ * note that we assume non-encoded input
+ *
+ * @param scheme
+ * the scheme part of an source location
+ * @param authority
+ * the authority part of an source location
+ * @param path
+ * the path part of an source location
+ * @param query
+ * the query part of an source location
+ * @param fragment
+ * the fragment part of an source location
+ * @return
+ */
+ public ISourceLocation sourceLocation(String scheme, String authority,
+ String path, @Nullable String query, @Nullable String fragment)
+ throws URISyntaxException;
+
+ /**
+ * Create an exact reference to a source location.
+ *
+ * @param path
+ * exact (absolute) path where the source is located.
+ * @return a value representing a source location, with type
+ * SourceLocationType
+ */
+ public ISourceLocation sourceLocation(String path);
+
+ /**
+ * Construct the nullary tuple
+ *
+ * @return the nullary tuple
+ */
+ public ITuple tuple();
+
+ /**
+ * Construct a tuple
+ *
+ * @param args
+ * a variable length argument list or an array of IValue
+ * @return a tuple with as many children as there are args
+ */
+ public ITuple tuple(IValue... args);
+
+ /**
+ * Construct a nullary generic tree node
+ *
+ * @param name
+ * the name of the tree node
+ * @return a new tree value
+ */
+ public INode node(String name);
+
+ /**
+ * Construct a node
+ *
+ * @param name
+ * the name of the node
+ * @param children
+ * the edges (children) of the node
+ * @return a new tree node
+ */
+ public INode node(String name, IValue... children);
+
+ /**
+ * Construct a node with keyword arguments
+ *
+ * @param name
+ * the name of the node
+ * @param keyArgValues
+ * to immediately put on the constructor
+ * @param keyArgValues
+ * the keyword parameters with their values
+ * @param children
+ * an array or variable length argument list of children
+ * @return a new tree value
+ * @throws FactTypeUseException
+ * if the children are not of the expected types for this node
+ * type
+ */
+ public INode node(String name, IValue[] children, Map keyArgValues);
+
+ /**
+ * Make a nullary constructor (a typed nullary node)
+ *
+ * @param constructor
+ * the constructor to use
+ * @return a new constructor value
+ */
+ public IConstructor constructor(Type constructor);
+
+ /**
+ * Make a constructor value.
+ *
+ * @param constructor
+ * the constructor to use
+ * @param children
+ * an array or variable length argument list of children
+ * @return a new tree value
+ * @throws FactTypeUseException
+ * if the children are not of the expected types for this node
+ * type
+ */
+ public IConstructor constructor(Type constructor, IValue... children);
+
+ /**
+ * Make a constructor value with keyword parameters
+ *
+ * @param constructor
+ * the constructor to use
+ * @param children
+ * an array or variable length argument list of children
+ * @param kwParams keyword parameters
+ * @return a new tree value
+ * @throws FactTypeUseException
+ * if the children are not of the expected types for this node
+ * type
+ */
+ public IConstructor constructor(Type constructor, IValue[] children, Map kwParams);
+
+ /**
+ * Get a set writer of which the element type will be the least upper bound
+ * of the element types
+ *
+ * @return a set writer
+ */
+ public ISetWriter setWriter();
+
+ /**
+ * Construct a set with a fixed number of elements in it. If the elements
+ * are compatible tuples, this will construct a relation.
+ *
+ * @param elems
+ * an array or variable argument list of values
+ * @return a set containing all the elements
+ */
+ public ISet set(IValue... elems);
+
+ /**
+ * Get a list writer of which the element type will be the least upper bound
+ * of the element types
+ *
+ * @return a list writer
+ */
+ public IListWriter listWriter();
+
+ /**
+ * Construct a list with a fixed number of elements in it.
+ *
+ * @param elems
+ * the elements to put in the list
+ * @return a list [a] of type list[a.getType()]
+ */
+ public IList list(IValue... elems);
+
+ /**
+ * Get a map writer of which the key and value types will be the least upper
+ * bound of the keys and values that are put in.
+ *
+ * @return a list writer
+ */
+ public IMapWriter mapWriter();
+
+ /**
+ * @return an empty map
+ */
+ public default IMap map() {
+ return mapWriter().done();
+ }
+
+ /**
+ * Create a boolean with a certain value
+ *
+ * @return a boolean
+ */
+ public IBool bool(boolean value);
+
+ /**
+ * Create a new DateTime representing a date with the given date fields
+ *
+ * @param year
+ * the year of the date
+ * @param month
+ * the month of the date
+ * @param day
+ * the day of the date
+ *
+ * @return a DateTime date with the provided year, month, and day
+ */
+ public IDateTime date(int year, int month, int day);
+
+ /**
+ * Create a new DateTime representing a time with the given time fields
+ *
+ * @param hour
+ * the hour of the time
+ * @param minute
+ * the minute of the time
+ * @param second
+ * the second of the time
+ * @param millisecond
+ * the millisecond of the time
+ *
+ * @return a DateTime time with the provided hour, minute, second, and
+ * milliseconds
+ */
+ public IDateTime time(int hour, int minute, int second, int millisecond);
+
+ /**
+ * Create a new DateTime representing a time with the given time fields
+ *
+ * @param hour
+ * the hour of the time
+ * @param minute
+ * the minute of the time
+ * @param second
+ * the second of the time
+ * @param millisecond
+ * the millisecond of the time
+ * @param hourOffset
+ * the hour offset of the timezone for this time (can be
+ * negative)
+ * @param minuteOffset
+ * the minute offset of the timezone for this time (can be
+ * negative if the hourOffset is 0)
+ *
+ * @return a DateTime time with the provided hour, minute, second,
+ * milliseconds, and timezone offset
+ */
+ public IDateTime time(int hour, int minute, int second, int millisecond,
+ int hourOffset, int minuteOffset);
+
+ /**
+ * Create a new DateTime with the given date and time fields
+ *
+ * @param year
+ * the year of the date
+ * @param month
+ * the month of the date
+ * @param day
+ * the day of the date
+ * @param hour
+ * the hour of the time
+ * @param minute
+ * the minute of the time
+ * @param second
+ * the second of the time
+ * @param millisecond
+ * the millisecond of the time
+ *
+ * @return a DateTime with the values for year, month, etc provided in the
+ * parameters
+ */
+ public IDateTime datetime(int year, int month, int day, int hour,
+ int minute, int second, int millisecond);
+
+ /**
+ * Create a new DateTime with the given date and time fields
+ *
+ * @param year
+ * the year of the date
+ * @param month
+ * the month of the date
+ * @param day
+ * the day of the date
+ * @param hour
+ * the hour of the time
+ * @param minute
+ * the minute of the time
+ * @param second
+ * the second of the time
+ * @param millisecond
+ * the millisecond of the time
+ * @param hourOffset
+ * the hour offset of the timezone for this time (can be
+ * negative)
+ * @param minuteOffset
+ * the minute offset of the timezone for this time (can be
+ * negative if the hourOffset is 0)
+ *
+ * @return a DateTime with the values for year, month, etc provided in the
+ * parameters
+ */
+ public IDateTime datetime(int year, int month, int day, int hour,
+ int minute, int second, int millisecond, int hourOffset,
+ int minuteOffset);
+
+ /**
+ * Create a new DateTime representing the given instant.
+ *
+ * @param instant
+ * the instant in time, according to the Java epoch
+ *
+ * @return a DateTime set to the given instant in time
+ */
+ public IDateTime datetime(long instant);
+
+ /**
+ * Create a new DateTime representing the given instant.
+ *
+ * @param instant
+ * the instant in time, according to the Java epoch
+ * @param timezoneHours The hour offset for the new object's timezone
+ * @param timezoneMinutes The minute offset for the new object's timezone
+ *
+ * @return a DateTime set to the given instant in time
+ */
+ public IDateTime datetime(long instant, int timezoneHours, int timezoneMinutes);
}
diff --git a/src/main/java/io/usethesource/vallang/IWithKeywordParameters.java b/src/main/java/io/usethesource/vallang/IWithKeywordParameters.java
index 1dc772c5c..61ef669a4 100644
--- a/src/main/java/io/usethesource/vallang/IWithKeywordParameters.java
+++ b/src/main/java/io/usethesource/vallang/IWithKeywordParameters.java
@@ -8,7 +8,7 @@
* Contributors:
*
* * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI
- * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
+ * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
*******************************************************************************/
package io.usethesource.vallang;
@@ -19,76 +19,76 @@
public interface IWithKeywordParameters {
- /**
- * Get the value of a parmeter
- *
- * @param label identifies the parameter
- * @return a value if the parameter has a value on this node or null otherwise
- */
- public @Nullable IValue getParameter(String label);
-
- /**
- * Set the value of an parameter
- *
- * @param label identifies the parameter
- * @param newValue the new value for the parameter
- * @return a new node where the value of the parameter is replaced (if previously present) or newly added
- * @throws FactTypeUseException when the type of the new value is not comparable to the old parameter value
- */
- public T setParameter(String label, IValue newValue);
+ /**
+ * Get the value of a parmeter
+ *
+ * @param label identifies the parameter
+ * @return a value if the parameter has a value on this node or null otherwise
+ */
+ public @Nullable IValue getParameter(String label);
- /**
- * Unset the value of an parameter
- *
- * @param label identifies the parameter
- * @return a new node where the value of the parameter is not present anymore
- */
- public T unsetParameter(String label);
+ /**
+ * Set the value of an parameter
+ *
+ * @param label identifies the parameter
+ * @param newValue the new value for the parameter
+ * @return a new node where the value of the parameter is replaced (if previously present) or newly added
+ * @throws FactTypeUseException when the type of the new value is not comparable to the old parameter value
+ */
+ public T setParameter(String label, IValue newValue);
- /**
- * Unset the values of all parameters
- *
- * @param label identifies the parameter
- * @return a new node where the value of all keyword parameters are unset
- */
- public T unsetAll();
-
- /**
- * Check whether a certain parameter is set.
- *
- * @param label identifies the parameter
- * @return true iff the parameter has a value on this node
- * @throws FactTypeUseException when no parameter with this label is defined for this type of node.
- */
- public boolean hasParameter(String label);
+ /**
+ * Unset the value of an parameter
+ *
+ * @param label identifies the parameter
+ * @return a new node where the value of the parameter is not present anymore
+ */
+ public T unsetParameter(String label);
- /**
- * Check whether any parameters are present.
- */
- public boolean hasParameters();
-
- /**
- * @return a set of parameter names
- */
- public Set getParameterNames();
+ /**
+ * Unset the values of all parameters
+ *
+ * @param label identifies the parameter
+ * @return a new node where the value of all keyword parameters are unset
+ */
+ public T unsetAll();
- /**
- * @return an unmodifiable map for the keyword parameters
- */
- Map getParameters();
+ /**
+ * Check whether a certain parameter is set.
+ *
+ * @param label identifies the parameter
+ * @return true iff the parameter has a value on this node
+ * @throws FactTypeUseException when no parameter with this label is defined for this type of node.
+ */
+ public boolean hasParameter(String label);
- /**
- *
- * @param params
- * @return
- */
- T setParameters(Map params);
+ /**
+ * Check whether any parameters are present.
+ */
+ public boolean hasParameters();
- /**
- * Given an arbitrary other IWithKeywordParameters, compare the values of the
- * parameters.
- * @param other
- * @return true iff the parameters are the same (same labels, same values)
- */
- > boolean equalParameters(U other);
+ /**
+ * @return a set of parameter names
+ */
+ public Set getParameterNames();
+
+ /**
+ * @return an unmodifiable map for the keyword parameters
+ */
+ Map getParameters();
+
+ /**
+ *
+ * @param params
+ * @return
+ */
+ T setParameters(Map params);
+
+ /**
+ * Given an arbitrary other IWithKeywordParameters, compare the values of the
+ * parameters.
+ * @param other
+ * @return true iff the parameters are the same (same labels, same values)
+ */
+ > boolean equalParameters(U other);
}
diff --git a/src/main/java/io/usethesource/vallang/IWriter.java b/src/main/java/io/usethesource/vallang/IWriter.java
index 40bfd7f06..f23cbe024 100644
--- a/src/main/java/io/usethesource/vallang/IWriter.java
+++ b/src/main/java/io/usethesource/vallang/IWriter.java
@@ -15,7 +15,7 @@ public interface IWriter> extends Iterable, Col
* Modify this writer to insert only unique instances into the collection
* @return
*/
- public default IWriter unique() {
+ public default IWriter unique() {
return this;
}
@@ -35,7 +35,7 @@ public default void append(IValue... value) {
/**
* Append elements at the end.
- *
+ *
* @param value array of elements to append
* @throws FactTypeUseException when done() was called before
*/
diff --git a/src/main/java/io/usethesource/vallang/exceptions/EmptyIdentifierException.java b/src/main/java/io/usethesource/vallang/exceptions/EmptyIdentifierException.java
index 30caac4be..8db3ee61e 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/EmptyIdentifierException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/EmptyIdentifierException.java
@@ -1,9 +1,9 @@
package io.usethesource.vallang.exceptions;
public class EmptyIdentifierException extends FactTypeDeclarationException {
- private static final long serialVersionUID = -7032740671919237233L;
+ private static final long serialVersionUID = -7032740671919237233L;
- public EmptyIdentifierException() {
- super("An identifier can not be empty or null");
- }
+ public EmptyIdentifierException() {
+ super("An identifier can not be empty or null");
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/FactParseError.java b/src/main/java/io/usethesource/vallang/exceptions/FactParseError.java
index a7954cd1f..8de5817fd 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/FactParseError.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/FactParseError.java
@@ -1,32 +1,32 @@
package io.usethesource.vallang.exceptions;
public class FactParseError extends RuntimeException {
- private static final long serialVersionUID = 8208492896666238438L;
- private int offset = -1;
+ private static final long serialVersionUID = 8208492896666238438L;
+ private int offset = -1;
- public FactParseError(String message, Throwable cause) {
- super(message, cause);
- }
-
- public FactParseError(String message, int offset) {
- super(message);
- this.offset = offset;
- }
-
- public FactParseError(String message, int offset, Throwable cause) {
- super(message + " at offset " + offset, cause);
- this.offset = offset;
- }
+ public FactParseError(String message, Throwable cause) {
+ super(message, cause);
+ }
- public boolean hasCause() {
- return getCause() != null;
- }
-
-
- public boolean hasOffset() {
- return offset != -1;
- }
- public int getOffset() {
- return offset;
- }
+ public FactParseError(String message, int offset) {
+ super(message);
+ this.offset = offset;
+ }
+
+ public FactParseError(String message, int offset, Throwable cause) {
+ super(message + " at offset " + offset, cause);
+ this.offset = offset;
+ }
+
+ public boolean hasCause() {
+ return getCause() != null;
+ }
+
+
+ public boolean hasOffset() {
+ return offset != -1;
+ }
+ public int getOffset() {
+ return offset;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/FactTypeDeclarationException.java b/src/main/java/io/usethesource/vallang/exceptions/FactTypeDeclarationException.java
index 168be8e59..b52dc6b35 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/FactTypeDeclarationException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/FactTypeDeclarationException.java
@@ -13,13 +13,13 @@
package io.usethesource.vallang.exceptions;
public abstract class FactTypeDeclarationException extends RuntimeException {
- private static final long serialVersionUID = -2991169068626385361L;
+ private static final long serialVersionUID = -2991169068626385361L;
- public FactTypeDeclarationException(String message) {
- super(message);
- }
-
- public FactTypeDeclarationException(String message, Throwable cause) {
- super(message, cause);
- }
+ public FactTypeDeclarationException(String message) {
+ super(message);
+ }
+
+ public FactTypeDeclarationException(String message, Throwable cause) {
+ super(message, cause);
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/FactTypeRedeclaredException.java b/src/main/java/io/usethesource/vallang/exceptions/FactTypeRedeclaredException.java
index a9dc9bb18..31ca212cf 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/FactTypeRedeclaredException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/FactTypeRedeclaredException.java
@@ -3,23 +3,23 @@
import io.usethesource.vallang.type.Type;
public class FactTypeRedeclaredException extends FactTypeDeclarationException {
- private static final long serialVersionUID = 9191150588452685289L;
- private String name;
- private Type earlier;
-
- public FactTypeRedeclaredException(String name, Type earlier) {
- super(name + " was declared earlier as " + earlier);
- this.name = name;
- this.earlier = earlier;
- }
+ private static final long serialVersionUID = 9191150588452685289L;
+ private String name;
+ private Type earlier;
+
+ public FactTypeRedeclaredException(String name, Type earlier) {
+ super(name + " was declared earlier as " + earlier);
+ this.name = name;
+ this.earlier = earlier;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Type declaredEarlier() {
+ return earlier;
+ }
+
- public String getName() {
- return name;
- }
-
- public Type declaredEarlier() {
- return earlier;
- }
-
-
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/FactTypeUseException.java b/src/main/java/io/usethesource/vallang/exceptions/FactTypeUseException.java
index f49ef8342..3e13e732f 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/FactTypeUseException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/FactTypeUseException.java
@@ -16,10 +16,10 @@ public abstract class FactTypeUseException extends RuntimeException {
private static final long serialVersionUID= 2135696551442574010L;
public FactTypeUseException(String message) {
- super(message);
+ super(message);
}
-
+
public FactTypeUseException(String reason, Throwable cause) {
- super(reason, cause);
+ super(reason, cause);
}
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/FieldLabelMismatchException.java b/src/main/java/io/usethesource/vallang/exceptions/FieldLabelMismatchException.java
index 448f6d7bc..e42559780 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/FieldLabelMismatchException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/FieldLabelMismatchException.java
@@ -1,22 +1,22 @@
package io.usethesource.vallang.exceptions;
public class FieldLabelMismatchException extends FactTypeDeclarationException {
- private static final long serialVersionUID = 3510697170437859049L;
- private int fields;
- private int labels;
+ private static final long serialVersionUID = 3510697170437859049L;
+ private int fields;
+ private int labels;
- public FieldLabelMismatchException(int fields, int labels) {
- super("Expected " + fields + " field labels, but got " + labels);
- this.fields = fields;
- this.labels = labels;
- }
-
- public int getFields() {
- return fields;
- }
-
- public int getLabels() {
- return labels;
- }
+ public FieldLabelMismatchException(int fields, int labels) {
+ super("Expected " + fields + " field labels, but got " + labels);
+ this.fields = fields;
+ this.labels = labels;
+ }
+
+ public int getFields() {
+ return fields;
+ }
+
+ public int getLabels() {
+ return labels;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/IllegalConstructorApplicationException.java b/src/main/java/io/usethesource/vallang/exceptions/IllegalConstructorApplicationException.java
index 2375b3745..865ab5522 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/IllegalConstructorApplicationException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/IllegalConstructorApplicationException.java
@@ -3,11 +3,11 @@
import io.usethesource.vallang.type.Type;
public class IllegalConstructorApplicationException extends FactTypeUseException {
- private static final long serialVersionUID = -1412303012184333060L;
+ private static final long serialVersionUID = -1412303012184333060L;
+
+ public IllegalConstructorApplicationException(Type constructorType, Type arguments) {
+ super("Constructor " + constructorType + " is not applicable to " + arguments);
+ }
- public IllegalConstructorApplicationException(Type constructorType, Type arguments) {
- super("Constructor " + constructorType + " is not applicable to " + arguments);
- }
-
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/IllegalFieldNameException.java b/src/main/java/io/usethesource/vallang/exceptions/IllegalFieldNameException.java
index 0d41996cd..26b0572e9 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/IllegalFieldNameException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/IllegalFieldNameException.java
@@ -3,25 +3,25 @@
import org.checkerframework.checker.nullness.qual.Nullable;
public class IllegalFieldNameException extends FactTypeDeclarationException {
- private static final long serialVersionUID = -2480224409679761754L;
- private int pos;
- private Object elem;
+ private static final long serialVersionUID = -2480224409679761754L;
+ private int pos;
+ private Object elem;
- public IllegalFieldNameException(int pos, Object elem, ClassCastException cause) {
- super("Expected a field name at position " + pos + ", but got something different", cause);
- this.pos = pos;
- this.elem = elem;
- }
-
- public Object getElement() {
- return elem;
- }
-
- public int getPos() {
- return pos;
- }
-
- public synchronized @Nullable ClassCastException getCause() {
- return (ClassCastException) super.getCause();
- }
+ public IllegalFieldNameException(int pos, Object elem, ClassCastException cause) {
+ super("Expected a field name at position " + pos + ", but got something different", cause);
+ this.pos = pos;
+ this.elem = elem;
+ }
+
+ public Object getElement() {
+ return elem;
+ }
+
+ public int getPos() {
+ return pos;
+ }
+
+ public synchronized @Nullable ClassCastException getCause() {
+ return (ClassCastException) super.getCause();
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/IllegalFieldTypeException.java b/src/main/java/io/usethesource/vallang/exceptions/IllegalFieldTypeException.java
index 4f4e3f68e..b3e9ff6bb 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/IllegalFieldTypeException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/IllegalFieldTypeException.java
@@ -1,26 +1,26 @@
package io.usethesource.vallang.exceptions;
public class IllegalFieldTypeException extends FactTypeDeclarationException {
- private static final long serialVersionUID = -8845629423612702596L;
- private int pos;
- private Object elem;
+ private static final long serialVersionUID = -8845629423612702596L;
+ private int pos;
+ private Object elem;
- public IllegalFieldTypeException(int pos, Object elem, ClassCastException cause) {
- super("Expected a field type at position " + pos + ", but got something different", cause);
- this.pos = pos;
- this.elem = elem;
- }
+ public IllegalFieldTypeException(int pos, Object elem, ClassCastException cause) {
+ super("Expected a field type at position " + pos + ", but got something different", cause);
+ this.pos = pos;
+ this.elem = elem;
+ }
- public Object getElement() {
- return elem;
- }
-
- public int getPos() {
- return pos;
- }
-
- public synchronized Throwable getCause() {
- Throwable cause = super.getCause();
- return cause == null ? this : cause;
- }
+ public Object getElement() {
+ return elem;
+ }
+
+ public int getPos() {
+ return pos;
+ }
+
+ public synchronized Throwable getCause() {
+ Throwable cause = super.getCause();
+ return cause == null ? this : cause;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/IllegalIdentifierException.java b/src/main/java/io/usethesource/vallang/exceptions/IllegalIdentifierException.java
index a11569832..7759b9d3f 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/IllegalIdentifierException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/IllegalIdentifierException.java
@@ -1,15 +1,15 @@
package io.usethesource.vallang.exceptions;
public class IllegalIdentifierException extends FactTypeDeclarationException {
- private static final long serialVersionUID = 7380196205269771711L;
- private String id;
+ private static final long serialVersionUID = 7380196205269771711L;
+ private String id;
- public IllegalIdentifierException(String id) {
- super(id + " is not a valid identifier");
- this.id = id;
- }
-
- public String getIdentifier() {
- return id;
- }
+ public IllegalIdentifierException(String id) {
+ super(id + " is not a valid identifier");
+ this.id = id;
+ }
+
+ public String getIdentifier() {
+ return id;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/IllegalInstantiatedAbstractDataTypeException.java b/src/main/java/io/usethesource/vallang/exceptions/IllegalInstantiatedAbstractDataTypeException.java
index ae4a46623..752eb601a 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/IllegalInstantiatedAbstractDataTypeException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/IllegalInstantiatedAbstractDataTypeException.java
@@ -3,10 +3,10 @@
import io.usethesource.vallang.type.Type;
public class IllegalInstantiatedAbstractDataTypeException extends
- FactTypeDeclarationException {
- private static final long serialVersionUID = -7171289358305194254L;
+ FactTypeDeclarationException {
+ private static final long serialVersionUID = -7171289358305194254L;
- public IllegalInstantiatedAbstractDataTypeException(Type adt) {
- super("should not declare instances of type-parametrized abstract data-types (" + adt + ")");
- }
+ public IllegalInstantiatedAbstractDataTypeException(Type adt) {
+ super("should not declare instances of type-parametrized abstract data-types (" + adt + ")");
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/IllegalKeywordParameterDeclarationException.java b/src/main/java/io/usethesource/vallang/exceptions/IllegalKeywordParameterDeclarationException.java
index cbcae7239..cfc25c49b 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/IllegalKeywordParameterDeclarationException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/IllegalKeywordParameterDeclarationException.java
@@ -3,9 +3,9 @@
import io.usethesource.vallang.type.Type;
public class IllegalKeywordParameterDeclarationException extends FactTypeUseException {
- private static final long serialVersionUID = -1073149631907760703L;
-
- public IllegalKeywordParameterDeclarationException(Type type) {
- super("Keyword parameters can not be declared on " + type);
- }
+ private static final long serialVersionUID = -1073149631907760703L;
+
+ public IllegalKeywordParameterDeclarationException(Type type) {
+ super("Keyword parameters can not be declared on " + type);
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/IllegalOperationException.java b/src/main/java/io/usethesource/vallang/exceptions/IllegalOperationException.java
index d9336067f..dd55f50cd 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/IllegalOperationException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/IllegalOperationException.java
@@ -3,13 +3,13 @@
import io.usethesource.vallang.type.Type;
public class IllegalOperationException extends FactTypeUseException {
- private static final long serialVersionUID = 546504861606007094L;
-
- public IllegalOperationException(String op, Type lhs) {
- super("Operation " + op + " not allowed on " + lhs);
- }
-
- public IllegalOperationException(String op, Type lhs, Type rhs) {
- super("Operation " +op + " not allowed on " + lhs + " and " + rhs);
- }
+ private static final long serialVersionUID = 546504861606007094L;
+
+ public IllegalOperationException(String op, Type lhs) {
+ super("Operation " + op + " not allowed on " + lhs);
+ }
+
+ public IllegalOperationException(String op, Type lhs, Type rhs) {
+ super("Operation " +op + " not allowed on " + lhs + " and " + rhs);
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/InvalidDateTimeException.java b/src/main/java/io/usethesource/vallang/exceptions/InvalidDateTimeException.java
index 629948535..cd0bf57e0 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/InvalidDateTimeException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/InvalidDateTimeException.java
@@ -1,15 +1,15 @@
-package io.usethesource.vallang.exceptions;
-
-public class InvalidDateTimeException extends FactTypeUseException {
-
- private static final long serialVersionUID = 5634976179346912971L;
-
- public InvalidDateTimeException(String message) {
- super(message);
- }
-
- public InvalidDateTimeException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
+package io.usethesource.vallang.exceptions;
+
+public class InvalidDateTimeException extends FactTypeUseException {
+
+ private static final long serialVersionUID = 5634976179346912971L;
+
+ public InvalidDateTimeException(String message) {
+ super(message);
+ }
+
+ public InvalidDateTimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/NullTypeException.java b/src/main/java/io/usethesource/vallang/exceptions/NullTypeException.java
index 11195884b..bf8962d04 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/NullTypeException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/NullTypeException.java
@@ -1,10 +1,10 @@
package io.usethesource.vallang.exceptions;
public class NullTypeException extends FactTypeUseException {
- private static final long serialVersionUID = -4201840676263159311L;
+ private static final long serialVersionUID = -4201840676263159311L;
- public NullTypeException() {
- super("A null reference as a type");
- }
+ public NullTypeException() {
+ super("A null reference as a type");
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/OverloadingNotSupportedException.java b/src/main/java/io/usethesource/vallang/exceptions/OverloadingNotSupportedException.java
index ecd4f4a5c..0b08e5d10 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/OverloadingNotSupportedException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/OverloadingNotSupportedException.java
@@ -3,14 +3,14 @@
import io.usethesource.vallang.type.Type;
public class OverloadingNotSupportedException extends FactTypeUseException {
- private static final long serialVersionUID = 5645367130014687132L;
+ private static final long serialVersionUID = 5645367130014687132L;
- public OverloadingNotSupportedException(String constructorId) {
- super("Overloading is not supported (" + constructorId + ")");
- }
-
- public OverloadingNotSupportedException(Type adt, String constructorId) {
- super("Overloading is not supported (" + adt + "." + constructorId + ")");
- }
+ public OverloadingNotSupportedException(String constructorId) {
+ super("Overloading is not supported (" + constructorId + ")");
+ }
+
+ public OverloadingNotSupportedException(Type adt, String constructorId) {
+ super("Overloading is not supported (" + adt + "." + constructorId + ")");
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/RedeclaredConstructorException.java b/src/main/java/io/usethesource/vallang/exceptions/RedeclaredConstructorException.java
index 3e2c2eef6..fb48e4db7 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/RedeclaredConstructorException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/RedeclaredConstructorException.java
@@ -3,28 +3,28 @@
import io.usethesource.vallang.type.Type;
public class RedeclaredConstructorException extends
- FactTypeDeclarationException {
- private static final long serialVersionUID = 8330548728032865311L;
- private String name;
- private Type firstArgs;
- private Type secondArgs;
+ FactTypeDeclarationException {
+ private static final long serialVersionUID = 8330548728032865311L;
+ private String name;
+ private Type firstArgs;
+ private Type secondArgs;
- public RedeclaredConstructorException(String name, Type firstArgs, Type secondArgs) {
- super("Constructor " + name + " overloaded with comparable argument types: " + firstArgs + " and " + secondArgs);
- this.name = name;
- this.firstArgs = firstArgs;
- this.secondArgs = secondArgs;
- }
+ public RedeclaredConstructorException(String name, Type firstArgs, Type secondArgs) {
+ super("Constructor " + name + " overloaded with comparable argument types: " + firstArgs + " and " + secondArgs);
+ this.name = name;
+ this.firstArgs = firstArgs;
+ this.secondArgs = secondArgs;
+ }
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- public Type getFirstArgs() {
- return firstArgs;
- }
+ public Type getFirstArgs() {
+ return firstArgs;
+ }
- public Type getSecondArgs() {
- return secondArgs;
- }
+ public Type getSecondArgs() {
+ return secondArgs;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/RedeclaredFieldNameException.java b/src/main/java/io/usethesource/vallang/exceptions/RedeclaredFieldNameException.java
index d15984557..2016e231c 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/RedeclaredFieldNameException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/RedeclaredFieldNameException.java
@@ -3,35 +3,35 @@
import io.usethesource.vallang.type.Type;
public class RedeclaredFieldNameException extends
- FactTypeDeclarationException {
- private static final long serialVersionUID = -4401062690006714904L;
- private String label;
- private Type one;
- private Type two;
- private Type tupleType;
-
- public RedeclaredFieldNameException(String label, Type one, Type two, Type tupleType) {
- super("The field name " + label + " is illegally used for both " + one + " and " + two + " in type " + tupleType);
- this.label = label;
- this.one = one;
- this.two = two;
- this.tupleType = tupleType;
- }
-
- public String getFieldName() {
- return label;
- }
-
- public Type getFirstType() {
- return one;
- }
-
- public Type getSecondType() {
- return two;
- }
-
- public Type getTupleType() {
- return tupleType;
- }
+ FactTypeDeclarationException {
+ private static final long serialVersionUID = -4401062690006714904L;
+ private String label;
+ private Type one;
+ private Type two;
+ private Type tupleType;
+
+ public RedeclaredFieldNameException(String label, Type one, Type two, Type tupleType) {
+ super("The field name " + label + " is illegally used for both " + one + " and " + two + " in type " + tupleType);
+ this.label = label;
+ this.one = one;
+ this.two = two;
+ this.tupleType = tupleType;
+ }
+
+ public String getFieldName() {
+ return label;
+ }
+
+ public Type getFirstType() {
+ return one;
+ }
+
+ public Type getSecondType() {
+ return two;
+ }
+
+ public Type getTupleType() {
+ return tupleType;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/RedeclaredKeywordParameterException.java b/src/main/java/io/usethesource/vallang/exceptions/RedeclaredKeywordParameterException.java
index 594a22c9c..08221c984 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/RedeclaredKeywordParameterException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/RedeclaredKeywordParameterException.java
@@ -3,21 +3,21 @@
import io.usethesource.vallang.type.Type;
public class RedeclaredKeywordParameterException extends FactTypeDeclarationException {
- private static final long serialVersionUID = -2118606173620347920L;
- private String label;
- private Type earlier;
+ private static final long serialVersionUID = -2118606173620347920L;
+ private String label;
+ private Type earlier;
- public RedeclaredKeywordParameterException(String label, Type earlier) {
- super("Keyword parameter " + label + " was declared earlier as " + earlier);
- this.label = label;
- this.earlier = earlier;
- }
-
- public String getLabel() {
- return label;
- }
-
- public Type getEarlierType() {
- return earlier;
- }
+ public RedeclaredKeywordParameterException(String label, Type earlier) {
+ super("Keyword parameter " + label + " was declared earlier as " + earlier);
+ this.label = label;
+ this.earlier = earlier;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public Type getEarlierType() {
+ return earlier;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/TypeParseError.java b/src/main/java/io/usethesource/vallang/exceptions/TypeParseError.java
index 1e2443198..672f978ee 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/TypeParseError.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/TypeParseError.java
@@ -4,29 +4,29 @@ public class TypeParseError extends RuntimeException {
private static final long serialVersionUID = 7054359699049181437L;
private int offset = -1;
- public TypeParseError(String message, Throwable cause) {
- super(message, cause);
- }
-
- public TypeParseError(String message, int offset) {
- super(message);
- this.offset = offset;
- }
-
- public TypeParseError(String message, int offset, Throwable cause) {
- super(message + " at offset " + offset, cause);
- this.offset = offset;
- }
+ public TypeParseError(String message, Throwable cause) {
+ super(message, cause);
+ }
- public boolean hasCause() {
- return getCause() != null;
- }
-
-
- public boolean hasOffset() {
- return offset != -1;
- }
- public int getOffset() {
- return offset;
- }
+ public TypeParseError(String message, int offset) {
+ super(message);
+ this.offset = offset;
+ }
+
+ public TypeParseError(String message, int offset, Throwable cause) {
+ super(message + " at offset " + offset, cause);
+ this.offset = offset;
+ }
+
+ public boolean hasCause() {
+ return getCause() != null;
+ }
+
+
+ public boolean hasOffset() {
+ return offset != -1;
+ }
+ public int getOffset() {
+ return offset;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/TypeReificationException.java b/src/main/java/io/usethesource/vallang/exceptions/TypeReificationException.java
index 6980efe1a..621201f12 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/TypeReificationException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/TypeReificationException.java
@@ -1,9 +1,9 @@
package io.usethesource.vallang.exceptions;
public class TypeReificationException extends FactTypeUseException {
- private static final long serialVersionUID = -1606508959996710935L;
+ private static final long serialVersionUID = -1606508959996710935L;
- public TypeReificationException(String reason, Throwable cause) {
- super(reason, cause);
- }
+ public TypeReificationException(String reason, Throwable cause) {
+ super(reason, cause);
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/UndeclaredAbstractDataTypeException.java b/src/main/java/io/usethesource/vallang/exceptions/UndeclaredAbstractDataTypeException.java
index 97a61489e..66e66ef5f 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/UndeclaredAbstractDataTypeException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/UndeclaredAbstractDataTypeException.java
@@ -3,10 +3,10 @@
import io.usethesource.vallang.type.Type;
public class UndeclaredAbstractDataTypeException extends
- FactTypeDeclarationException {
- private static final long serialVersionUID = 2192451595458909479L;
+ FactTypeDeclarationException {
+ private static final long serialVersionUID = 2192451595458909479L;
- public UndeclaredAbstractDataTypeException(Type adt) {
- super(adt + " is not registered");
- }
+ public UndeclaredAbstractDataTypeException(Type adt) {
+ super(adt + " is not registered");
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/UndeclaredFieldException.java b/src/main/java/io/usethesource/vallang/exceptions/UndeclaredFieldException.java
index 845faaa58..5e9f1daf5 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/UndeclaredFieldException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/UndeclaredFieldException.java
@@ -3,21 +3,21 @@
import io.usethesource.vallang.type.Type;
public class UndeclaredFieldException extends FactTypeUseException {
- private static final long serialVersionUID = 8997399464492627705L;
- private Type type;
- private String label;
-
- public UndeclaredFieldException(Type type, String label) {
- super(type + " does not have a field with label " + label + " declared for it");
- this.type = type;
- this.label = label;
- }
-
- public Type getType() {
- return type;
- }
-
- public String getLabel() {
- return label;
- }
+ private static final long serialVersionUID = 8997399464492627705L;
+ private Type type;
+ private String label;
+
+ public UndeclaredFieldException(Type type, String label) {
+ super(type + " does not have a field with label " + label + " declared for it");
+ this.type = type;
+ this.label = label;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public String getLabel() {
+ return label;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/UnexpectedAnnotationTypeException.java b/src/main/java/io/usethesource/vallang/exceptions/UnexpectedAnnotationTypeException.java
index 1f46856ed..b014cf585 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/UnexpectedAnnotationTypeException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/UnexpectedAnnotationTypeException.java
@@ -3,10 +3,10 @@
import io.usethesource.vallang.type.Type;
public class UnexpectedAnnotationTypeException extends UnexpectedTypeException {
- private static final long serialVersionUID = -4865168232421987847L;
+ private static final long serialVersionUID = -4865168232421987847L;
- public UnexpectedAnnotationTypeException(Type expected, Type got) {
- super(expected, got);
- }
+ public UnexpectedAnnotationTypeException(Type expected, Type got) {
+ super(expected, got);
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/UnexpectedChildTypeException.java b/src/main/java/io/usethesource/vallang/exceptions/UnexpectedChildTypeException.java
index c6dc11793..0739fce13 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/UnexpectedChildTypeException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/UnexpectedChildTypeException.java
@@ -3,9 +3,9 @@
import io.usethesource.vallang.type.Type;
public class UnexpectedChildTypeException extends UnexpectedTypeException {
- private static final long serialVersionUID = -1848764011952028440L;
+ private static final long serialVersionUID = -1848764011952028440L;
- public UnexpectedChildTypeException(Type expected, Type got) {
- super(expected, got);
- }
+ public UnexpectedChildTypeException(Type expected, Type got) {
+ super(expected, got);
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/UnexpectedConstructorTypeException.java b/src/main/java/io/usethesource/vallang/exceptions/UnexpectedConstructorTypeException.java
index 6ec4c9e79..e2d592dd4 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/UnexpectedConstructorTypeException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/UnexpectedConstructorTypeException.java
@@ -3,10 +3,10 @@
import io.usethesource.vallang.type.Type;
public class UnexpectedConstructorTypeException extends UnexpectedTypeException {
- private static final long serialVersionUID = -6198133177142765746L;
+ private static final long serialVersionUID = -6198133177142765746L;
- public UnexpectedConstructorTypeException(Type expected, Type got) {
- super(expected, got);
- }
+ public UnexpectedConstructorTypeException(Type expected, Type got) {
+ super(expected, got);
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/UnexpectedTypeException.java b/src/main/java/io/usethesource/vallang/exceptions/UnexpectedTypeException.java
index d4c2405b1..54f2f820f 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/UnexpectedTypeException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/UnexpectedTypeException.java
@@ -3,27 +3,27 @@
import io.usethesource.vallang.type.Type;
public class UnexpectedTypeException extends FactTypeUseException {
- private static final long serialVersionUID = -5107803679675463540L;
- private Type expected;
- private Type got;
-
- public UnexpectedTypeException(Type expected, Type got) {
- super("Expected " + expected + ", but got " + got);
- this.expected = expected;
- this.got = got;
- }
-
- public boolean hasExpected() {
- return expected != null;
- }
-
- public Type getExpected() {
- return expected;
- }
-
- public Type getGiven() {
- return got;
- }
+ private static final long serialVersionUID = -5107803679675463540L;
+ private Type expected;
+ private Type got;
+
+ public UnexpectedTypeException(Type expected, Type got) {
+ super("Expected " + expected + ", but got " + got);
+ this.expected = expected;
+ this.got = got;
+ }
+
+ public boolean hasExpected() {
+ return expected != null;
+ }
+
+ public Type getExpected() {
+ return expected;
+ }
+
+ public Type getGiven() {
+ return got;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/exceptions/UnsupportedTypeException.java b/src/main/java/io/usethesource/vallang/exceptions/UnsupportedTypeException.java
index 90b88cb9a..fc833493d 100644
--- a/src/main/java/io/usethesource/vallang/exceptions/UnsupportedTypeException.java
+++ b/src/main/java/io/usethesource/vallang/exceptions/UnsupportedTypeException.java
@@ -3,14 +3,14 @@
import io.usethesource.vallang.type.Type;
public class UnsupportedTypeException extends FactTypeUseException {
- private static final long serialVersionUID = -8995093767494157052L;
- private Type type;
- public UnsupportedTypeException(String explanation, Type type) {
- super(explanation);
- this.type = type;
- }
-
- public Type getType() {
- return type;
- }
+ private static final long serialVersionUID = -8995093767494157052L;
+ private Type type;
+ public UnsupportedTypeException(String explanation, Type type) {
+ super(explanation);
+ this.type = type;
+ }
+
+ public Type getType() {
+ return type;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/impl/fields/AbstractDefaultWithKeywordParameters.java b/src/main/java/io/usethesource/vallang/impl/fields/AbstractDefaultWithKeywordParameters.java
index 210f0c308..2a4fff2c4 100644
--- a/src/main/java/io/usethesource/vallang/impl/fields/AbstractDefaultWithKeywordParameters.java
+++ b/src/main/java/io/usethesource/vallang/impl/fields/AbstractDefaultWithKeywordParameters.java
@@ -7,7 +7,7 @@
*
* Contributors:
*
- * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
+ * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
*******************************************************************************/
package io.usethesource.vallang.impl.fields;
@@ -24,166 +24,166 @@
/**
- * A generic wrapper for an {@link IValue} that associates keyword parameters to it.
+ * A generic wrapper for an {@link IValue} that associates keyword parameters to it.
*
* @param the interface over which this parameter wrapper closes
*/
public abstract class AbstractDefaultWithKeywordParameters implements IWithKeywordParameters {
- protected final T content;
- protected final io.usethesource.capsule.Map.Immutable parameters;
-
- /**
- * Creates an {@link IWithKeywordParameters} view on {@link #content} with already
- * provided {@link #parameters}.
- *
- * @param content
- * is the wrapped object that supports keywod fields
- * @param parameters
- * is the map of fields associated to {@link #content}
- */
- public AbstractDefaultWithKeywordParameters(T content, io.usethesource.capsule.Map.Immutable parameters) {
- this.content = content;
- this.parameters = parameters;
- }
-
- /**
- * Wraps {@link #content} with other parameters. This methods is mandatory
- * because of PDB's immutable value nature: Once parameters are modified, a
- * new immutable view is returned.
- *
- * @param content
- * is the wrapped object that supports keyword fields
- * @param annotations
- * is the map of fields associated to {@link #content}
- * @return a new representations of {@link #content} with associated
- * {@link #parameters}
- */
- protected abstract T wrap(final T content, final io.usethesource.capsule.Map.Immutable parameters);
-
- @Override
- public String toString() {
- return content.toString();
- }
-
- @Override
- public @Nullable IValue getParameter(String label) {
- return parameters.get(label);
- }
-
- @Override
- public T setParameter(String label, IValue newValue) {
- return wrap(content, parameters.__put(label, newValue));
- }
-
- @Override
- public T unsetParameter(String label) {
- io.usethesource.capsule.Map.Immutable removed = parameters.__remove(label);
-
- if (removed.isEmpty()) {
- return content;
- }
- return wrap(content, removed);
- }
-
- @Override
- public T unsetAll() {
- return content;
- }
-
- @Override
- @Pure
- public boolean hasParameter(String label) {
- return parameters.containsKey(label);
- }
-
- @Override
- public boolean hasParameters() {
- return !parameters.isEmpty();
- }
-
- @Override
- @Pure
- public Set getParameterNames() {
- return Collections.unmodifiableSet(parameters.keySet());
- }
-
- @Override
- public Map getParameters() {
- return Collections.unmodifiableMap(parameters);
- }
-
- @Override
- public int hashCode() {
- return 91 + content.hashCode() * 13 + 101 * parameters.hashCode();
- }
-
- @Override
- public boolean equals(@Nullable Object other) {
- if (other == null) {
- return false;
- }
-
- if (!getClass().equals(other.getClass())) {
- return false;
- }
-
- AbstractDefaultWithKeywordParameters extends IValue> o = (AbstractDefaultWithKeywordParameters>) other;
-
- if (!content.equals(o.content)) {
- return false;
- }
-
- if (parameters.size() != o.parameters.size()) {
- return false;
- }
-
- // TODO: there should be a faster way for this
- for (String key : parameters.keySet()) {
- if (!parameters.get(key).equals(o.getParameter(key))) {
- return false;
- }
- }
-
- return true;
- }
-
- @Override
- public > boolean equalParameters(U other) {
- if (!(other instanceof AbstractDefaultWithKeywordParameters>)) {
- return false;
- }
-
- AbstractDefaultWithKeywordParameters extends IValue> o = (AbstractDefaultWithKeywordParameters>) other;
-
- if (parameters.size() != o.parameters.size()) {
- return false;
- }
-
- for (String key : parameters.keySet()) {
- IValue parameter = getParameter(key);
- if (parameter == null && o.getParameter(key) != null) {
- return false;
- }
- else if (parameter != null && !parameter.equals(o.getParameter(key))) {
- return false;
- }
- }
-
- return true;
- }
-
- @Override
- public T setParameters(Map params) {
- if (params.isEmpty()) {
- return content;
- }
- return wrap(content, AbstractSpecialisedImmutableMap.mapOf(params));
- }
-
- /**
- * This method is only to be used by internal methods, such as testing and fast iterators
- */
- public io.usethesource.capsule.Map.Immutable internalGetParameters() {
- return parameters;
- }
+ protected final T content;
+ protected final io.usethesource.capsule.Map.Immutable parameters;
+
+ /**
+ * Creates an {@link IWithKeywordParameters} view on {@link #content} with already
+ * provided {@link #parameters}.
+ *
+ * @param content
+ * is the wrapped object that supports keywod fields
+ * @param parameters
+ * is the map of fields associated to {@link #content}
+ */
+ public AbstractDefaultWithKeywordParameters(T content, io.usethesource.capsule.Map.Immutable parameters) {
+ this.content = content;
+ this.parameters = parameters;
+ }
+
+ /**
+ * Wraps {@link #content} with other parameters. This methods is mandatory
+ * because of PDB's immutable value nature: Once parameters are modified, a
+ * new immutable view is returned.
+ *
+ * @param content
+ * is the wrapped object that supports keyword fields
+ * @param annotations
+ * is the map of fields associated to {@link #content}
+ * @return a new representations of {@link #content} with associated
+ * {@link #parameters}
+ */
+ protected abstract T wrap(final T content, final io.usethesource.capsule.Map.Immutable parameters);
+
+ @Override
+ public String toString() {
+ return content.toString();
+ }
+
+ @Override
+ public @Nullable IValue getParameter(String label) {
+ return parameters.get(label);
+ }
+
+ @Override
+ public T setParameter(String label, IValue newValue) {
+ return wrap(content, parameters.__put(label, newValue));
+ }
+
+ @Override
+ public T unsetParameter(String label) {
+ io.usethesource.capsule.Map.Immutable removed = parameters.__remove(label);
+
+ if (removed.isEmpty()) {
+ return content;
+ }
+ return wrap(content, removed);
+ }
+
+ @Override
+ public T unsetAll() {
+ return content;
+ }
+
+ @Override
+ @Pure
+ public boolean hasParameter(String label) {
+ return parameters.containsKey(label);
+ }
+
+ @Override
+ public boolean hasParameters() {
+ return !parameters.isEmpty();
+ }
+
+ @Override
+ @Pure
+ public Set getParameterNames() {
+ return Collections.unmodifiableSet(parameters.keySet());
+ }
+
+ @Override
+ public Map getParameters() {
+ return Collections.unmodifiableMap(parameters);
+ }
+
+ @Override
+ public int hashCode() {
+ return 91 + content.hashCode() * 13 + 101 * parameters.hashCode();
+ }
+
+ @Override
+ public boolean equals(@Nullable Object other) {
+ if (other == null) {
+ return false;
+ }
+
+ if (!getClass().equals(other.getClass())) {
+ return false;
+ }
+
+ AbstractDefaultWithKeywordParameters extends IValue> o = (AbstractDefaultWithKeywordParameters>) other;
+
+ if (!content.equals(o.content)) {
+ return false;
+ }
+
+ if (parameters.size() != o.parameters.size()) {
+ return false;
+ }
+
+ // TODO: there should be a faster way for this
+ for (String key : parameters.keySet()) {
+ if (!parameters.get(key).equals(o.getParameter(key))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public > boolean equalParameters(U other) {
+ if (!(other instanceof AbstractDefaultWithKeywordParameters>)) {
+ return false;
+ }
+
+ AbstractDefaultWithKeywordParameters extends IValue> o = (AbstractDefaultWithKeywordParameters>) other;
+
+ if (parameters.size() != o.parameters.size()) {
+ return false;
+ }
+
+ for (String key : parameters.keySet()) {
+ IValue parameter = getParameter(key);
+ if (parameter == null && o.getParameter(key) != null) {
+ return false;
+ }
+ else if (parameter != null && !parameter.equals(o.getParameter(key))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public T setParameters(Map params) {
+ if (params.isEmpty()) {
+ return content;
+ }
+ return wrap(content, AbstractSpecialisedImmutableMap.mapOf(params));
+ }
+
+ /**
+ * This method is only to be used by internal methods, such as testing and fast iterators
+ */
+ public io.usethesource.capsule.Map.Immutable internalGetParameters() {
+ return parameters;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/impl/fields/AbstractValueFactoryAdapter.java b/src/main/java/io/usethesource/vallang/impl/fields/AbstractValueFactoryAdapter.java
index 63320edee..8076bc10b 100644
--- a/src/main/java/io/usethesource/vallang/impl/fields/AbstractValueFactoryAdapter.java
+++ b/src/main/java/io/usethesource/vallang/impl/fields/AbstractValueFactoryAdapter.java
@@ -30,7 +30,7 @@
* of IValueFactory without having to extend them again and again using
* inheritance. Clients extend this class and override the methods that need
* special handling.
- *
+ *
* Note: this class is intended to be sub-classed. It should not be abstract
* because we want the compiler to check that it provides a facade for the full
* IValueFactory interface.
@@ -88,7 +88,7 @@ public IDateTime datetime(long instant, int timezoneHours, int timezoneMinutes)
public IInteger integer(String i) {
return adapted.integer(i);
}
-
+
@Override
public IInteger integer(int i) {
return adapted.integer(i);
diff --git a/src/main/java/io/usethesource/vallang/impl/fields/ConstructorWithKeywordParametersFacade.java b/src/main/java/io/usethesource/vallang/impl/fields/ConstructorWithKeywordParametersFacade.java
index 7e830919f..42c167f57 100644
--- a/src/main/java/io/usethesource/vallang/impl/fields/ConstructorWithKeywordParametersFacade.java
+++ b/src/main/java/io/usethesource/vallang/impl/fields/ConstructorWithKeywordParametersFacade.java
@@ -7,7 +7,7 @@
*
* Contributors:
*
- * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
+ * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
*******************************************************************************/
package io.usethesource.vallang.impl.fields;
@@ -98,7 +98,7 @@ public boolean equals(@Nullable Object o) {
if (o == this) {
return true;
}
-
+
if (o == null) {
return false;
}
@@ -116,7 +116,7 @@ public boolean equals(@Nullable Object o) {
@Override
public boolean match(IValue other) {
if (other instanceof ConstructorWithKeywordParametersFacade) {
- return content.match(((ConstructorWithKeywordParametersFacade) other).content);
+ return content.match(((ConstructorWithKeywordParametersFacade) other).content);
}
if (other instanceof IConstructor) {
@@ -152,7 +152,7 @@ public boolean hasParameters() {
@Override
@SuppressWarnings("return.type.incompatible")
public Set getParameterNames() {
- return Collections.unmodifiableSet(parameters.keySet());
+ return Collections.unmodifiableSet(parameters.keySet());
}
@Override
diff --git a/src/main/java/io/usethesource/vallang/impl/fields/NodeWithKeywordParametersFacade.java b/src/main/java/io/usethesource/vallang/impl/fields/NodeWithKeywordParametersFacade.java
index 9fdc11d8c..fbd1f5f4a 100644
--- a/src/main/java/io/usethesource/vallang/impl/fields/NodeWithKeywordParametersFacade.java
+++ b/src/main/java/io/usethesource/vallang/impl/fields/NodeWithKeywordParametersFacade.java
@@ -7,7 +7,7 @@
*
* Contributors:
*
- * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
+ * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
*******************************************************************************/
package io.usethesource.vallang.impl.fields;
@@ -24,107 +24,107 @@
import io.usethesource.vallang.visitors.IValueVisitor;
public class NodeWithKeywordParametersFacade implements INode {
- protected final INode content;
- protected final Map.Immutable parameters;
-
- public NodeWithKeywordParametersFacade(final INode content, final Map.Immutable parameters) {
- this.content = content;
- this.parameters = parameters;
- }
-
- @Override
- public Type getType() {
- return content.getType();
- }
-
- @Override
+ protected final INode content;
+ protected final Map.Immutable parameters;
+
+ public NodeWithKeywordParametersFacade(final INode content, final Map.Immutable parameters) {
+ this.content = content;
+ this.parameters = parameters;
+ }
+
+ @Override
+ public Type getType() {
+ return content.getType();
+ }
+
+ @Override
public INode setChildren(IValue[] childArray) {
return content.setChildren(childArray).asWithKeywordParameters().setParameters(parameters);
}
- @Override
- public T accept(IValueVisitor v) throws E {
- return v.visitNode(this);
- }
-
- @Override
- public IValue get(int i) {
- return content.get(i);
- }
-
- @Override
- public INode set(int i, IValue newChild) {
- INode newContent = content.set(i, newChild);
- return new NodeWithKeywordParametersFacade(newContent, parameters); // TODO: introduce wrap() here as well
- }
-
- @Override
- public int arity() {
- return content.arity();
- }
-
- @Override
- public String toString() {
- return defaultToString();
- }
-
- @Override
- public String getName() {
- return content.getName();
- }
-
- @Override
- public Iterable getChildren() {
- return content.getChildren();
- }
-
- @Override
- public Iterator iterator() {
- return content.iterator();
- }
-
- @Override
- public INode replace(int first, int second, int end, IList repl) {
- INode newContent = content.replace(first, second, end, repl);
- return new NodeWithKeywordParametersFacade(newContent, parameters); // TODO: introduce wrap() here as well
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if(o == this) {
- return true;
- }
- if(o == null) {
- return false;
- }
-
- if(o.getClass() == getClass()){
- NodeWithKeywordParametersFacade other = (NodeWithKeywordParametersFacade) o;
-
- return content.equals(other.content) && parameters.equals(other.parameters);
- }
-
- return false;
- }
-
- @Override
- public int hashCode() {
- return 15551 + 7 * content.hashCode() + 11 * parameters.hashCode();
- }
-
- @Override
- public boolean mayHaveKeywordParameters() {
- return true;
- }
-
- @Override
- public IWithKeywordParameters extends INode> asWithKeywordParameters() {
- return new AbstractDefaultWithKeywordParameters(content, parameters) {
- @Override
- protected INode wrap(INode content, Map.Immutable parameters) {
- return new NodeWithKeywordParametersFacade(content, parameters);
- }
- };
- }
-
+ @Override
+ public T accept(IValueVisitor v) throws E {
+ return v.visitNode(this);
+ }
+
+ @Override
+ public IValue get(int i) {
+ return content.get(i);
+ }
+
+ @Override
+ public INode set(int i, IValue newChild) {
+ INode newContent = content.set(i, newChild);
+ return new NodeWithKeywordParametersFacade(newContent, parameters); // TODO: introduce wrap() here as well
+ }
+
+ @Override
+ public int arity() {
+ return content.arity();
+ }
+
+ @Override
+ public String toString() {
+ return defaultToString();
+ }
+
+ @Override
+ public String getName() {
+ return content.getName();
+ }
+
+ @Override
+ public Iterable getChildren() {
+ return content.getChildren();
+ }
+
+ @Override
+ public Iterator iterator() {
+ return content.iterator();
+ }
+
+ @Override
+ public INode replace(int first, int second, int end, IList repl) {
+ INode newContent = content.replace(first, second, end, repl);
+ return new NodeWithKeywordParametersFacade(newContent, parameters); // TODO: introduce wrap() here as well
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if(o == this) {
+ return true;
+ }
+ if(o == null) {
+ return false;
+ }
+
+ if(o.getClass() == getClass()){
+ NodeWithKeywordParametersFacade other = (NodeWithKeywordParametersFacade) o;
+
+ return content.equals(other.content) && parameters.equals(other.parameters);
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return 15551 + 7 * content.hashCode() + 11 * parameters.hashCode();
+ }
+
+ @Override
+ public boolean mayHaveKeywordParameters() {
+ return true;
+ }
+
+ @Override
+ public IWithKeywordParameters extends INode> asWithKeywordParameters() {
+ return new AbstractDefaultWithKeywordParameters(content, parameters) {
+ @Override
+ protected INode wrap(INode content, Map.Immutable parameters) {
+ return new NodeWithKeywordParametersFacade(content, parameters);
+ }
+ };
+ }
+
}
diff --git a/src/main/java/io/usethesource/vallang/impl/fields/package-info.java b/src/main/java/io/usethesource/vallang/impl/fields/package-info.java
index fe2dd413e..4d6cd06af 100644
--- a/src/main/java/io/usethesource/vallang/impl/fields/package-info.java
+++ b/src/main/java/io/usethesource/vallang/impl/fields/package-info.java
@@ -1,5 +1,5 @@
/**
* This contains generic wrapper classes to implement IAnnotable and IWithKeywordParameters for different
- * host values (INode and IConstructor).
+ * host values (INode and IConstructor).
*/
package io.usethesource.vallang.impl.fields;
\ No newline at end of file
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/Constructor.java b/src/main/java/io/usethesource/vallang/impl/persistent/Constructor.java
index 2ccfceca1..643b08760 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/Constructor.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/Constructor.java
@@ -103,7 +103,7 @@ public boolean equals(@Nullable Object o){
return false;
}
-
+
@Override
public String toString() {
return defaultToString();
@@ -726,7 +726,7 @@ public IConstructor set(int index, IValue newArg) {
public int hashCode() {
return super.hashCode();
}
-
+
@Override
public boolean equals(@Nullable Object o) {
if (o == this) {
@@ -823,14 +823,14 @@ public Type getUninstantiatedConstructorType() {
/**
* As empty constructors are very common and are only based on a type that is already maximally shared we also maximally share the Constructor0 instances
- *
+ *
* This descreases both memory footprint and allocation overhead.
*/
private static final LoadingCache EMPTY_CONSTRUCTOR_SINGLETONS = Caffeine.newBuilder().build(Constructor0::new);
/*package*/ static IConstructor newConstructor(Type constructorType, IValue[] children) {
assert IConstructor.assertTypeCorrectConstructorApplication(constructorType, children);
-
+
if (constructorType.isParameterized()) {
return new TypeParameterizedConstructorN(constructorType, children);
}
@@ -853,7 +853,7 @@ private static T nonNull(@Nullable T value) {
}
return value;
}
-
+
/*package*/ static IConstructor newConstructor(Type constructorType, IValue[] children, Map kwParams) {
IConstructor r = newConstructor(constructorType, children);
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/EmptySet.java b/src/main/java/io/usethesource/vallang/impl/persistent/EmptySet.java
index d759e3335..a9467066d 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/EmptySet.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/EmptySet.java
@@ -136,7 +136,7 @@ public ISet product(ISet that) {
public boolean isSubsetOf(ISet other) {
return true;
}
-
+
@Override
public IRelation asRelation() {
return new IRelation() {
@@ -144,42 +144,42 @@ public IRelation asRelation() {
public ISet asContainer() {
return EmptySet.this;
}
-
+
@Override
public ISet compose(IRelation that) {
return EmptySet.this;
}
-
+
@Override
public ISet closure() {
return EmptySet.this;
}
-
+
@Override
public ISet closureStar() {
return EmptySet.this;
}
-
+
@Override
public ISet carrier() {
return EmptySet.this;
}
-
+
@Override
public ISet domain() {
return EmptySet.this;
}
-
+
@Override
public ISet range() {
return EmptySet.this;
}
-
+
@Override
public ISet empty() {
return EmptySet.this;
}
-
+
@Override
public ISet index(IValue key) {
return EmptySet.this;
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/List.java b/src/main/java/io/usethesource/vallang/impl/persistent/List.java
index e6373e049..47a349905 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/List.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/List.java
@@ -192,7 +192,7 @@ IList materializedSublist(int offset, int length){
Type oldElementType = getType().getElementType();
Type newElementType = TypeFactory.getInstance().voidType();
-
+
for(IValue el : newData) {
if (newElementType == oldElementType) {
// the type can only get more specific
@@ -223,7 +223,7 @@ public boolean equals(@Nullable Object o){
if (o == this) {
return true;
}
-
+
if (o == null) {
return false;
}
@@ -326,7 +326,7 @@ public boolean equals(@Nullable Object o){
if (o == this) {
return true;
}
-
+
if (o == null) {
return false;
}
@@ -340,7 +340,7 @@ public boolean equals(@Nullable Object o){
if (o instanceof IList) {
return defaultEquals(o);
}
-
+
return false;
}
@@ -503,7 +503,7 @@ public IList replace(int arg0, int arg1, int arg2, IList arg3) {
@Override
public IList reverse() {
ListWriter w = new ListWriter();
- for(int i = offset + length - 1; i >= offset; i--){
+ for(int i = offset + length - 1; i >= offset; i--){
w.append(base.get(i));
}
return w.done();
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/ListRelation.java b/src/main/java/io/usethesource/vallang/impl/persistent/ListRelation.java
index d029d4fb9..bc895a721 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/ListRelation.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/ListRelation.java
@@ -14,12 +14,12 @@ public class ListRelation implements IRelation {
public ListRelation(IList list) {
this.list = list;
}
-
+
@Override
public IList asContainer() {
return list;
}
-
+
@Override
public IList closure() {
// will throw exception if not binary and reflexive
@@ -41,11 +41,11 @@ public IList closure() {
w.append(t1);
}
}
-
+
tmp = tmp.asContainer().concat(w.done()).asRelation();
addedTuples.clear();
}
-
+
return tmp.asContainer();
}
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/ListWriter.java b/src/main/java/io/usethesource/vallang/impl/persistent/ListWriter.java
index c18220ad7..84b3f9dbe 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/ListWriter.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/ListWriter.java
@@ -25,218 +25,218 @@
/**
* Implementation of IListWriter.
- *
+ *
* @author Arnold Lankamp
*/
/*package*/ class ListWriter implements IListWriter{
private Type elementType;
- private final ShareableValuesList data;
- private @MonotonicNonNull IList constructedList;
- private final boolean unique;
-
- /*package*/ ListWriter() {
- super();
-
- this.elementType = TypeFactory.getInstance().voidType();
- data = new ShareableValuesList();
- unique = false;
- }
-
- private ListWriter(boolean unique) {
- this.elementType = TypeFactory.getInstance().voidType();
+ private final ShareableValuesList data;
+ private @MonotonicNonNull IList constructedList;
+ private final boolean unique;
+
+ /*package*/ ListWriter() {
+ super();
+
+ this.elementType = TypeFactory.getInstance().voidType();
+ data = new ShareableValuesList();
+ unique = false;
+ }
+
+ private ListWriter(boolean unique) {
+ this.elementType = TypeFactory.getInstance().voidType();
data = new ShareableValuesList();
- this.unique = unique;
- }
-
- @Override
+ this.unique = unique;
+ }
+
+ @Override
public IWriter unique() {
return new ListWriter(true);
}
- @Override
- public Iterator iterator() {
- return data.iterator();
- }
-
- /*package*/ ListWriter(Type elementType, ShareableValuesList data){
- super();
-
- this.elementType = elementType;
- this.data = data;
- this.unique = false;
- }
-
- @Override
- public void insertTuple(IValue... fields) {
- insert(Tuple.newTuple(fields));
- }
-
- public void append(IValue element){
- checkMutation();
-
- if (unique && data.contains(element)) {
- return;
+ @Override
+ public Iterator iterator() {
+ return data.iterator();
+ }
+
+ /*package*/ ListWriter(Type elementType, ShareableValuesList data){
+ super();
+
+ this.elementType = elementType;
+ this.data = data;
+ this.unique = false;
+ }
+
+ @Override
+ public void insertTuple(IValue... fields) {
+ insert(Tuple.newTuple(fields));
+ }
+
+ public void append(IValue element){
+ checkMutation();
+
+ if (unique && data.contains(element)) {
+ return;
+ }
+
+ updateType(element);
+ data.append(element);
+ }
+
+ @Override
+ public void appendTuple(IValue... fields) {
+ append(Tuple.newTuple(fields));
+ }
+
+ private void updateType(IValue element) {
+ elementType = elementType.lub(element.getType());
+ }
+
+ @Override
+ public void append(IValue... elems){
+ checkMutation();
+ boolean notUnique = false;
+
+ for (IValue elem : elems){
+ if (unique && data.contains(elem)) {
+ notUnique = true;
+ break;
+ }
+ updateType(elem);
+ }
+
+ if (!notUnique) {
+ data.appendAll(elems);
+ }
+ else {
+ for (IValue next : elems) {
+ if (unique && data.contains(next)) {
+ continue;
+ }
+
+ updateType(next);
+ data.append(next);
+ }
+ }
+ }
+
+ @Override
+ public void appendAll(Iterable extends IValue> collection){
+ checkMutation();
+
+ for (IValue next : collection) {
+ if (unique && data.contains(next)) {
+ continue;
+ }
+
+ updateType(next);
+ data.append(next);
+ }
+ }
+
+ public void insert(IValue elem){
+ checkMutation();
+ if (unique && data.contains(elem)) {
+ return;
+ }
+ updateType(elem);
+ data.insert(elem);
+ }
+
+ @Override
+ public void insert(IValue... elements){
+ insert(elements, 0, elements.length);
+ }
+
+ @Override
+ public void insert(IValue[] elements, int start, int length){
+ checkMutation();
+ checkBounds(elements, start, length);
+
+ for(int i = start + length - 1; i >= start; i--){
+ updateType(elements[i]);
+
+ if (unique && data.contains(elements[i])) {
+ continue;
+ }
+
+ data.insert(elements[i]);
}
-
- updateType(element);
- data.append(element);
- }
-
- @Override
- public void appendTuple(IValue... fields) {
- append(Tuple.newTuple(fields));
- }
-
- private void updateType(IValue element) {
- elementType = elementType.lub(element.getType());
- }
-
- @Override
- public void append(IValue... elems){
- checkMutation();
- boolean notUnique = false;
-
- for (IValue elem : elems){
- if (unique && data.contains(elem)) {
- notUnique = true;
- break;
- }
- updateType(elem);
- }
-
- if (!notUnique) {
- data.appendAll(elems);
- }
- else {
- for (IValue next : elems) {
- if (unique && data.contains(next)) {
- continue;
- }
-
- updateType(next);
- data.append(next);
- }
- }
- }
-
- @Override
- public void appendAll(Iterable extends IValue> collection){
- checkMutation();
-
- for (IValue next : collection) {
- if (unique && data.contains(next)) {
- continue;
- }
-
- updateType(next);
- data.append(next);
- }
- }
-
- public void insert(IValue elem){
- checkMutation();
- if (unique && data.contains(elem)) {
- return;
- }
- updateType(elem);
- data.insert(elem);
- }
-
- @Override
- public void insert(IValue... elements){
- insert(elements, 0, elements.length);
- }
-
- @Override
- public void insert(IValue[] elements, int start, int length){
- checkMutation();
- checkBounds(elements, start, length);
-
- for(int i = start + length - 1; i >= start; i--){
- updateType(elements[i]);
-
- if (unique && data.contains(elements[i])) {
- continue;
- }
-
- data.insert(elements[i]);
- }
- }
-
- @Override
- public void insertAll(Iterable extends IValue> collection){
- checkMutation();
-
- for (IValue next : collection) {
- if (unique && data.contains(next)) {
+ }
+
+ @Override
+ public void insertAll(Iterable extends IValue> collection){
+ checkMutation();
+
+ for (IValue next : collection) {
+ if (unique && data.contains(next)) {
continue;
}
- updateType(next);
- data.insert(next);
- }
- }
-
- @Override
- public void insertAt(int index, IValue... elements){
- insertAt(index, elements, 0, 0);
- }
-
- @Override
- public void insertAt(int index, IValue[] elements, int start, int length){
- checkMutation();
- checkBounds(elements, start, length);
-
- for(int i = start + length - 1; i >= start; i--){
- updateType(elements[i]);
- data.insertAt(index, elements[i]);
- }
- }
-
- @Override
- public IValue replaceAt(int index, IValue element){
- checkMutation();
-
- updateType(element);
- return data.set(index, element);
- }
-
- @Override
- public IValue get(int i) throws IndexOutOfBoundsException {
- return data.get(i);
- }
-
- @Override
- public int length() {
- return data.size();
- }
-
- protected void checkMutation() {
- if (constructedList != null) {
- throw new UnsupportedOperationException("Mutation of a finalized list is not supported.");
- }
- }
-
- private void checkBounds(IValue[] elems, int start, int length){
- if (start < 0) {
- throw new ArrayIndexOutOfBoundsException("start < 0");
- }
-
- if ((start + length) > elems.length) {
- throw new ArrayIndexOutOfBoundsException("(start + length) > elems.length");
- }
- }
-
- @Override
- public IList done() {
- if (constructedList == null) {
- constructedList = List.newList(elementType, data);
- }
-
- return constructedList;
- }
-
- @Override
- public Supplier> supplier() {
- return () -> new ListWriter();
- }
+ updateType(next);
+ data.insert(next);
+ }
+ }
+
+ @Override
+ public void insertAt(int index, IValue... elements){
+ insertAt(index, elements, 0, 0);
+ }
+
+ @Override
+ public void insertAt(int index, IValue[] elements, int start, int length){
+ checkMutation();
+ checkBounds(elements, start, length);
+
+ for(int i = start + length - 1; i >= start; i--){
+ updateType(elements[i]);
+ data.insertAt(index, elements[i]);
+ }
+ }
+
+ @Override
+ public IValue replaceAt(int index, IValue element){
+ checkMutation();
+
+ updateType(element);
+ return data.set(index, element);
+ }
+
+ @Override
+ public IValue get(int i) throws IndexOutOfBoundsException {
+ return data.get(i);
+ }
+
+ @Override
+ public int length() {
+ return data.size();
+ }
+
+ protected void checkMutation() {
+ if (constructedList != null) {
+ throw new UnsupportedOperationException("Mutation of a finalized list is not supported.");
+ }
+ }
+
+ private void checkBounds(IValue[] elems, int start, int length){
+ if (start < 0) {
+ throw new ArrayIndexOutOfBoundsException("start < 0");
+ }
+
+ if ((start + length) > elems.length) {
+ throw new ArrayIndexOutOfBoundsException("(start + length) > elems.length");
+ }
+ }
+
+ @Override
+ public IList done() {
+ if (constructedList == null) {
+ constructedList = List.newList(elementType, data);
+ }
+
+ return constructedList;
+ }
+
+ @Override
+ public Supplier> supplier() {
+ return () -> new ListWriter();
+ }
}
\ No newline at end of file
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/MapWriter.java b/src/main/java/io/usethesource/vallang/impl/persistent/MapWriter.java
index 5ec06c50c..b199841c8 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/MapWriter.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/MapWriter.java
@@ -29,102 +29,102 @@
final class MapWriter implements IMapWriter {
- private AbstractTypeBag keyTypeBag = AbstractTypeBag.of();
- private AbstractTypeBag valTypeBag = AbstractTypeBag.of();
- private final Map.Transient mapContent = Map.Transient.of();
-
- private @MonotonicNonNull IMap constructedMap;
-
- @Override
- public void put(IValue key, IValue value) {
- checkMutation();
-
- final Type keyType = key.getType();
- final Type valType = value.getType();
-
- int oldSize = mapContent.size();
-
- final IValue replaced = mapContent.__put(key, value);
-
- if (oldSize == mapContent.size() && replaced == null) {
- // update nothing because they key/value pair was already there
- }
- else if (replaced != null) {
- // only update the val since the key was already there
- valTypeBag = valTypeBag.decrease(replaced.getType()).increase(valType);
- }
- else {
- // add the new entry for both bags since its entirely new
- keyTypeBag = keyTypeBag.increase(keyType);
- valTypeBag = valTypeBag.increase(valType);
- }
-
- assert mapContent.size() == keyTypeBag.sum();
- }
+ private AbstractTypeBag keyTypeBag = AbstractTypeBag.of();
+ private AbstractTypeBag valTypeBag = AbstractTypeBag.of();
+ private final Map.Transient mapContent = Map.Transient.of();
+
+ private @MonotonicNonNull IMap constructedMap;
+
+ @Override
+ public void put(IValue key, IValue value) {
+ checkMutation();
+
+ final Type keyType = key.getType();
+ final Type valType = value.getType();
+
+ int oldSize = mapContent.size();
+
+ final IValue replaced = mapContent.__put(key, value);
+
+ if (oldSize == mapContent.size() && replaced == null) {
+ // update nothing because they key/value pair was already there
+ }
+ else if (replaced != null) {
+ // only update the val since the key was already there
+ valTypeBag = valTypeBag.decrease(replaced.getType()).increase(valType);
+ }
+ else {
+ // add the new entry for both bags since its entirely new
+ keyTypeBag = keyTypeBag.increase(keyType);
+ valTypeBag = valTypeBag.increase(valType);
+ }
+
+ assert mapContent.size() == keyTypeBag.sum();
+ }
@Override
- public void putAll(IMap map) {
- putAll(map.entryIterator());
- }
+ public void putAll(IMap map) {
+ putAll(map.entryIterator());
+ }
- @Override
- public void putAll(java.util.Map map) {
- putAll(map.entrySet().iterator());
- }
+ @Override
+ public void putAll(java.util.Map map) {
+ putAll(map.entrySet().iterator());
+ }
- private void putAll(Iterator> entryIterator) {
- checkMutation();
+ private void putAll(Iterator> entryIterator) {
+ checkMutation();
- while (entryIterator.hasNext()) {
- Entry entry = entryIterator.next();
- IValue key = entry.getKey();
- IValue value = entry.getValue();
+ while (entryIterator.hasNext()) {
+ Entry entry = entryIterator.next();
+ IValue key = entry.getKey();
+ IValue value = entry.getValue();
- this.put(key, value);
- }
- }
+ this.put(key, value);
+ }
+ }
- @Override
- public void insert(IValue... values) {
- insertAll(Arrays.asList(values));
- }
+ @Override
+ public void insert(IValue... values) {
+ insertAll(Arrays.asList(values));
+ }
- @Override
- public void insertAll(Iterable extends IValue> collection) {
- checkMutation();
+ @Override
+ public void insertAll(Iterable extends IValue> collection) {
+ checkMutation();
- Iterator extends IValue> collectionIterator = collection.iterator();
- while (collectionIterator.hasNext()) {
- final Object item = collectionIterator.next();
+ Iterator extends IValue> collectionIterator = collection.iterator();
+ while (collectionIterator.hasNext()) {
+ final Object item = collectionIterator.next();
- if (!(item instanceof ITuple)) {
- throw new IllegalArgumentException("Argument must be of ITuple type.");
- }
+ if (!(item instanceof ITuple)) {
+ throw new IllegalArgumentException("Argument must be of ITuple type.");
+ }
- final ITuple tuple = (ITuple) item;
+ final ITuple tuple = (ITuple) item;
- if (tuple.arity() != 2) {
- throw new IllegalArgumentException("Tuple must have an arity of 2.");
- }
+ if (tuple.arity() != 2) {
+ throw new IllegalArgumentException("Tuple must have an arity of 2.");
+ }
- put(tuple.get(0), tuple.get(1));
- }
- }
+ put(tuple.get(0), tuple.get(1));
+ }
+ }
- protected void checkMutation() {
- if (constructedMap != null) {
- throw new UnsupportedOperationException("Mutation of a finalized map is not supported.");
- }
- }
+ protected void checkMutation() {
+ if (constructedMap != null) {
+ throw new UnsupportedOperationException("Mutation of a finalized map is not supported.");
+ }
+ }
- @Override
- public IMap done() {
- if (constructedMap == null) {
- constructedMap = new PersistentHashMap(keyTypeBag, valTypeBag, mapContent.freeze());
- }
+ @Override
+ public IMap done() {
+ if (constructedMap == null) {
+ constructedMap = new PersistentHashMap(keyTypeBag, valTypeBag, mapContent.freeze());
+ }
- return constructedMap;
- }
+ return constructedMap;
+ }
@Override
public void insertTuple(IValue... fields) {
@@ -135,7 +135,7 @@ public void insertTuple(IValue... fields) {
public Iterator iterator() {
return mapContent.keyIterator();
}
-
+
@Override
public IValue get(IValue key) {
return mapContent.get(key);
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/Node.java b/src/main/java/io/usethesource/vallang/impl/persistent/Node.java
index 407f13b18..a905228ff 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/Node.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/Node.java
@@ -24,130 +24,130 @@
import io.usethesource.vallang.type.TypeFactory;
/*package*/ class Node implements INode {
- protected static final Type NODE_TYPE = TF.nodeType();
- protected static final Type VALUE_TYPE = TypeFactory.getInstance().valueType();
-
- protected final String name;
- protected final IValue[] children;
-
- /*package*/ static INode newNode(String name, IValue[] children) {
- return new Node(name, children);
- }
-
- Node(String name, IValue[] children) {
- super();
-
- this.name = name.intern();
- this.children = children;
- }
-
- /*package*/ static INode newNode(String name, IList children) {
- return new Node(name, children);
- }
-
- private Node(String name, IList children) {
- super();
- IValue[] childArray = new IValue[children.length()];
- this.name = name.intern();
- for(int i = 0; i < childArray.length; i++){
- childArray[i] = children.get(i);
- }
- this.children = childArray;
- }
-
- @Override
- public String toString() {
- return defaultToString();
- }
-
- @Override
- public Type getType(){
- return NODE_TYPE;
- }
-
- @Override
- public int arity(){
- return children.length;
- }
-
- @Override
+ protected static final Type NODE_TYPE = TF.nodeType();
+ protected static final Type VALUE_TYPE = TypeFactory.getInstance().valueType();
+
+ protected final String name;
+ protected final IValue[] children;
+
+ /*package*/ static INode newNode(String name, IValue[] children) {
+ return new Node(name, children);
+ }
+
+ Node(String name, IValue[] children) {
+ super();
+
+ this.name = name.intern();
+ this.children = children;
+ }
+
+ /*package*/ static INode newNode(String name, IList children) {
+ return new Node(name, children);
+ }
+
+ private Node(String name, IList children) {
+ super();
+ IValue[] childArray = new IValue[children.length()];
+ this.name = name.intern();
+ for(int i = 0; i < childArray.length; i++){
+ childArray[i] = children.get(i);
+ }
+ this.children = childArray;
+ }
+
+ @Override
+ public String toString() {
+ return defaultToString();
+ }
+
+ @Override
+ public Type getType(){
+ return NODE_TYPE;
+ }
+
+ @Override
+ public int arity(){
+ return children.length;
+ }
+
+ @Override
public INode setChildren(IValue[] childArray) {
return new Node(name, childArray);
}
-
- @Override
- public IValue get(int i){
- return children[i];
- }
-
- @Override
- public String getName(){
- return name;
- }
-
- @Override
- public Iterator iterator(){
- return ArrayIterator.of(children);
- }
-
- @Override
- public Iterable getChildren(){
- return this;
- }
-
- @Override
- public INode set(int i, IValue arg){
- IValue[] newChildren = children.clone();
- newChildren[i] = arg;
-
- return newNode(name, newChildren);
- }
-
- @Override
- public int hashCode() {
- int hash = name.hashCode();
-
- for(int i = children.length - 1; i >= 0; i--){
- hash = (hash << 23) + (hash >> 5);
- hash ^= children[i].hashCode();
- }
- return hash;
- }
-
- @Override
- public boolean equals(@Nullable Object o){
- if (o == this) {
- return true;
- }
-
- if (o == null) {
- return false;
- }
-
- if (o.getClass() != getClass()) {
- return false;
- }
-
- Node other = (Node) o;
-
- // Yes '!=' works here, since it has been interned.
- if (name != other.name) {
- return false;
- }
-
- IValue[] otherChildren = other.children;
- int nrOfChildren = children.length;
-
- if (otherChildren.length != nrOfChildren) {
- return false;
- }
-
- for (int i = nrOfChildren - 1; i >= 0; i--) {
- if (!otherChildren[i].equals(children[i])) {
- return false;
- }
- }
-
- return true;
- }
+
+ @Override
+ public IValue get(int i){
+ return children[i];
+ }
+
+ @Override
+ public String getName(){
+ return name;
+ }
+
+ @Override
+ public Iterator iterator(){
+ return ArrayIterator.of(children);
+ }
+
+ @Override
+ public Iterable getChildren(){
+ return this;
+ }
+
+ @Override
+ public INode set(int i, IValue arg){
+ IValue[] newChildren = children.clone();
+ newChildren[i] = arg;
+
+ return newNode(name, newChildren);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = name.hashCode();
+
+ for(int i = children.length - 1; i >= 0; i--){
+ hash = (hash << 23) + (hash >> 5);
+ hash ^= children[i].hashCode();
+ }
+ return hash;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o){
+ if (o == this) {
+ return true;
+ }
+
+ if (o == null) {
+ return false;
+ }
+
+ if (o.getClass() != getClass()) {
+ return false;
+ }
+
+ Node other = (Node) o;
+
+ // Yes '!=' works here, since it has been interned.
+ if (name != other.name) {
+ return false;
+ }
+
+ IValue[] otherChildren = other.children;
+ int nrOfChildren = children.length;
+
+ if (otherChildren.length != nrOfChildren) {
+ return false;
+ }
+
+ for (int i = nrOfChildren - 1; i >= 0; i--) {
+ if (!otherChildren[i].equals(children[i])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/PersistentHashIndexedBinaryRelation.java b/src/main/java/io/usethesource/vallang/impl/persistent/PersistentHashIndexedBinaryRelation.java
index f9c936224..75191d9aa 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/PersistentHashIndexedBinaryRelation.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/PersistentHashIndexedBinaryRelation.java
@@ -43,702 +43,702 @@
import io.usethesource.vallang.util.AbstractTypeBag;
/**
- * Implements both ISet and IRelation, by indexing on the first column
- * and reconstructing binary tuples while iterating. This class
- * is faster for compose and closure because the index has been pre-computed.
- */
+* Implements both ISet and IRelation, by indexing on the first column
+* and reconstructing binary tuples while iterating. This class
+* is faster for compose and closure because the index has been pre-computed.
+*/
public final class PersistentHashIndexedBinaryRelation implements ISet, IRelation {
- private @MonotonicNonNull Type cachedRelationType;
- private final AbstractTypeBag keyTypeBag;
- private final AbstractTypeBag valTypeBag;
- private final SetMultimap.Immutable content;
-
- /**
- * Construction of persistent indexed binary relation with multi-map backend.
- *
- * DO NOT CALL OUTSIDE OF {@link PersistentSetFactory}.
- *
- * @param keyTypeBag precise dynamic type of first data column
- * @param valTypeBag precise dynamic type of second data column
- * @param content immutable multi-map
- */
- PersistentHashIndexedBinaryRelation(AbstractTypeBag keyTypeBag, AbstractTypeBag valTypeBag,
- SetMultimap.Immutable content) {
- this.keyTypeBag = Objects.requireNonNull(keyTypeBag);
- this.valTypeBag = Objects.requireNonNull(valTypeBag);
- this.content = Objects.requireNonNull(content);
-
- assert USE_MULTIMAP_BINARY_RELATIONS
+ private @MonotonicNonNull Type cachedRelationType;
+ private final AbstractTypeBag keyTypeBag;
+ private final AbstractTypeBag valTypeBag;
+ private final SetMultimap.Immutable content;
+
+ /**
+ * Construction of persistent indexed binary relation with multi-map backend.
+ *
+ * DO NOT CALL OUTSIDE OF {@link PersistentSetFactory}.
+ *
+ * @param keyTypeBag precise dynamic type of first data column
+ * @param valTypeBag precise dynamic type of second data column
+ * @param content immutable multi-map
+ */
+ PersistentHashIndexedBinaryRelation(AbstractTypeBag keyTypeBag, AbstractTypeBag valTypeBag,
+ SetMultimap.Immutable content) {
+ this.keyTypeBag = Objects.requireNonNull(keyTypeBag);
+ this.valTypeBag = Objects.requireNonNull(valTypeBag);
+ this.content = Objects.requireNonNull(content);
+
+ assert USE_MULTIMAP_BINARY_RELATIONS
&& isTupleOfArityTwo.test(TF.tupleType(keyTypeBag.lub(), valTypeBag.lub()));
- assert USE_MULTIMAP_BINARY_RELATIONS && !content.isEmpty();
- assert USE_MULTIMAP_BINARY_RELATIONS && checkDynamicType(keyTypeBag, valTypeBag, content);
- }
+ assert USE_MULTIMAP_BINARY_RELATIONS && !content.isEmpty();
+ assert USE_MULTIMAP_BINARY_RELATIONS && checkDynamicType(keyTypeBag, valTypeBag, content);
+ }
- @Override
- public IRelation asRelation() {
- return this;
- }
+ @Override
+ public IRelation asRelation() {
+ return this;
+ }
- private static final boolean checkDynamicType(final AbstractTypeBag keyTypeBag,
- final AbstractTypeBag valTypeBag, final SetMultimap.Immutable content) {
+ private static final boolean checkDynamicType(final AbstractTypeBag keyTypeBag,
+ final AbstractTypeBag valTypeBag, final SetMultimap.Immutable content) {
- final AbstractTypeBag expectedKeyTypeBag = calcTypeBag(content, Map.Entry::getKey);
- final AbstractTypeBag expectedValTypeBag = calcTypeBag(content, Map.Entry::getValue);
+ final AbstractTypeBag expectedKeyTypeBag = calcTypeBag(content, Map.Entry::getKey);
+ final AbstractTypeBag expectedValTypeBag = calcTypeBag(content, Map.Entry::getValue);
- boolean keyTypesEqual = expectedKeyTypeBag.equals(keyTypeBag);
- boolean valTypesEqual = expectedValTypeBag.equals(valTypeBag);
+ boolean keyTypesEqual = expectedKeyTypeBag.equals(keyTypeBag);
+ boolean valTypesEqual = expectedValTypeBag.equals(valTypeBag);
- return keyTypesEqual && valTypesEqual;
- }
-
- @Override
- public ISetWriter writer() {
- return ValueFactory.getInstance().setWriter();
- }
+ return keyTypesEqual && valTypesEqual;
+ }
- @Override
- public Type getType() {
- if (cachedRelationType == null) {
- cachedRelationType = TF.relType(keyTypeBag.lub(), valTypeBag.lub());
+ @Override
+ public ISetWriter writer() {
+ return ValueFactory.getInstance().setWriter();
}
- return cachedRelationType;
- }
- private final BiFunction tupleConverter() {
- return (first, second) -> Tuple.newTuple(first, second);
- }
+ @Override
+ public Type getType() {
+ if (cachedRelationType == null) {
+ cachedRelationType = TF.relType(keyTypeBag.lub(), valTypeBag.lub());
+ }
+ return cachedRelationType;
+ }
- @Override
- public boolean isEmpty() {
- return content.isEmpty();
- }
+ private final BiFunction tupleConverter() {
+ return (first, second) -> Tuple.newTuple(first, second);
+ }
- @Override
- public ISet insert(IValue value) {
- if (!isTupleOfArityTwo.test(value.getType())) {
- /*
- * NOTE: conversion of set representations are assumed to be scarce, but are costly if they
- * happen though.
- */
- final Stream tupleStream = content.tupleStream(tupleConverter());
- return Stream.concat(tupleStream, Stream.of(value)).collect(ValueCollectors.toSet());
+ @Override
+ public boolean isEmpty() {
+ return content.isEmpty();
}
- final ITuple tuple = (ITuple) value;
- final IValue key = tuple.get(0);
- final IValue val = tuple.get(1);
+ @Override
+ public ISet insert(IValue value) {
+ if (!isTupleOfArityTwo.test(value.getType())) {
+ /*
+ * NOTE: conversion of set representations are assumed to be scarce, but are costly if they
+ * happen though.
+ */
+ final Stream tupleStream = content.tupleStream(tupleConverter());
+ return Stream.concat(tupleStream, Stream.of(value)).collect(ValueCollectors.toSet());
+ }
+
+ final ITuple tuple = (ITuple) value;
+ final IValue key = tuple.get(0);
+ final IValue val = tuple.get(1);
+
+ final SetMultimap.Immutable contentNew = content.__insert(key, val);
- final SetMultimap.Immutable contentNew = content.__insert(key, val);
+ if (content == contentNew) {
+ return this;
+ }
- if (content == contentNew) {
- return this;
+ final AbstractTypeBag keyTypeBagNew = keyTypeBag.increase(key.getType());
+ final AbstractTypeBag valTypeBagNew = valTypeBag.increase(val.getType());
+
+ return PersistentSetFactory.from(keyTypeBagNew, valTypeBagNew, contentNew);
}
- final AbstractTypeBag keyTypeBagNew = keyTypeBag.increase(key.getType());
- final AbstractTypeBag valTypeBagNew = valTypeBag.increase(val.getType());
+ @Override
+ public ISet delete(IValue value) {
+ if (!isTupleOfArityTwo.test(value.getType())) {
+ return this;
+ }
+
+ final ITuple tuple = (ITuple) value;
+ final IValue key = tuple.get(0);
+ final IValue val = tuple.get(1);
+
+ final SetMultimap.Immutable contentNew = content.__remove(key, val);
+
+ if (content == contentNew) {
+ return this;
+ }
+
+ final AbstractTypeBag keyTypeBagNew = keyTypeBag.decrease(key.getType());
+ final AbstractTypeBag valTypeBagNew = valTypeBag.decrease(val.getType());
- return PersistentSetFactory.from(keyTypeBagNew, valTypeBagNew, contentNew);
- }
+ return PersistentSetFactory.from(keyTypeBagNew, valTypeBagNew, contentNew);
+ }
- @Override
- public ISet delete(IValue value) {
- if (!isTupleOfArityTwo.test(value.getType())) {
- return this;
+ @Override
+ public int size() {
+ return content.size();
}
- final ITuple tuple = (ITuple) value;
- final IValue key = tuple.get(0);
- final IValue val = tuple.get(1);
+ @Override
+ public boolean contains(IValue value) {
+ if (!isTupleOfArityTwo.test(value.getType())) {
+ return false;
+ }
- final SetMultimap.Immutable contentNew = content.__remove(key, val);
+ final ITuple tuple = (ITuple) value;
+ final IValue key = tuple.get(0);
+ final IValue val = tuple.get(1);
- if (content == contentNew) {
- return this;
+ return content.containsEntry(key, val);
}
- final AbstractTypeBag keyTypeBagNew = keyTypeBag.decrease(key.getType());
- final AbstractTypeBag valTypeBagNew = valTypeBag.decrease(val.getType());
+ @Override
+ public Iterator iterator() {
+ return content.tupleIterator(Tuple::newTuple);
+ }
- return PersistentSetFactory.from(keyTypeBagNew, valTypeBagNew, contentNew);
- }
+ @Override
+ public int hashCode() {
+ final int hashCode =
+ StreamSupport.stream(spliterator(), false).mapToInt(tuple -> tuple.hashCode()).sum();
- @Override
- public int size() {
- return content.size();
- }
+ return hashCode;
+ }
- @Override
- public boolean contains(IValue value) {
- if (!isTupleOfArityTwo.test(value.getType())) {
- return false;
+ @Override
+ public String toString() {
+ return defaultToString();
}
- final ITuple tuple = (ITuple) value;
- final IValue key = tuple.get(0);
- final IValue val = tuple.get(1);
+ @Override
+ public boolean equals(@Nullable Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (other == null) {
+ return false;
+ }
+
+ if (other instanceof PersistentHashIndexedBinaryRelation) {
+ PersistentHashIndexedBinaryRelation that = (PersistentHashIndexedBinaryRelation) other;
- return content.containsEntry(key, val);
- }
+ if (this.getType() != that.getType()) {
+ return false;
+ }
- @Override
- public Iterator iterator() {
- return content.tupleIterator(Tuple::newTuple);
- }
+ if (this.size() != that.size()) {
+ return false;
+ }
- @Override
- public int hashCode() {
- final int hashCode =
- StreamSupport.stream(spliterator(), false).mapToInt(tuple -> tuple.hashCode()).sum();
+ return content.equals(that.content);
+ }
- return hashCode;
- }
-
- @Override
- public String toString() {
- return defaultToString();
- }
+ if (other instanceof ISet) {
+ return defaultEquals(other);
+ }
- @Override
- public boolean equals(@Nullable Object other) {
- if (other == this) {
- return true;
+ return false;
}
-
- if (other == null) {
- return false;
+
+ @Override
+ public ISet union(ISet other) {
+ if (other == this) {
+ return this;
+ }
+ if (other == null) {
+ return this;
+ }
+
+ if (other instanceof PersistentHashIndexedBinaryRelation) {
+ PersistentHashIndexedBinaryRelation that = (PersistentHashIndexedBinaryRelation) other;
+
+ final SetMultimap.Immutable one;
+ final SetMultimap.Immutable two;
+ AbstractTypeBag keyTypeBagNew;
+ AbstractTypeBag valTypeBagNew;
+ final ISet def;
+
+ if (that.size() >= this.size()) {
+ def = that;
+ one = that.content;
+ keyTypeBagNew = that.keyTypeBag;
+ valTypeBagNew = that.valTypeBag;
+ two = this.content;
+ } else {
+ def = this;
+ one = this.content;
+ keyTypeBagNew = this.keyTypeBag;
+ valTypeBagNew = this.valTypeBag;
+ two = that.content;
+ }
+
+ final SetMultimap.Transient tmp = one.asTransient();
+ boolean modified = false;
+
+ for (Map.Entry entry : two.entrySet()) {
+ final IValue key = entry.getKey();
+ final IValue val = entry.getValue();
+
+ if (tmp.__insert(key, val)) {
+ modified = true;
+ keyTypeBagNew = keyTypeBagNew.increase(key.getType());
+ valTypeBagNew = valTypeBagNew.increase(val.getType());
+ }
+ }
+
+ if (modified) {
+ return PersistentSetFactory.from(keyTypeBagNew, valTypeBagNew, tmp.freeze());
+ }
+ return def;
+ } else {
+ return ISet.super.union(other);
+ }
}
- if (other instanceof PersistentHashIndexedBinaryRelation) {
- PersistentHashIndexedBinaryRelation that = (PersistentHashIndexedBinaryRelation) other;
+ @Override
+ public ISet intersect(ISet other) {
+ if (other == this) {
+ return this;
+ }
+ if (other == null) {
+ return EmptySet.EMPTY_SET;
+ }
+
+ if (other instanceof PersistentHashIndexedBinaryRelation) {
+ PersistentHashIndexedBinaryRelation that = (PersistentHashIndexedBinaryRelation) other;
+
+ final SetMultimap.Immutable one;
+ final SetMultimap.Immutable two;
+ AbstractTypeBag keyTypeBagNew;
+ AbstractTypeBag valTypeBagNew;
+ final ISet def;
+
+ if (that.size() >= this.size()) {
+ def = this;
+ one = this.content;
+ keyTypeBagNew = this.keyTypeBag;
+ valTypeBagNew = this.valTypeBag;
+ two = that.content;
+ } else {
+ def = that;
+ one = that.content;
+ keyTypeBagNew = that.keyTypeBag;
+ valTypeBagNew = that.valTypeBag;
+ two = this.content;
+ }
- if (this.getType() != that.getType()) {
- return false;
- }
+ final SetMultimap.Transient tmp = one.asTransient();
+ boolean modified = false;
- if (this.size() != that.size()) {
- return false;
- }
+ for (Iterator> it = tmp.entryIterator(); it.hasNext(); ) {
+ final Map.Entry tuple = it.next();
+ final IValue key = tuple.getKey();
+ final IValue val = tuple.getValue();
+
+ if (!two.containsEntry(key, val)) {
+ it.remove();
+ modified = true;
+ keyTypeBagNew = keyTypeBagNew.decrease(key.getType());
+ valTypeBagNew = valTypeBagNew.decrease(val.getType());
+ }
+ }
+
+ if (modified) {
+ return PersistentSetFactory.from(keyTypeBagNew, valTypeBagNew, tmp.freeze());
+ }
+ return def;
+ } else {
+ return ISet.super.intersect(other);
+ }
+ }
+
+ @Override
+ public ISet subtract(ISet other) {
+ if (other == this) {
+ return EmptySet.EMPTY_SET;
+ }
+ if (other == null) {
+ return this;
+ }
+
+ if (other instanceof PersistentHashIndexedBinaryRelation) {
+ PersistentHashIndexedBinaryRelation that = (PersistentHashIndexedBinaryRelation) other;
+
+ final SetMultimap.Immutable one;
+ final SetMultimap.Immutable two;
+ AbstractTypeBag keyTypeBagNew;
+ AbstractTypeBag valTypeBagNew;
+ final ISet def;
+
+ def = this;
+ one = this.content;
+ keyTypeBagNew = this.keyTypeBag;
+ valTypeBagNew = this.valTypeBag;
+ two = that.content;
+
+ final SetMultimap.Transient tmp = one.asTransient();
+ boolean modified = false;
+
+ for (Map.Entry tuple : two.entrySet()) {
+ final IValue key = tuple.getKey();
+ final IValue val = tuple.getValue();
+
+ if (tmp.__remove(key, val)) {
+ modified = true;
+ keyTypeBagNew = keyTypeBagNew.decrease(key.getType());
+ valTypeBagNew = valTypeBagNew.decrease(val.getType());
+ }
+ }
+
+ if (modified) {
+ return PersistentSetFactory.from(keyTypeBagNew, valTypeBagNew, tmp.freeze());
+ }
+ return def;
+ } else {
+ return ISet.super.subtract(other);
+ }
+ }
+
+ @Override
+ public ISet compose(IRelation otherSetRelation) {
+ if (otherSetRelation.getClass() != this.getClass()) {
+ return IRelation.super.compose(otherSetRelation);
+ }
+
+ // Here we can optimize the compose operation because we have already an index in memory
+ // for both relations
+
+ final PersistentHashIndexedBinaryRelation thatSet =
+ (PersistentHashIndexedBinaryRelation) otherSetRelation.asContainer();
+
+ final SetMultimap.Immutable xy = content;
+ final SetMultimap.Immutable yz = thatSet.content;
+
+ /**
+ * The code below is still sub-optimal because it operates on the logical (rather than the structural) level.
+ *
+ * TODO: nodes should get proper support for stream processing such that the following template can be used:
+ *
+ * // @formatter:off
+ * final Stream> localStream = null;
+ * final Node updatedNode = localStream
+ * .filter((x, y) -> yz.containsKey(y))
+ * .mapValues(y -> yz.get(y))
+ * .collect(toNode());
+ * // @formatter:on
+ */
+ final SetMultimap.Transient xz = xy.asTransient();
+
+ for (IValue x : xy.keySet()) {
+ final Set.Immutable ys = xy.get(x);
+ // TODO: simplify expression with nullable data
+ final Set.Immutable zs = ys.stream()
+ .flatMap(y -> Optional.ofNullable(yz.get(y)).orElseGet(Set.Immutable::of).stream())
+ .collect(CapsuleCollectors.toSet());
+
+ if (zs == null) {
+ xz.__remove(x);
+ } else {
+ // xz.__put(x, zs); // TODO: requires node batch update support
+
+ xz.__remove(x);
+ zs.forEach(z -> xz.__insert(x, z));
+ }
+ }
+
+ final SetMultimap.Immutable data = xz.freeze();
- return content.equals(that.content);
- }
-
- if (other instanceof ISet) {
- return defaultEquals(other);
- }
-
- return false;
- }
-
- @Override
- public ISet union(ISet other) {
- if (other == this) {
- return this;
- }
- if (other == null) {
- return this;
- }
-
- if (other instanceof PersistentHashIndexedBinaryRelation) {
- PersistentHashIndexedBinaryRelation that = (PersistentHashIndexedBinaryRelation) other;
-
- final SetMultimap.Immutable one;
- final SetMultimap.Immutable two;
- AbstractTypeBag keyTypeBagNew;
- AbstractTypeBag valTypeBagNew;
- final ISet def;
-
- if (that.size() >= this.size()) {
- def = that;
- one = that.content;
- keyTypeBagNew = that.keyTypeBag;
- valTypeBagNew = that.valTypeBag;
- two = this.content;
- } else {
- def = this;
- one = this.content;
- keyTypeBagNew = this.keyTypeBag;
- valTypeBagNew = this.valTypeBag;
- two = that.content;
- }
-
- final SetMultimap.Transient tmp = one.asTransient();
- boolean modified = false;
-
- for (Map.Entry entry : two.entrySet()) {
- final IValue key = entry.getKey();
- final IValue val = entry.getValue();
- if (tmp.__insert(key, val)) {
- modified = true;
- keyTypeBagNew = keyTypeBagNew.increase(key.getType());
- valTypeBagNew = valTypeBagNew.increase(val.getType());
- }
- }
-
- if (modified) {
- return PersistentSetFactory.from(keyTypeBagNew, valTypeBagNew, tmp.freeze());
- }
- return def;
- } else {
- return ISet.super.union(other);
- }
- }
-
- @Override
- public ISet intersect(ISet other) {
- if (other == this) {
- return this;
- }
- if (other == null) {
- return EmptySet.EMPTY_SET;
- }
-
- if (other instanceof PersistentHashIndexedBinaryRelation) {
- PersistentHashIndexedBinaryRelation that = (PersistentHashIndexedBinaryRelation) other;
-
- final SetMultimap.Immutable one;
- final SetMultimap.Immutable two;
- AbstractTypeBag keyTypeBagNew;
- AbstractTypeBag valTypeBagNew;
- final ISet def;
-
- if (that.size() >= this.size()) {
- def = this;
- one = this.content;
- keyTypeBagNew = this.keyTypeBag;
- valTypeBagNew = this.valTypeBag;
- two = that.content;
- } else {
- def = that;
- one = that.content;
- keyTypeBagNew = that.keyTypeBag;
- valTypeBagNew = that.valTypeBag;
- two = this.content;
- }
-
- final SetMultimap.Transient tmp = one.asTransient();
- boolean modified = false;
-
- for (Iterator> it = tmp.entryIterator(); it.hasNext(); ) {
- final Map.Entry tuple = it.next();
- final IValue key = tuple.getKey();
- final IValue val = tuple.getValue();
-
- if (!two.containsEntry(key, val)) {
- it.remove();
- modified = true;
- keyTypeBagNew = keyTypeBagNew.decrease(key.getType());
- valTypeBagNew = valTypeBagNew.decrease(val.getType());
- }
- }
-
- if (modified) {
- return PersistentSetFactory.from(keyTypeBagNew, valTypeBagNew, tmp.freeze());
- }
- return def;
- } else {
- return ISet.super.intersect(other);
- }
- }
-
- @Override
- public ISet subtract(ISet other) {
- if (other == this) {
- return EmptySet.EMPTY_SET;
- }
- if (other == null) {
- return this;
- }
-
- if (other instanceof PersistentHashIndexedBinaryRelation) {
- PersistentHashIndexedBinaryRelation that = (PersistentHashIndexedBinaryRelation) other;
-
- final SetMultimap.Immutable one;
- final SetMultimap.Immutable two;
- AbstractTypeBag keyTypeBagNew;
- AbstractTypeBag valTypeBagNew;
- final ISet def;
-
- def = this;
- one = this.content;
- keyTypeBagNew = this.keyTypeBag;
- valTypeBagNew = this.valTypeBag;
- two = that.content;
-
- final SetMultimap.Transient tmp = one.asTransient();
- boolean modified = false;
-
- for (Map.Entry tuple : two.entrySet()) {
- final IValue key = tuple.getKey();
- final IValue val = tuple.getValue();
-
- if (tmp.__remove(key, val)) {
- modified = true;
- keyTypeBagNew = keyTypeBagNew.decrease(key.getType());
- valTypeBagNew = valTypeBagNew.decrease(val.getType());
- }
- }
-
- if (modified) {
- return PersistentSetFactory.from(keyTypeBagNew, valTypeBagNew, tmp.freeze());
- }
- return def;
- } else {
- return ISet.super.subtract(other);
- }
- }
-
- @Override
- public ISet compose(IRelation otherSetRelation) {
- if (otherSetRelation.getClass() != this.getClass()) {
- return IRelation.super.compose(otherSetRelation);
- }
-
- // Here we can optimize the compose operation because we have already an index in memory
- // for both relations
-
- final PersistentHashIndexedBinaryRelation thatSet =
- (PersistentHashIndexedBinaryRelation) otherSetRelation.asContainer();
-
- final SetMultimap.Immutable xy = content;
- final SetMultimap.Immutable yz = thatSet.content;
-
- /**
- * The code below is still sub-optimal because it operates on the logical (rather than the structural) level.
- *
- * TODO: nodes should get proper support for stream processing such that the following template can be used:
- *
- * // @formatter:off
- * final Stream> localStream = null;
- * final Node updatedNode = localStream
- * .filter((x, y) -> yz.containsKey(y))
- * .mapValues(y -> yz.get(y))
- * .collect(toNode());
- * // @formatter:on
- */
- final SetMultimap.Transient xz = xy.asTransient();
-
- for (IValue x : xy.keySet()) {
- final Set.Immutable ys = xy.get(x);
- // TODO: simplify expression with nullable data
- final Set.Immutable zs = ys.stream()
- .flatMap(y -> Optional.ofNullable(yz.get(y)).orElseGet(Set.Immutable::of).stream())
- .collect(CapsuleCollectors.toSet());
-
- if (zs == null) {
- xz.__remove(x);
- } else {
- // xz.__put(x, zs); // TODO: requires node batch update support
-
- xz.__remove(x);
- zs.forEach(z -> xz.__insert(x, z));
- }
- }
-
- final SetMultimap.Immutable data = xz.freeze();
-
-
- final AbstractTypeBag keyTypeBag = calcTypeBag(data, Map.Entry::getKey);
- final AbstractTypeBag valTypeBag = calcTypeBag(data, Map.Entry::getValue);
-
- return PersistentSetFactory.from(keyTypeBag, valTypeBag, data);
- }
-
- @Override
- public int arity() {
- return 2;
- }
-
- @Override
- public ISet project(int... fieldIndexes) {
- if (Arrays.equals(fieldIndexes, ArrayUtilsInt.arrayOfInt(0))) {
- return domain();
- }
-
- if (Arrays.equals(fieldIndexes, ArrayUtilsInt.arrayOfInt(1))) {
- return range();
- }
-
- if (Arrays.equals(fieldIndexes, ArrayUtilsInt.arrayOfInt(0, 1))) {
- return this;
- }
-
- // TODO: replace by `inverse` API of subsequent capsule release
- if (Arrays.equals(fieldIndexes, ArrayUtilsInt.arrayOfInt(1, 0))) {
- final SetMultimap.Transient builder =
- PersistentTrieSetMultimap.transientOf(Object::equals);
-
- content.entryIterator().forEachRemaining(
- tuple -> builder.__insert(tuple.getValue(), tuple.getKey()));
-
-
- return PersistentSetFactory.from(valTypeBag, keyTypeBag, builder.freeze());
- }
-
- throw new IllegalStateException("Binary relation patterns exhausted.");
- }
-
- /**
- * Flattening Set[Tuple[Tuple[K, V]], _] to Multimap[K, V].
- *
- * @return canonical set of keys
- */
- @Override
- public ISet domain() {
- final Type fieldType0 = this.getType().getFieldType(0);
-
- if (isTupleOfArityTwo.test(fieldType0)) {
- // TODO: use lazy keySet view instead of materialized data structure
- return this.content.keySet().stream().map(asInstanceOf(ITuple.class))
- .collect(ValueCollectors.toSetMultimap(tuple -> tuple.get(0), tuple -> tuple.get(1)));
- }
-
- /**
- * NOTE: the following call to {@code stream().collect(toSet())} is suboptimal because
- * {@code thisSet.content.keySet()} already produces the result (modulo dynamic types). The
- * usage of streams solely hides the calculation of precise dynamic type of the set.
- */
- return this.content.keySet().stream().collect(ValueCollectors.toSet());
- }
-
- /**
- * Flattening Set[Tuple[_, Tuple[K, V]]] to Multimap[K, V].
- *
- * @return canonical set of values
- */
- @Override
- public ISet range() {
- return content.values().stream().collect(ValueCollectors.toSet());
- }
-
- @Override
- public ISet index(IValue key) {
- Immutable values = content.get(key);
- if (values == null) {
- return EmptySet.EMPTY_SET;
- }
-
- return PersistentSetFactory.from(values);
- }
-
- @Override
- public ISet asContainer() {
- return this;
- }
-
- @Override
- public Type getElementType() {
- return ISet.super.getElementType();
- }
-
- @Override
- public ISet empty() {
- return ISet.super.empty();
- }
-
- private static AbstractTypeBag calcTypeBag(SetMultimap contents, Function, IValue> mapper) {
- return contents.entrySet().stream().map(mapper)
- .map(IValue::getType).collect(AbstractTypeBag.toTypeBag());
- }
-
- @Override
- public ISet closure() {
- Type tupleType = getElementType();
- assert tupleType.getArity() == 2;
- Type keyType = tupleType.getFieldType(0);
- Type valueType = tupleType.getFieldType(1);
-
- if (!keyType.comparable(valueType)) {
- // if someone tries, then we have a very quick answer
- return this;
- }
-
- var result = computeClosure(content);
-
- final AbstractTypeBag keyTypeBag;
- final AbstractTypeBag valTypeBag;
-
- if (keyType == valueType && isConcreteValueType(keyType)) {
- // this means no other types can be introduced other than the originals,
- // so iteration is no longer necessary to construct the new type bag
- keyTypeBag = AbstractTypeBag.of(keyType, result.size());
- valTypeBag = keyTypeBag;
- }
- else {
- keyTypeBag = calcTypeBag(result, Map.Entry::getKey);
- valTypeBag = calcTypeBag(result, Map.Entry::getValue);
- }
-
- return PersistentSetFactory.from(keyTypeBag, valTypeBag, result.freeze());
- }
-
- private boolean isConcreteValueType(Type keyType) {
- return keyType.isSourceLocation()
- || keyType.isInteger()
- || keyType.isRational()
- || keyType.isReal()
- || keyType.isDateTime()
- || (keyType.isAbstractData() && !keyType.isParameterized())
- || keyType.isString()
- || keyType.isBool()
- ;
- }
-
- @Override
- public ISet closureStar() {
- Type tupleType = getElementType();
- assert tupleType.getArity() == 2;
- Type keyType = tupleType.getFieldType(0);
- Type valueType = tupleType.getFieldType(1);
-
- var result = computeClosure(content);
-
- for (var carrier: content.entrySet()) {
- result.__insert(carrier.getKey(), carrier.getKey());
- result.__insert(carrier.getValue(), carrier.getValue());
- }
-
- final AbstractTypeBag keyTypeBag;
- final AbstractTypeBag valTypeBag;
-
- if (keyType == valueType && isConcreteValueType(keyType)) {
- // this means no other types can be introduced other than the originals,
- // so iteration is no longer necessary to construct the new type bag
- keyTypeBag = AbstractTypeBag.of(keyType, result.size());
- valTypeBag = keyTypeBag;
- }
- else {
- keyTypeBag = calcTypeBag(result, Map.Entry::getKey);
- valTypeBag = calcTypeBag(result, Map.Entry::getValue);
- }
-
- return PersistentSetFactory.from(keyTypeBag, valTypeBag, result.freeze());
- }
-
- private static SetMultimap.Transient computeClosure(final SetMultimap.Immutable content) {
- return content.size() > 256
- ? computeClosureDepthFirst(content)
- : computeClosureBreadthFirst(content)
- ;
- }
-
- @SuppressWarnings("unchecked")
- private static SetMultimap.Transient computeClosureDepthFirst(final SetMultimap.Immutable content) {
- final SetMultimap.Transient result = content.asTransient();
- var todo = new ArrayDeque();
- var done = new HashSet(); // keep track of LHS we already did, so we don't have to go into the depth of them anymore
- var mainIt = content.nativeEntryIterator();
- while (mainIt.hasNext()) {
- final var focus = mainIt.next();
- final IValue lhs = focus.getKey();
- final Object values =focus.getValue();
-
- assert todo.isEmpty();
- if (values instanceof IValue) {
- todo.push((IValue)values);
- }
- else if (values instanceof Set) {
- todo.addAll((Set)values);
- }
- else {
- throw new IllegalArgumentException("Unexpected map entry");
- }
- // to avoid recalculating `lhs` next time we see it, we mark it as done.
- // so that the next time we come across if on the rhs, we know the range is
- // already the transitive closure.
- // We add it before we've done it, just to avoid scheduling
- // when it occurs during the depth scan for lhs.
- done.add(lhs);
- IValue rhs;
- while ((rhs = todo.poll()) != null) {
- if (lhs == rhs) {
- // no need to handle
- continue;
- }
- boolean rhsDone = done.contains(rhs);
- for (IValue composed : result.get(rhs)) {
- if (result.__insert(lhs, composed) && !rhsDone) {
- todo.push(composed);
- }
- }
- }
- }
- return result;
- }
-
- @SuppressWarnings("unchecked")
- private static SetMultimap.Transient computeClosureBreadthFirst(final SetMultimap.Immutable content) {
- /*
- * we want to compute the closure of R, which in essence is a composition on itself.
- * until nothing changes:
- *
- * solve(R) {
- * R = R o R;
- * }
- *
- * The algorithm below realizes the following things:
- *
- * - Instead of recomputing the compose for the whole of R, we only have to
- * compose for the newly added edges (called todo in the algorithm).
- * - Since the LHS of `R o R` will be using the range of R as a lookup in R
- * we store the todo in inverse.
- *
- * In essence the algorithm becomes:
- *
- * result = R;
- * todo = invert(R);
- *
- * while (todo != {}) {
- * composed = fastCompose(todo, R);
- * newEdges = composed - result;
- * todo = invert(newEdges);
- * result += newEdges;
- * }
- *
- * fastCompose(todo, R) = { l * R[r] | <- todo};
- *
+ final AbstractTypeBag keyTypeBag = calcTypeBag(data, Map.Entry::getKey);
+ final AbstractTypeBag valTypeBag = calcTypeBag(data, Map.Entry::getValue);
+
+ return PersistentSetFactory.from(keyTypeBag, valTypeBag, data);
+ }
+
+ @Override
+ public int arity() {
+ return 2;
+ }
+
+ @Override
+ public ISet project(int... fieldIndexes) {
+ if (Arrays.equals(fieldIndexes, ArrayUtilsInt.arrayOfInt(0))) {
+ return domain();
+ }
+
+ if (Arrays.equals(fieldIndexes, ArrayUtilsInt.arrayOfInt(1))) {
+ return range();
+ }
+
+ if (Arrays.equals(fieldIndexes, ArrayUtilsInt.arrayOfInt(0, 1))) {
+ return this;
+ }
+
+ // TODO: replace by `inverse` API of subsequent capsule release
+ if (Arrays.equals(fieldIndexes, ArrayUtilsInt.arrayOfInt(1, 0))) {
+ final SetMultimap.Transient builder =
+ PersistentTrieSetMultimap.transientOf(Object::equals);
+
+ content.entryIterator().forEachRemaining(
+ tuple -> builder.__insert(tuple.getValue(), tuple.getKey()));
+
+
+ return PersistentSetFactory.from(valTypeBag, keyTypeBag, builder.freeze());
+ }
+
+ throw new IllegalStateException("Binary relation patterns exhausted.");
+ }
+
+ /**
+ * Flattening Set[Tuple[Tuple[K, V]], _] to Multimap[K, V].
+ *
+ * @return canonical set of keys
*/
- final SetMultimap.Transient result = content.asTransient();
-
- SetMultimap todo = content.inverseMap();
- while (!todo.isEmpty()) {
- final SetMultimap.Transient nextTodo = PersistentTrieSetMultimap.transientOf(Object::equals);
-
- var todoIt = todo.nativeEntryIterator();
- while (todoIt.hasNext()) {
- var next = todoIt.next();
- IValue lhs = next.getKey();
- Immutable values = content.get(lhs);
- if (!values.isEmpty()) {
- Object keys = next.getValue();
- if (keys instanceof IValue) {
- singleCompose(result, nextTodo, values, (IValue)keys);
- }
- else if (keys instanceof Set) {
- for (IValue key : (Set)keys) {
- singleCompose(result, nextTodo, values, key);
+ @Override
+ public ISet domain() {
+ final Type fieldType0 = this.getType().getFieldType(0);
+
+ if (isTupleOfArityTwo.test(fieldType0)) {
+ // TODO: use lazy keySet view instead of materialized data structure
+ return this.content.keySet().stream().map(asInstanceOf(ITuple.class))
+ .collect(ValueCollectors.toSetMultimap(tuple -> tuple.get(0), tuple -> tuple.get(1)));
+ }
+
+ /**
+ * NOTE: the following call to {@code stream().collect(toSet())} is suboptimal because
+ * {@code thisSet.content.keySet()} already produces the result (modulo dynamic types). The
+ * usage of streams solely hides the calculation of precise dynamic type of the set.
+ */
+ return this.content.keySet().stream().collect(ValueCollectors.toSet());
+ }
+
+ /**
+ * Flattening Set[Tuple[_, Tuple[K, V]]] to Multimap[K, V].
+ *
+ * @return canonical set of values
+ */
+ @Override
+ public ISet range() {
+ return content.values().stream().collect(ValueCollectors.toSet());
+ }
+
+ @Override
+ public ISet index(IValue key) {
+ Immutable values = content.get(key);
+ if (values == null) {
+ return EmptySet.EMPTY_SET;
+ }
+
+ return PersistentSetFactory.from(values);
+ }
+
+ @Override
+ public ISet asContainer() {
+ return this;
+ }
+
+ @Override
+ public Type getElementType() {
+ return ISet.super.getElementType();
+ }
+
+ @Override
+ public ISet empty() {
+ return ISet.super.empty();
+ }
+
+ private static AbstractTypeBag calcTypeBag(SetMultimap contents, Function, IValue> mapper) {
+ return contents.entrySet().stream().map(mapper)
+ .map(IValue::getType).collect(AbstractTypeBag.toTypeBag());
+ }
+
+ @Override
+ public ISet closure() {
+ Type tupleType = getElementType();
+ assert tupleType.getArity() == 2;
+ Type keyType = tupleType.getFieldType(0);
+ Type valueType = tupleType.getFieldType(1);
+
+ if (!keyType.comparable(valueType)) {
+ // if someone tries, then we have a very quick answer
+ return this;
+ }
+
+ var result = computeClosure(content);
+
+ final AbstractTypeBag keyTypeBag;
+ final AbstractTypeBag valTypeBag;
+
+ if (keyType == valueType && isConcreteValueType(keyType)) {
+ // this means no other types can be introduced other than the originals,
+ // so iteration is no longer necessary to construct the new type bag
+ keyTypeBag = AbstractTypeBag.of(keyType, result.size());
+ valTypeBag = keyTypeBag;
+ }
+ else {
+ keyTypeBag = calcTypeBag(result, Map.Entry::getKey);
+ valTypeBag = calcTypeBag(result, Map.Entry::getValue);
+ }
+
+ return PersistentSetFactory.from(keyTypeBag, valTypeBag, result.freeze());
+ }
+
+ private boolean isConcreteValueType(Type keyType) {
+ return keyType.isSourceLocation()
+ || keyType.isInteger()
+ || keyType.isRational()
+ || keyType.isReal()
+ || keyType.isDateTime()
+ || (keyType.isAbstractData() && !keyType.isParameterized())
+ || keyType.isString()
+ || keyType.isBool()
+ ;
+ }
+
+ @Override
+ public ISet closureStar() {
+ Type tupleType = getElementType();
+ assert tupleType.getArity() == 2;
+ Type keyType = tupleType.getFieldType(0);
+ Type valueType = tupleType.getFieldType(1);
+
+ var result = computeClosure(content);
+
+ for (var carrier: content.entrySet()) {
+ result.__insert(carrier.getKey(), carrier.getKey());
+ result.__insert(carrier.getValue(), carrier.getValue());
+ }
+
+ final AbstractTypeBag keyTypeBag;
+ final AbstractTypeBag valTypeBag;
+
+ if (keyType == valueType && isConcreteValueType(keyType)) {
+ // this means no other types can be introduced other than the originals,
+ // so iteration is no longer necessary to construct the new type bag
+ keyTypeBag = AbstractTypeBag.of(keyType, result.size());
+ valTypeBag = keyTypeBag;
+ }
+ else {
+ keyTypeBag = calcTypeBag(result, Map.Entry::getKey);
+ valTypeBag = calcTypeBag(result, Map.Entry::getValue);
+ }
+
+ return PersistentSetFactory.from(keyTypeBag, valTypeBag, result.freeze());
+ }
+
+ private static SetMultimap.Transient computeClosure(final SetMultimap.Immutable content) {
+ return content.size() > 256
+ ? computeClosureDepthFirst(content)
+ : computeClosureBreadthFirst(content)
+ ;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static SetMultimap.Transient computeClosureDepthFirst(final SetMultimap.Immutable content) {
+ final SetMultimap.Transient result = content.asTransient();
+ var todo = new ArrayDeque();
+ var done = new HashSet(); // keep track of LHS we already did, so we don't have to go into the depth of them anymore
+ var mainIt = content.nativeEntryIterator();
+ while (mainIt.hasNext()) {
+ final var focus = mainIt.next();
+ final IValue lhs = focus.getKey();
+ final Object values =focus.getValue();
+
+ assert todo.isEmpty();
+ if (values instanceof IValue) {
+ todo.push((IValue)values);
+ }
+ else if (values instanceof Set) {
+ todo.addAll((Set)values);
+ }
+ else {
+ throw new IllegalArgumentException("Unexpected map entry");
}
- }
- else {
- throw new IllegalArgumentException("Unexpected map entry");
- }
+ // to avoid recalculating `lhs` next time we see it, we mark it as done.
+ // so that the next time we come across if on the rhs, we know the range is
+ // already the transitive closure.
+ // We add it before we've done it, just to avoid scheduling
+ // when it occurs during the depth scan for lhs.
+ done.add(lhs);
+ IValue rhs;
+ while ((rhs = todo.poll()) != null) {
+ if (lhs == rhs) {
+ // no need to handle
+ continue;
+ }
+ boolean rhsDone = done.contains(rhs);
+ for (IValue composed : result.get(rhs)) {
+ if (result.__insert(lhs, composed) && !rhsDone) {
+ todo.push(composed);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static SetMultimap.Transient computeClosureBreadthFirst(final SetMultimap.Immutable content) {
+ /*
+ * we want to compute the closure of R, which in essence is a composition on itself.
+ * until nothing changes:
+ *
+ * solve(R) {
+ * R = R o R;
+ * }
+ *
+ * The algorithm below realizes the following things:
+ *
+ * - Instead of recomputing the compose for the whole of R, we only have to
+ * compose for the newly added edges (called todo in the algorithm).
+ * - Since the LHS of `R o R` will be using the range of R as a lookup in R
+ * we store the todo in inverse.
+ *
+ * In essence the algorithm becomes:
+ *
+ * result = R;
+ * todo = invert(R);
+ *
+ * while (todo != {}) {
+ * composed = fastCompose(todo, R);
+ * newEdges = composed - result;
+ * todo = invert(newEdges);
+ * result += newEdges;
+ * }
+ *
+ * fastCompose(todo, R) = { l * R[r] | <- todo};
+ *
+ */
+ final SetMultimap.Transient result = content.asTransient();
+
+ SetMultimap todo = content.inverseMap();
+ while (!todo.isEmpty()) {
+ final SetMultimap.Transient nextTodo = PersistentTrieSetMultimap.transientOf(Object::equals);
+
+ var todoIt = todo.nativeEntryIterator();
+ while (todoIt.hasNext()) {
+ var next = todoIt.next();
+ IValue lhs = next.getKey();
+ Immutable values = content.get(lhs);
+ if (!values.isEmpty()) {
+ Object keys = next.getValue();
+ if (keys instanceof IValue) {
+ singleCompose(result, nextTodo, values, (IValue)keys);
+ }
+ else if (keys instanceof Set) {
+ for (IValue key : (Set)keys) {
+ singleCompose(result, nextTodo, values, key);
+ }
+ }
+ else {
+ throw new IllegalArgumentException("Unexpected map entry");
+ }
+ }
+ }
+
+ todo = nextTodo;
}
- }
- todo = nextTodo;
+ return result;
}
-
- return result;
- }
- private static void singleCompose(final SetMultimap.Transient result,
- final SetMultimap.Transient nextTodo, Immutable values, IValue key) {
- for (IValue val: values) {
- if (result.__insert(key, val)) {
- nextTodo.__insert(val, key);
- }
+ private static void singleCompose(final SetMultimap.Transient result,
+ final SetMultimap.Transient nextTodo, Immutable values, IValue key) {
+ for (IValue val: values) {
+ if (result.__insert(key, val)) {
+ nextTodo.__insert(val, key);
+ }
+ }
}
- }
}
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/PersistentHashMap.java b/src/main/java/io/usethesource/vallang/impl/persistent/PersistentHashMap.java
index 03ddc37bd..3a2f2f815 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/PersistentHashMap.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/PersistentHashMap.java
@@ -31,200 +31,200 @@
public final class PersistentHashMap implements IMap {
- private @MonotonicNonNull Type cachedMapType;
- private final AbstractTypeBag keyTypeBag;
- private final AbstractTypeBag valTypeBag;
- private final Map.Immutable<@NonNull IValue, @NonNull IValue> content;
-
- /*
- * Passing an pre-calulated map type is only allowed from inside this class.
- */
- protected PersistentHashMap(AbstractTypeBag keyTypeBag, AbstractTypeBag valTypeBag, Map.Immutable<@NonNull IValue, @NonNull IValue> content) {
- this.keyTypeBag = keyTypeBag;
- this.valTypeBag = valTypeBag;
- this.content = content;
- assert content.size() == keyTypeBag.sum();
- }
-
- @Override
- public String toString() {
- return defaultToString();
- }
-
- @Override
- public Type getType() {
- if (cachedMapType == null) {
- cachedMapType = TF.mapType(keyTypeBag.lub(), valTypeBag.lub());
- }
-
- return cachedMapType;
- }
-
- @Override
- public boolean isEmpty() {
- return content.isEmpty();
- }
-
- @Override
- public IMap put(IValue key, IValue value) {
- final Map.Immutable contentNew =
- content.__put(key, value);
-
- if (content == contentNew)
- return this;
-
- final AbstractTypeBag keyBagNew;
- final AbstractTypeBag valBagNew;
-
- if (content.size() == contentNew.size()) {
- // value replaced
- final IValue replaced = content.get(key);
- keyBagNew = keyTypeBag;
- valBagNew = valTypeBag.decrease(replaced.getType()).increase(value.getType());
- } else {
- // pair added
- keyBagNew = keyTypeBag.increase(key.getType());
- valBagNew = valTypeBag.increase(value.getType());
- }
-
- return new PersistentHashMap(keyBagNew, valBagNew, contentNew);
- }
-
- @Override
- public IMap removeKey(IValue key) {
- final Map.Immutable newContent = content.__remove(key);
-
- if (newContent == content) {
- return this;
- }
-
- // this only happens if something has actually been removed:
- final IValue removedValue = content.get(key);
- final AbstractTypeBag newKeyBag = keyTypeBag.decrease(key.getType());
- final AbstractTypeBag newValBag = valTypeBag.decrease(removedValue.getType());
-
- assert !newContent.isEmpty() || (newKeyBag.lub().isBottom() && newValBag.lub().isBottom());
- return new PersistentHashMap(newKeyBag, newValBag, newContent);
- }
-
- @Override
- public int size() {
- return content.size();
- }
-
- @Override
- @EnsuresNonNullIf(expression="get(#1)", result=true)
+ private @MonotonicNonNull Type cachedMapType;
+ private final AbstractTypeBag keyTypeBag;
+ private final AbstractTypeBag valTypeBag;
+ private final Map.Immutable<@NonNull IValue, @NonNull IValue> content;
+
+ /*
+ * Passing an pre-calulated map type is only allowed from inside this class.
+ */
+ protected PersistentHashMap(AbstractTypeBag keyTypeBag, AbstractTypeBag valTypeBag, Map.Immutable<@NonNull IValue, @NonNull IValue> content) {
+ this.keyTypeBag = keyTypeBag;
+ this.valTypeBag = valTypeBag;
+ this.content = content;
+ assert content.size() == keyTypeBag.sum();
+ }
+
+ @Override
+ public String toString() {
+ return defaultToString();
+ }
+
+ @Override
+ public Type getType() {
+ if (cachedMapType == null) {
+ cachedMapType = TF.mapType(keyTypeBag.lub(), valTypeBag.lub());
+ }
+
+ return cachedMapType;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return content.isEmpty();
+ }
+
+ @Override
+ public IMap put(IValue key, IValue value) {
+ final Map.Immutable contentNew =
+ content.__put(key, value);
+
+ if (content == contentNew)
+ return this;
+
+ final AbstractTypeBag keyBagNew;
+ final AbstractTypeBag valBagNew;
+
+ if (content.size() == contentNew.size()) {
+ // value replaced
+ final IValue replaced = content.get(key);
+ keyBagNew = keyTypeBag;
+ valBagNew = valTypeBag.decrease(replaced.getType()).increase(value.getType());
+ } else {
+ // pair added
+ keyBagNew = keyTypeBag.increase(key.getType());
+ valBagNew = valTypeBag.increase(value.getType());
+ }
+
+ return new PersistentHashMap(keyBagNew, valBagNew, contentNew);
+ }
+
+ @Override
+ public IMap removeKey(IValue key) {
+ final Map.Immutable newContent = content.__remove(key);
+
+ if (newContent == content) {
+ return this;
+ }
+
+ // this only happens if something has actually been removed:
+ final IValue removedValue = content.get(key);
+ final AbstractTypeBag newKeyBag = keyTypeBag.decrease(key.getType());
+ final AbstractTypeBag newValBag = valTypeBag.decrease(removedValue.getType());
+
+ assert !newContent.isEmpty() || (newKeyBag.lub().isBottom() && newValBag.lub().isBottom());
+ return new PersistentHashMap(newKeyBag, newValBag, newContent);
+ }
+
+ @Override
+ public int size() {
+ return content.size();
+ }
+
+ @Override
+ @EnsuresNonNullIf(expression="get(#1)", result=true)
@SuppressWarnings({"contracts.conditional.postcondition"}) // that's impossible to prove for the Checker Framework
- public boolean containsKey(IValue key) {
- return content.containsKey(key);
- }
-
- @Override
- public boolean containsValue(IValue value) {
- return content.containsValue(value);
- }
-
- @Override
- public IValue get(IValue key) {
- return content.get(key);
- }
-
- @Override
- public int hashCode() {
- return content.hashCode();
- }
-
- @Override
- public boolean equals(@Nullable Object other) {
- if (other == this) {
- return true;
- }
-
- if (other == null) {
- return false;
- }
-
-
-
- if (other instanceof PersistentHashMap) {
- PersistentHashMap that = (PersistentHashMap) other;
-
- if (this.getType() != that.getType())
- return false;
-
- if (this.size() != that.size())
- return false;
-
- return content.equals(that.content);
- }
-
- if (other instanceof IMap) {
- return defaultEquals(other);
- }
-
- return false;
- }
-
- @Override
- public Iterator iterator() {
- return content.keyIterator();
- }
-
- @Override
- public Iterator valueIterator() {
- return content.valueIterator();
- }
-
- @Override
- public Iterator> entryIterator() {
- return content.entryIterator();
- }
-
- @Override
- public IMap join(IMap other) {
- if (other instanceof PersistentHashMap) {
- PersistentHashMap that = (PersistentHashMap) other;
-
- final Map.Transient transientContent = content.asTransient();
-
- boolean isModified = false;
- int previousSize = size();
-
- AbstractTypeBag keyBagNew = keyTypeBag;
- AbstractTypeBag valBagNew = valTypeBag;
-
- for (Iterator> it = that.entryIterator(); it.hasNext();) {
- Entry tuple = it.next();
- IValue key = tuple.getKey();
- IValue value = tuple.getValue();
-
- final IValue replaced = transientContent.__put(key, value);
-
- if (replaced != null) {
- // value replaced
- valBagNew = valBagNew.decrease(replaced.getType()).increase(value.getType());
-
- isModified = true;
- } else if (previousSize != transientContent.size()) {
- // pair added
- keyBagNew = keyBagNew.increase(key.getType());
- valBagNew = valBagNew.increase(value.getType());
-
- isModified = true;
- previousSize++;
- }
- }
-
- if (isModified) {
- return new PersistentHashMap(keyBagNew, valBagNew, transientContent.freeze());
- } else {
- return this;
- }
- } else {
- return IMap.super.join(other);
- }
- }
-
+ public boolean containsKey(IValue key) {
+ return content.containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(IValue value) {
+ return content.containsValue(value);
+ }
+
+ @Override
+ public IValue get(IValue key) {
+ return content.get(key);
+ }
+
+ @Override
+ public int hashCode() {
+ return content.hashCode();
+ }
+
+ @Override
+ public boolean equals(@Nullable Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (other == null) {
+ return false;
+ }
+
+
+
+ if (other instanceof PersistentHashMap) {
+ PersistentHashMap that = (PersistentHashMap) other;
+
+ if (this.getType() != that.getType())
+ return false;
+
+ if (this.size() != that.size())
+ return false;
+
+ return content.equals(that.content);
+ }
+
+ if (other instanceof IMap) {
+ return defaultEquals(other);
+ }
+
+ return false;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return content.keyIterator();
+ }
+
+ @Override
+ public Iterator valueIterator() {
+ return content.valueIterator();
+ }
+
+ @Override
+ public Iterator> entryIterator() {
+ return content.entryIterator();
+ }
+
+ @Override
+ public IMap join(IMap other) {
+ if (other instanceof PersistentHashMap) {
+ PersistentHashMap that = (PersistentHashMap) other;
+
+ final Map.Transient transientContent = content.asTransient();
+
+ boolean isModified = false;
+ int previousSize = size();
+
+ AbstractTypeBag keyBagNew = keyTypeBag;
+ AbstractTypeBag valBagNew = valTypeBag;
+
+ for (Iterator> it = that.entryIterator(); it.hasNext();) {
+ Entry tuple = it.next();
+ IValue key = tuple.getKey();
+ IValue value = tuple.getValue();
+
+ final IValue replaced = transientContent.__put(key, value);
+
+ if (replaced != null) {
+ // value replaced
+ valBagNew = valBagNew.decrease(replaced.getType()).increase(value.getType());
+
+ isModified = true;
+ } else if (previousSize != transientContent.size()) {
+ // pair added
+ keyBagNew = keyBagNew.increase(key.getType());
+ valBagNew = valBagNew.increase(value.getType());
+
+ isModified = true;
+ previousSize++;
+ }
+ }
+
+ if (isModified) {
+ return new PersistentHashMap(keyBagNew, valBagNew, transientContent.freeze());
+ } else {
+ return this;
+ }
+ } else {
+ return IMap.super.join(other);
+ }
+ }
+
@Override
public Type getElementType() {
return keyTypeBag.lub();
@@ -244,7 +244,7 @@ public IMapWriter writer() {
public Stream stream() {
return StreamSupport.stream(spliterator(), false).map(key -> Tuple.newTuple(key, get(key)));
}
-
+
@Override
public IRelation asRelation() {
throw new UnsupportedOperationException();
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/PersistentHashSet.java b/src/main/java/io/usethesource/vallang/impl/persistent/PersistentHashSet.java
index feff8c3e6..ba1422557 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/PersistentHashSet.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/PersistentHashSet.java
@@ -25,273 +25,273 @@
import io.usethesource.vallang.util.AbstractTypeBag;
public final class PersistentHashSet implements ISet {
- private @Nullable Type cachedSetType = null;
- private final AbstractTypeBag elementTypeBag;
- private final Set.Immutable content;
-
- /**
- * Construction of persistent hash-set.
- *
- * DO NOT CALL OUTSIDE OF {@link PersistentSetFactory}.
- *
- * @param elementTypeBag precise dynamic type
- * @param content immutable set
- */
- PersistentHashSet(AbstractTypeBag elementTypeBag, Set.Immutable content) {
- this.elementTypeBag = Objects.requireNonNull(elementTypeBag);
- this.content = Objects.requireNonNull(content);
-
- assert checkDynamicType(elementTypeBag, content);
- assert !(elementTypeBag.lub() == TF.voidType() || content.isEmpty());
- }
-
- @Override
- public String toString() {
- return defaultToString();
- }
-
- private static final boolean checkDynamicType(final AbstractTypeBag elementTypeBag,
- final Set.Immutable content) {
-
- final AbstractTypeBag expectedElementTypeBag =
- content.stream().map(IValue::getType).collect(AbstractTypeBag.toTypeBag());
-
- boolean expectedTypesEqual = expectedElementTypeBag.equals(elementTypeBag);
-
- return expectedTypesEqual;
- }
-
- @Override
- public ISetWriter writer() {
- return ValueFactory.getInstance().setWriter();
- }
-
- @Override
- public Type getType() {
- if (cachedSetType == null) {
- cachedSetType = TF.setType(elementTypeBag.lub());
+ private @Nullable Type cachedSetType = null;
+ private final AbstractTypeBag elementTypeBag;
+ private final Set.Immutable content;
+
+ /**
+ * Construction of persistent hash-set.
+ *
+ * DO NOT CALL OUTSIDE OF {@link PersistentSetFactory}.
+ *
+ * @param elementTypeBag precise dynamic type
+ * @param content immutable set
+ */
+ PersistentHashSet(AbstractTypeBag elementTypeBag, Set.Immutable content) {
+ this.elementTypeBag = Objects.requireNonNull(elementTypeBag);
+ this.content = Objects.requireNonNull(content);
+
+ assert checkDynamicType(elementTypeBag, content);
+ assert !(elementTypeBag.lub() == TF.voidType() || content.isEmpty());
}
-
- return cachedSetType;
- }
-
- @Override
- public boolean isEmpty() {
- return content.isEmpty();
- }
-
- @Override
- public ISet insert(IValue value) {
- final Set.Immutable contentNew =
- content.__insert(value);
-
- if (content == contentNew)
- return this;
-
- final AbstractTypeBag bagNew = elementTypeBag.increase(value.getType());
-
- return PersistentSetFactory.from(bagNew, contentNew);
- }
-
- @Override
- public ISet delete(IValue value) {
- final Set.Immutable contentNew =
- content.__remove(value);
-
- if (content == contentNew)
- return this;
-
- final AbstractTypeBag bagNew = elementTypeBag.decrease(value.getType());
-
- return PersistentSetFactory.from(bagNew, contentNew);
- }
-
- @Override
- public int size() {
- return content.size();
- }
-
- @Override
- public boolean contains(IValue value) {
- return content.contains(value);
- }
-
- @Override
- public Iterator iterator() {
- return content.iterator();
- }
-
- @Override
- public int hashCode() {
- return content.hashCode();
- }
-
- @Override
- public boolean equals(@Nullable Object other) {
- if (other == this) {
- return true;
+
+ @Override
+ public String toString() {
+ return defaultToString();
}
-
- if (other == null) {
- return false;
+
+ private static final boolean checkDynamicType(final AbstractTypeBag elementTypeBag,
+ final Set.Immutable content) {
+
+ final AbstractTypeBag expectedElementTypeBag =
+ content.stream().map(IValue::getType).collect(AbstractTypeBag.toTypeBag());
+
+ boolean expectedTypesEqual = expectedElementTypeBag.equals(elementTypeBag);
+
+ return expectedTypesEqual;
}
- if (other instanceof PersistentHashSet) {
- PersistentHashSet that = (PersistentHashSet) other;
+ @Override
+ public ISetWriter writer() {
+ return ValueFactory.getInstance().setWriter();
+ }
- if (this.getType() != that.getType()) {
- return false;
- }
+ @Override
+ public Type getType() {
+ if (cachedSetType == null) {
+ cachedSetType = TF.setType(elementTypeBag.lub());
+ }
- if (this.size() != that.size()) {
- return false;
- }
+ return cachedSetType;
+ }
- return content.equals(that.content);
+ @Override
+ public boolean isEmpty() {
+ return content.isEmpty();
}
- if (other instanceof ISet) {
- return defaultEquals(other);
+ @Override
+ public ISet insert(IValue value) {
+ final Set.Immutable contentNew =
+ content.__insert(value);
+
+ if (content == contentNew)
+ return this;
+
+ final AbstractTypeBag bagNew = elementTypeBag.increase(value.getType());
+
+ return PersistentSetFactory.from(bagNew, contentNew);
}
- return false;
- }
+ @Override
+ public ISet delete(IValue value) {
+ final Set.Immutable contentNew =
+ content.__remove(value);
+
+ if (content == contentNew)
+ return this;
- @Override
- public ISet union(ISet other) {
- if (other == this) {
- return this;
+ final AbstractTypeBag bagNew = elementTypeBag.decrease(value.getType());
+
+ return PersistentSetFactory.from(bagNew, contentNew);
}
-
- if (other instanceof PersistentHashSet) {
- PersistentHashSet that = (PersistentHashSet) other;
-
- final Set.Immutable one;
- final Set.Immutable two;
- AbstractTypeBag bag;
- final ISet def;
-
- if (that.size() >= this.size()) {
- def = that;
- one = that.content;
- bag = that.elementTypeBag;
- two = this.content;
- } else {
- def = this;
- one = this.content;
- bag = this.elementTypeBag;
- two = that.content;
- }
-
- final Set.Transient tmp = one.asTransient();
- boolean modified = false;
-
- for (IValue key : two) {
- if (tmp.__insert(key)) {
- modified = true;
- bag = bag.increase(key.getType());
- }
- }
-
- if (modified) {
- return PersistentSetFactory.from(bag, tmp.freeze());
- }
- return def;
- } else {
- return ISet.super.union(other);
+
+ @Override
+ public int size() {
+ return content.size();
}
- }
- @Override
- public ISet intersect(ISet other) {
- if (other == this) {
- return this;
+ @Override
+ public boolean contains(IValue value) {
+ return content.contains(value);
}
- if (other instanceof PersistentHashSet) {
- PersistentHashSet that = (PersistentHashSet) other;
-
- final Set.Immutable one;
- final Set.Immutable two;
- AbstractTypeBag bag;
- final ISet def;
-
- if (that.size() >= this.size()) {
- def = this;
- one = this.content;
- bag = this.elementTypeBag;
- two = that.content;
- } else {
- def = that;
- one = that.content;
- bag = that.elementTypeBag;
- two = this.content;
- }
-
- final Set.Transient tmp = one.asTransient();
- boolean modified = false;
-
- for (Iterator it = tmp.iterator(); it.hasNext();) {
- final IValue key = it.next();
- if (!two.contains(key)) {
- it.remove();
- modified = true;
- bag = bag.decrease(key.getType());
- }
- }
-
- if (modified) {
- return PersistentSetFactory.from(bag, tmp.freeze());
- }
- return def;
- } else {
- return ISet.super.intersect(other);
+ @Override
+ public Iterator iterator() {
+ return content.iterator();
}
- }
- @Override
- public ISet subtract(ISet other) {
- if (other == this) {
- return EmptySet.EMPTY_SET;
+ @Override
+ public int hashCode() {
+ return content.hashCode();
+ }
+
+ @Override
+ public boolean equals(@Nullable Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (other == null) {
+ return false;
+ }
+
+ if (other instanceof PersistentHashSet) {
+ PersistentHashSet that = (PersistentHashSet) other;
+
+ if (this.getType() != that.getType()) {
+ return false;
+ }
+
+ if (this.size() != that.size()) {
+ return false;
+ }
+
+ return content.equals(that.content);
+ }
+
+ if (other instanceof ISet) {
+ return defaultEquals(other);
+ }
+
+ return false;
}
-
- if (other == null) {
- return this;
+
+ @Override
+ public ISet union(ISet other) {
+ if (other == this) {
+ return this;
+ }
+
+ if (other instanceof PersistentHashSet) {
+ PersistentHashSet that = (PersistentHashSet) other;
+
+ final Set.Immutable one;
+ final Set.Immutable two;
+ AbstractTypeBag bag;
+ final ISet def;
+
+ if (that.size() >= this.size()) {
+ def = that;
+ one = that.content;
+ bag = that.elementTypeBag;
+ two = this.content;
+ } else {
+ def = this;
+ one = this.content;
+ bag = this.elementTypeBag;
+ two = that.content;
+ }
+
+ final Set.Transient tmp = one.asTransient();
+ boolean modified = false;
+
+ for (IValue key : two) {
+ if (tmp.__insert(key)) {
+ modified = true;
+ bag = bag.increase(key.getType());
+ }
+ }
+
+ if (modified) {
+ return PersistentSetFactory.from(bag, tmp.freeze());
+ }
+ return def;
+ } else {
+ return ISet.super.union(other);
+ }
}
- if (other instanceof PersistentHashSet) {
- PersistentHashSet that = (PersistentHashSet) other;
+ @Override
+ public ISet intersect(ISet other) {
+ if (other == this) {
+ return this;
+ }
- final Set.Immutable one;
- final Set.Immutable two;
- AbstractTypeBag bag;
- final ISet def;
+ if (other instanceof PersistentHashSet) {
+ PersistentHashSet that = (PersistentHashSet) other;
+
+ final Set.Immutable one;
+ final Set.Immutable two;
+ AbstractTypeBag bag;
+ final ISet def;
+
+ if (that.size() >= this.size()) {
+ def = this;
+ one = this.content;
+ bag = this.elementTypeBag;
+ two = that.content;
+ } else {
+ def = that;
+ one = that.content;
+ bag = that.elementTypeBag;
+ two = this.content;
+ }
+
+ final Set.Transient tmp = one.asTransient();
+ boolean modified = false;
+
+ for (Iterator it = tmp.iterator(); it.hasNext();) {
+ final IValue key = it.next();
+ if (!two.contains(key)) {
+ it.remove();
+ modified = true;
+ bag = bag.decrease(key.getType());
+ }
+ }
+
+ if (modified) {
+ return PersistentSetFactory.from(bag, tmp.freeze());
+ }
+ return def;
+ } else {
+ return ISet.super.intersect(other);
+ }
+ }
- def = this;
- one = this.content;
- bag = this.elementTypeBag;
- two = that.content;
+ @Override
+ public ISet subtract(ISet other) {
+ if (other == this) {
+ return EmptySet.EMPTY_SET;
+ }
- final Set.Transient tmp = one.asTransient();
- boolean modified = false;
+ if (other == null) {
+ return this;
+ }
- for (IValue key : two) {
- if (tmp.__remove(key)) {
- modified = true;
- bag = bag.decrease(key.getType());
+ if (other instanceof PersistentHashSet) {
+ PersistentHashSet that = (PersistentHashSet) other;
+
+ final Set.Immutable one;
+ final Set.Immutable two;
+ AbstractTypeBag bag;
+ final ISet def;
+
+ def = this;
+ one = this.content;
+ bag = this.elementTypeBag;
+ two = that.content;
+
+ final Set.Transient tmp = one.asTransient();
+ boolean modified = false;
+
+ for (IValue key : two) {
+ if (tmp.__remove(key)) {
+ modified = true;
+ bag = bag.decrease(key.getType());
+ }
+ }
+
+ if (modified) {
+ return PersistentSetFactory.from(bag, tmp.freeze());
+ }
+ return def;
+ } else {
+ return ISet.super.subtract(other);
}
- }
-
- if (modified) {
- return PersistentSetFactory.from(bag, tmp.freeze());
- }
- return def;
- } else {
- return ISet.super.subtract(other);
}
- }
-
- @Override
+
+ @Override
public IRelation asRelation() {
return new PersistentSetRelation(this);
}
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/PersistentSetFactory.java b/src/main/java/io/usethesource/vallang/impl/persistent/PersistentSetFactory.java
index 04d05b4e9..d822d5689 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/PersistentSetFactory.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/PersistentSetFactory.java
@@ -23,74 +23,74 @@
import io.usethesource.vallang.util.AbstractTypeBag;
/**
- * Smart constructors for choosing (or converting to) the most appropriate representations based on
- * dynamic types and data.
- */
+* Smart constructors for choosing (or converting to) the most appropriate representations based on
+* dynamic types and data.
+*/
/*package*/ class PersistentSetFactory {
- /**
- * Creating an {@link ISet} instance from a {@link SetMultimap.Immutable} representation
- * by recovering the precise dynamic type.
- *
- * @param content internal set representation of an {@link ISet}
- * @return appropriate {@link ISet} based on data and type
- */
- static final ISet from(final Set.Immutable content) {
-
- if (content.isEmpty()) {
- return EmptySet.EMPTY_SET;
- }
-
- // recover precise dynamic type
- final AbstractTypeBag elementTypeBag =
- content.stream().map(IValue::getType).collect(AbstractTypeBag.toTypeBag());
-
- return from(elementTypeBag, content);
- }
-
- /**
- * Creating an {@link ISet} instance from a {@link SetMultimap.Immutable} representation.
- *
- * @param keyTypeBag precise dynamic type of first data column
- * @param valTypeBag precise dynamic type of second data column
- * @param content internal multi-map representation of an {@link ISet}
- * @return appropriate {@link ISet} based on data and type
- */
- static final ISet from(final AbstractTypeBag keyTypeBag, final AbstractTypeBag valTypeBag,
- final SetMultimap.Immutable content) {
-
- if (content.isEmpty()) {
- return EmptySet.EMPTY_SET;
- }
+ /**
+ * Creating an {@link ISet} instance from a {@link SetMultimap.Immutable} representation
+ * by recovering the precise dynamic type.
+ *
+ * @param content internal set representation of an {@link ISet}
+ * @return appropriate {@link ISet} based on data and type
+ */
+ static final ISet from(final Set.Immutable content) {
- // keep current representation
- return new PersistentHashIndexedBinaryRelation(keyTypeBag, valTypeBag, content);
- }
+ if (content.isEmpty()) {
+ return EmptySet.EMPTY_SET;
+ }
- /**
- * Creating an {@link ISet} instance from a {@link SetMultimap.Immutable} representation.
- *
- * @param elementTypeBag precise dynamic type of elements of a collection
- * @param content internal set representation of an {@link ISet}
- * @return appropriate {@link ISet} based on data and type
- */
- static final ISet from(final AbstractTypeBag elementTypeBag,
- final Set.Immutable content) {
+ // recover precise dynamic type
+ final AbstractTypeBag elementTypeBag =
+ content.stream().map(IValue::getType).collect(AbstractTypeBag.toTypeBag());
- final Type elementType = elementTypeBag.lub();
-
- if (elementType.isBottom()) {
- return EmptySet.EMPTY_SET;
+ return from(elementTypeBag, content);
}
- if (isTupleOfArityTwo.test(elementType)) {
- // convert to binary relation
- return content.stream().map(asInstanceOf(ITuple.class))
- .collect(ValueCollectors.toSetMultimap(tuple -> tuple.get(0), tuple -> tuple.get(1)));
+ /**
+ * Creating an {@link ISet} instance from a {@link SetMultimap.Immutable} representation.
+ *
+ * @param keyTypeBag precise dynamic type of first data column
+ * @param valTypeBag precise dynamic type of second data column
+ * @param content internal multi-map representation of an {@link ISet}
+ * @return appropriate {@link ISet} based on data and type
+ */
+ static final ISet from(final AbstractTypeBag keyTypeBag, final AbstractTypeBag valTypeBag,
+ final SetMultimap.Immutable content) {
+
+ if (content.isEmpty()) {
+ return EmptySet.EMPTY_SET;
+ }
+
+ // keep current representation
+ return new PersistentHashIndexedBinaryRelation(keyTypeBag, valTypeBag, content);
}
- // keep current representation
- return new PersistentHashSet(elementTypeBag, content);
- }
+ /**
+ * Creating an {@link ISet} instance from a {@link SetMultimap.Immutable} representation.
+ *
+ * @param elementTypeBag precise dynamic type of elements of a collection
+ * @param content internal set representation of an {@link ISet}
+ * @return appropriate {@link ISet} based on data and type
+ */
+ static final ISet from(final AbstractTypeBag elementTypeBag,
+ final Set.Immutable content) {
+
+ final Type elementType = elementTypeBag.lub();
+
+ if (elementType.isBottom()) {
+ return EmptySet.EMPTY_SET;
+ }
+
+ if (isTupleOfArityTwo.test(elementType)) {
+ // convert to binary relation
+ return content.stream().map(asInstanceOf(ITuple.class))
+ .collect(ValueCollectors.toSetMultimap(tuple -> tuple.get(0), tuple -> tuple.get(1)));
+ }
+
+ // keep current representation
+ return new PersistentHashSet(elementTypeBag, content);
+ }
}
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/PersistentSetRelation.java b/src/main/java/io/usethesource/vallang/impl/persistent/PersistentSetRelation.java
index fd83654d7..f226d3cfc 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/PersistentSetRelation.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/PersistentSetRelation.java
@@ -16,7 +16,7 @@ public class PersistentSetRelation implements IRelation {
public PersistentSetRelation(ISet set) {
this.set = set;
}
-
+
@Override
public ISet asContainer() {
return set;
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/SetWriter.java b/src/main/java/io/usethesource/vallang/impl/persistent/SetWriter.java
index 03683b1e3..907c44d29 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/SetWriter.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/SetWriter.java
@@ -164,14 +164,14 @@ private void put(IValue element) {
}
else if (builder == null) {
// first values was not a binary tuple, so let's build a normal set
- builder = new SetBuilder();
+ builder = new SetBuilder();
}
else if (builder instanceof MultiMapBuilder) {
// special case, previous values were all binary tuples, but the new value isn't
MultiMapBuilder oldBuilder = (MultiMapBuilder) builder;
builder = new SetBuilder();
final Builder finalSetBuilder = builder;
- oldBuilder.map.tupleStream(constructTuple).forEach(t -> finalSetBuilder.put(t, t.getType()));
+ oldBuilder.map.tupleStream(constructTuple).forEach(t -> finalSetBuilder.put(t, t.getType()));
}
}
diff --git a/src/main/java/io/usethesource/vallang/impl/persistent/Tuple.java b/src/main/java/io/usethesource/vallang/impl/persistent/Tuple.java
index 30bdfa976..ce3c7cd2b 100644
--- a/src/main/java/io/usethesource/vallang/impl/persistent/Tuple.java
+++ b/src/main/java/io/usethesource/vallang/impl/persistent/Tuple.java
@@ -23,178 +23,178 @@
import io.usethesource.vallang.visitors.IValueVisitor;
/*package*/ class Tuple implements ITuple{
- protected static final TypeFactory typeFactory = TypeFactory.getInstance();
- private @MonotonicNonNull Type cachedTupleType;
- protected final IValue[] elements;
-
- private static final ITuple EMPTY_TUPLE = new Tuple();
-
- public static ITuple newTuple(IValue... elements) {
- if (elements.length == 0) {
- return EMPTY_TUPLE;
- }
- return new Tuple(elements);
- }
-
- private Tuple(IValue... elements) {
- super();
-
- this.elements = elements;
- }
-
- @Override
- public Type getType() {
- if (cachedTupleType == null) {
- cachedTupleType = TypeFactory.getInstance().tupleType(elements);
- }
-
- return cachedTupleType;
- }
-
- @Override
- public int arity() {
- return elements.length;
- }
-
- @Override
- public IValue get(int i) {
- return elements[i];
- }
-
- @Override
- public IValue get(String label) {
- return elements[getType().getFieldIndex(label)];
- }
-
- @Override
- public Iterator iterator() {
- return new TupleIterator(this);
- }
-
- @Override
- public T accept(IValueVisitor v) throws E {
- return v.visitTuple(this);
- }
-
- @Override
- public ITuple set(int index, IValue arg) {
- int nrOfElements = elements.length;
- IValue[] newElements = new IValue[nrOfElements];
- Type[] elementTypes = new Type[nrOfElements];
- for (int i = nrOfElements - 1; i >= 0; i--) {
- IValue element = elements[i];
- newElements[i] = element;
- elementTypes[i] = element.getType();
- }
-
- newElements[index] = arg;
- elementTypes[index] = arg.getType();
-
- return new Tuple(newElements);
- }
-
- @Override
- public ITuple set(String label, IValue arg) {
- int nrOfElements = elements.length;
- IValue[] newElements = new IValue[nrOfElements];
- Type[] elementTypes = new Type[nrOfElements];
- for (int i = nrOfElements - 1; i >= 0; i--) {
- IValue element = elements[i];
- newElements[i] = element;
- elementTypes[i] = element.getType();
- }
-
- newElements[getType().getFieldIndex(label)] = arg;
- elementTypes[getType().getFieldIndex(label)] = arg.getType();
-
- return new Tuple(newElements);
- }
-
- @Override
- public IValue select(int... indexes) {
- if (indexes.length == 1)
- return get(indexes[0]);
-
- int nrOfElements = indexes.length;
- IValue[] elements = new IValue[nrOfElements];
- Type[] elementTypes = new Type[nrOfElements];
- for (int i = nrOfElements - 1; i >= 0; i--) {
- IValue element = get(indexes[i]);
- elements[i] = element;
- elementTypes[i] = element.getType();
- }
-
- return new Tuple(elements);
- }
-
- @Override
- public IValue selectByFieldNames(String... fields) {
- if (fields.length == 1)
- return get(fields[0]);
-
- int nrOfElements = fields.length;
- IValue[] elements = new IValue[nrOfElements];
- Type[] elementTypes = new Type[nrOfElements];
- for (int i = nrOfElements - 1; i >= 0; i--) {
- IValue element = get(fields[i]);
- elements[i] = element;
- elementTypes[i] = element.getType();
- }
-
- return new Tuple(elements);
- }
-
- @Override
- public String toString() {
- return defaultToString();
- }
-
- @Override
- public int hashCode() {
- int hash = 1331;
-
- for (int i = elements.length - 1; i >= 0; i--) {
- hash -= (hash << 19) + (hash >>> 8);
- hash ^= elements[i].hashCode();
- }
-
- return hash - (hash << 7);
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (o == this) {
- return true;
- }
-
- if (o == null) {
- return false;
- }
-
- if (o.getClass() == getClass()) {
- Tuple otherTuple = (Tuple) o;
-
- // checking for the type will dynamically allocate memory
- // because tuple types are computed lazily.
- // so we skip this "fast failure" check
- // if (getType() != otherTuple.getType()) { return false; }
-
-
- IValue[] otherElements = otherTuple.elements;
- int nrOfElements = elements.length;
- if (otherElements.length == nrOfElements) {
- for (int i = nrOfElements - 1; i >= 0; i--) {
- if (!otherElements[i].equals(elements[i]))
- return false;
- }
- return true;
- }
- }
-
- return false;
- }
-
- @Override
+ protected static final TypeFactory typeFactory = TypeFactory.getInstance();
+ private @MonotonicNonNull Type cachedTupleType;
+ protected final IValue[] elements;
+
+ private static final ITuple EMPTY_TUPLE = new Tuple();
+
+ public static ITuple newTuple(IValue... elements) {
+ if (elements.length == 0) {
+ return EMPTY_TUPLE;
+ }
+ return new Tuple(elements);
+ }
+
+ private Tuple(IValue... elements) {
+ super();
+
+ this.elements = elements;
+ }
+
+ @Override
+ public Type getType() {
+ if (cachedTupleType == null) {
+ cachedTupleType = TypeFactory.getInstance().tupleType(elements);
+ }
+
+ return cachedTupleType;
+ }
+
+ @Override
+ public int arity() {
+ return elements.length;
+ }
+
+ @Override
+ public IValue get(int i) {
+ return elements[i];
+ }
+
+ @Override
+ public IValue get(String label) {
+ return elements[getType().getFieldIndex(label)];
+ }
+
+ @Override
+ public Iterator