use of org.eclipse.collections.api.list.primitive.ByteList in project narchy by automenta.
the class Subterms method equivalentStructures.
// TODO optionally allow atomic structure positions to differ
default boolean equivalentStructures() {
int t0Struct = sub(0).structure();
int s = subs();
for (int i = 1; i < s; i++) {
if (sub(i).structure() != t0Struct)
return false;
}
ByteList structureKey = sub(0).structureKey();
ByteArrayList reuseKey = new ByteArrayList(structureKey.size());
for (int i = 1; i < s; i++) {
// TODO only needs to construct the key while comparing equality with the first
if (!sub(i).structureKey(reuseKey).equals(structureKey))
return false;
reuseKey.clear();
}
return true;
}
use of org.eclipse.collections.api.list.primitive.ByteList in project narchy by automenta.
the class Int method unroll.
/**
* unroll IntInterval's
*/
public static Iterator<Term> unroll(Term cc) {
// assert(!c.hasAny(Op.INT));
// return Iterators.singletonIterator(c); //no IntInterval's early exit
Map<ByteList, IntRange> intervals = new HashMap();
cc.pathsTo(x -> x instanceof IntRange ? ((IntRange) x) : null, d -> d.hasAny(Op.INT), (ByteList p, IntRange x) -> {
intervals.put(p.toImmutable(), x);
return true;
});
int dim = intervals.size();
switch(dim) {
case 0:
throw new RuntimeException();
case // 1D
1:
{
Map.Entry<ByteList, IntRange> e = intervals.entrySet().iterator().next();
IntRange i1 = e.getValue();
int max = i1.max;
int min = i1.min;
List<Term> t = $.newArrayList(1 + max - min);
for (int i = min; i <= max; i++) {
@Nullable Term c1 = cc.transform(e.getKey(), $.the(i));
if (c1 != null)
t.add(c1);
}
return t.iterator();
}
case // 2D
2:
Iterator<Map.Entry<ByteList, IntRange>> ee = intervals.entrySet().iterator();
Map.Entry<ByteList, IntRange> e1 = ee.next();
Map.Entry<ByteList, IntRange> e2 = ee.next();
IntRange i1 = e1.getValue();
IntRange i2 = e2.getValue();
int max1 = i1.max, min1 = i1.min, max2 = i2.max, min2 = i2.min;
List<Term> t = $.newArrayList((1 + max2 - min2) * (1 + max1 - min1));
for (int i = min1; i <= max1; i++) {
for (int j = min2; j <= max2; j++) {
Term c1 = cc.transform(e1.getKey(), $.the(i));
Term c2 = c1.transform(e2.getKey(), $.the(j));
if (!(c2 instanceof Compound))
// throw new RuntimeException("how not transformed to compound");
continue;
t.add(c2);
}
}
return t.iterator();
default:
// either there is none, or too many -- just use the term directly
if (Param.DEBUG)
throw new UnsupportedOperationException("too many embedded dimensions: " + dim);
else
return null;
}
}
use of org.eclipse.collections.api.list.primitive.ByteList in project eclipse-collections by eclipse.
the class Collectors2AdditionalTest method collectByte.
@Test
public void collectByte() {
ByteList expected = SMALL_INTERVAL.collectByte(each -> (byte) (each % Byte.MAX_VALUE), ByteLists.mutable.empty());
ByteList actual = this.smallData.stream().collect(Collectors2.collectByte(each -> (byte) (each % Byte.MAX_VALUE), ByteLists.mutable::empty));
Assert.assertEquals(expected, actual);
}
use of org.eclipse.collections.api.list.primitive.ByteList in project narchy by automenta.
the class Int method intersect.
// public static Term[] intersect(Term[] u) {
//
// TreeSet<Intlike> integers = new TreeSet();
// for (Term x : u) {
// if (x.op() == INT) {
// integers.add((Intlike) x);
// }
// }
//
// int ii = integers.size();
// if (ii < 2)
// return u; //one or less integers, do nothing about it
//
//
// TreeSet<Term> v = new TreeSet<>();
// for (Term uu : u)
// v.add(uu);
//
// Intlike a = integers.pollFirst();
// Intlike b = integers.pollFirst();
// Range ar = a.range();
// Range br = b.range();
// if (ar.isConnected(br)) {
// Intlike combined = Int.the(ar.span(br));
// v.remove(a);
// v.remove(b);
// v.add(combined);
// }
//
//
// return v.toArray(new Term[v.size()]);
//
// }
/**
* TODO permute other arrangements
*/
public static Term[] intersect(final Term... _subs) {
RoaringBitmap factoring = new RoaringBitmap();
int equalVolume = -1, equalStructure = -1;
int pureInts = 0;
for (int i = 0, subsLength = _subs.length; i < subsLength; i++) {
Term x = _subs[i];
if (!x.hasAny(Op.INT)) {
continue;
}
if (x.op() == INT)
pureInts++;
if (equalVolume != -1) {
if (x.volume() != equalVolume) {
// a term with non-matching volume
continue;
}
}
if (equalStructure != -1) {
if (x.structure() != equalStructure) {
continue;
}
}
equalVolume = x.volume();
equalStructure = x.structure();
factoring.add(i);
}
int ff = factoring.getCardinality();
if (ff < 2)
return sorted(_subs);
Term[] subs;
if (ff < _subs.length) {
subs = new Term[ff];
int j = 0;
for (int i = 0; i < _subs.length; i++) {
if (factoring.contains(i))
subs[j++] = _subs[i];
}
assert (j == ff);
} else {
subs = _subs;
}
if (subs.length == 3) {
Term[] rr;
// HACK try permutations to combine some but not all
Term[] ab = intersect(subs[0], subs[1]);
if (ab.length == 1) {
rr = intersect(ab[0], subs[2]);
} else {
Term[] bc = intersect(subs[1], subs[2]);
if (bc.length == 1) {
rr = intersect(bc[0], subs[0]);
} else {
Term[] ac = intersect(subs[0], subs[2]);
if (ac.length == 1) {
rr = intersect(ac[0], subs[1]);
} else {
rr = null;
}
}
}
if (rr != null) {
return intersectResult(factoring, ff, new FasterList(rr), _subs);
}
}
FasterList<Term> yAux = new FasterList(0);
if (pureInts == ff) {
// avoid the path stuff, just merge the int terms
SimpleIntSet s = new SimpleIntSet(ff);
for (Term x : subs) {
((Intlike) x).forEachInt(s::add);
}
int ns = s.size();
assert (ns > 1);
if (ns == 2) {
// simple case
Iterator<Integer> si = s.iterator();
int a = si.next();
int b = si.next();
if (Math.abs(a - b) > 1) {
yAux.add(Int.the(a));
yAux.add(Int.the(b));
} else {
if (a > b) {
int c = b;
b = a;
a = c;
}
yAux.add(Int.range(a, b));
}
} else {
features(s.iterator(), -1).forEachRemaining(yAux::add);
}
} else {
// paths * extracted sequence of numbers at given path for each subterm
Map<ByteList, Object> /*SimpleIntSet*/
data = new LinkedHashMap<>(subs.length);
// if a subterm is not an integer, check for equality of atoms (structure already compared abovec)
final boolean[] valid = { true };
subs[0].pathsTo(x -> x, d -> true, (p, x) -> {
// if (p.isEmpty())
// return true; //continue past root, of course the root term will be unique
ImmutableByteList path = null;
SimpleIntSet c = null;
int xVol = x.volume();
int xStruct = x.structure();
for (int others = 1; others < subs.length; others++) {
Term y = subs[others].subPath(p);
if (x.equals(y))
continue;
if (!x.hasAny(INT)) {
// and we expect differences but only in the INT
if (!y.equals(x)) {
valid[0] = false;
return false;
}
} else if (x.op() == INT) {
if (y.op() != INT) {
valid[0] = false;
return false;
}
if (path == null)
path = p.toImmutable();
// store the path to the integer(s)
if (c == null)
c = (SimpleIntSet) data.computeIfAbsent(path, (pp) -> new SimpleIntSet(2));
((Intlike) y).forEachInt(c::add);
} else {
// this is a term containing an INT but is not an INT; the structure must still match
if (xVol != y.volume() || xStruct != y.structure()) {
valid[0] = false;
return false;
}
}
}
if (x.op() == INT) {
if (c == null) {
if (path == null)
path = p.toImmutable();
data.put(path, c = new SimpleIntSet(1));
}
((Intlike) x).forEachInt(c::add);
}
return true;
});
if (!valid[0])
return _subs;
Iterator<Map.Entry<ByteList, Object>> entries = data.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<ByteList, Object> /*SimpleIntSet*/
e = entries.next();
SimpleIntSet s = (SimpleIntSet) e.getValue();
if (s.size() < 2) {
entries.remove();
// same integer value in each
continue;
}
// for each path where the other numerics are uniformly equal (only one unique value)
/*if (new HashSet(nn).size()==1)*/
Iterator<Integer> si = s.iterator();
if (e.getKey().isEmpty()) {
// root level, get as many as possible
features(si, -1).forEachRemaining(yAux::add);
entries.remove();
} else {
Iterator<Intlike> iii = features(si, 1);
if (iii == null || !iii.hasNext())
// discontiguous or otherwise ununifiable
return _subs;
e.setValue(iii.next());
}
}
Term y;
if (!data.isEmpty()) {
y = subs[0];
for (Map.Entry<ByteList, Object> /*Intlike*/
e : data.entrySet()) {
Object v = e.getValue();
y = y.transform(e.getKey(), (Term) v);
}
} else {
y = null;
}
if (subs.length == _subs.length && yAux.isEmpty()) {
if (y == null)
// ??
return _subs;
return new Term[] { y };
} else {
yAux.add(y);
}
}
return intersectResult(factoring, ff, yAux, _subs);
// int ffs = ff.size();
// if (ffs == 0 || ffs >= numInvolved) {
// //nothing would be gained; dont bother
// continue;
// }
//
// for (Intlike f : ff) {
// byte j = 0;
// for (Term x : subs) {
//
// if (!involved.contains(j)) {
// result.add(x);
// //System.out.println("1: " + result);
// } else {
//
//
// //x is contained within range expression p
// Term xpp = x.subs() > 0 ? x.subPath(pp) : x;
//
// boolean connected;
// if (xpp.op() == INT) {
// connected = (f.range().isConnected(((Intlike) xpp).range()));
// } else {
// connected = false;
// }
//
// if (connected) {
// Term y = x instanceof Compound ?
// x.transform(pp, f)
// : f;
// //if (!y.equals(x)) {
//
// if (!x.equals(y)) {
// subsumed.add(x);
// }
// result.add(y);
// //System.out.println(x + " 3: " + result + "\t + " + y);
// //}
// } else {
// result.add(x);
// }
// }
// j++;
// }
//
//
// }
//
// int results = result.size();
// if ((results == 1) /*|| (results > resultLimit * subCount)*/) {
// break; //reduced to one or exploded, go no further
// }
// }
// result.removeAll(subsumed);
//
// if (result.isEmpty()) {
// return subs;
// } else {
//
// Term[] rr = result.toArray(new Term[result.size()]);
// if (Arrays.equals(rr, subs))
// return rr;
// else
// return intersect(rr); //changed, recompress
//
// }
}
use of org.eclipse.collections.api.list.primitive.ByteList in project narchy by automenta.
the class DepIndepVarIntroduction method introduce.
@Nullable
@Override
protected Term introduce(Term input, Term selected, byte order) {
if (selected.equals(Imdex))
return null;
Op inOp = input.op();
List<ByteList> paths = $.newArrayList(1);
int minPathLength = inOp.statement ? 2 : 0;
input.pathsTo(selected, (path, t) -> {
if (path.size() >= minPathLength)
paths.add(path.toImmutable());
// TODO may be able to terminate early if we know this is the last one
return true;
});
int pSize = paths.size();
// if (pSize == 0)
if (pSize <= 1)
return null;
// byte[][] paths = pp.toArray(new byte[pSize][]);
// //detect an invalid top-level indep var substitution
// if (inOp.statement) {
// Iterator<byte[]> pp = paths.iterator();
// while (pp.hasNext()) {
// byte[] p = pp.next();
// if (p.length < 2)
// pp.remove();;
// for (byte[] r : paths)
// if (r.length < 2)
// return null; //substitution would replace something at the top level of a statement}
// }
// }
// use the innermost common parent to decide the type of variable.
// in case there is no other common parent besides input itself, use that.
Term commonParent = input.commonParent(paths);
Op commonParentOp = commonParent.op();
// decide what kind of variable can be introduced according to the input operator
boolean depOrIndep;
switch(commonParentOp) {
case CONJ:
depOrIndep = true;
break;
case IMPL:
depOrIndep = false;
break;
default:
// ????
return null;
}
ObjectByteHashMap<Term> m = new ObjectByteHashMap<>(0);
for (int path = 0; path < pSize; path++) {
ByteList p = paths.get(path);
// root
Term t = null;
int pathLength = p.size();
for (int i = -1; i < pathLength - 1; /* dont include the selected term itself */
i++) {
t = (i == -1) ? input : t.sub(p.get(i));
Op o = t.op();
if (!depOrIndep && validIndepVarSuperterm(o)) {
byte inside = (byte) (1 << p.get(i + 1));
m.updateValue(t, inside, (previous) -> (byte) ((previous) | inside));
} else if (depOrIndep && validDepVarSuperterm(o)) {
m.addToValue(t, (byte) 1);
}
}
}
if (!depOrIndep) {
// at least one impl/equiv must have both sides covered
return (m.anySatisfy(b -> b == 0b11)) ? $.v(VAR_INDEP, order) : /*varIndep(order)*/
null;
} else {
// at least one conjunction must contain >=2 path instances
return m.anySatisfy(b -> b >= 2) ? $.v(VAR_DEP, order) : /* $.varDep(order) */
null;
}
}
Aggregations