use of org.eclipse.collections.api.tuple.primitive.LongObjectPair in project narchy by automenta.
the class ConjClustering method conjoinCentroid.
// /**
// * produces a parallel conjunction term consisting of all the task's terms
// */
// public Stream<List<Task>> chunk(Stream<Task> input, int maxComponentsPerTerm, int maxVolume) {
// final int[] group = {0};
// final int[] subterms = {0};
// final int[] currentVolume = {0};
// final float[] currentConf = {1};
// return input.filter(x -> !x.isDeleted())
// .collect(Collectors.groupingBy(x -> {
//
// int v = x.volume();
// float c = x.conf();
//
// if ((subterms[0] >= maxComponentsPerTerm) || (currentVolume[0] + v >= maxVolume) || (currentConf[0] * c < confMin)) {
// //next group
// group[0]++;
// subterms[0] = 1;
// currentVolume[0] = v;
// currentConf[0] = c;
// } else {
// subterms[0]++;
// currentVolume[0] += v;
// currentConf[0] *= c;
// }
//
// return group[0];
// }))
// .entrySet().stream()
// .map(c -> {
// List<Task> v = c.getValue();
// return c.getKey() >= 0 && //only batches of >1
// v.size() > 1 ? v : null; //ignore the -1 discard group
// })
// .filter(Objects::nonNull);
//
// }
// static final BiFunction<Task, Task, Task> termPointMerger = (prevZ, newZ) -> ((prevZ == null) || (newZ.conf() >= prevZ.conf())) ?
// newZ : prevZ;
private List<Task> conjoinCentroid(Stream<VLink<Task>> group, Pair<NAR, List<Task>> narAndTarget) {
NAR nar = narAndTarget.getOne();
// get only the maximum confidence task for each term at its given starting time
// in.input(
// chunk(group.filter(Objects::nonNull).takeWhile(kontinue)
// .map(x -> x.id), maxConjSize, volMax).takeWhile(kontinue).map(tasks -> {
Iterator<VLink<Task>> gg = group.filter(x -> x != null && !x.isDeleted()).iterator();
// Iterators.peekingIterator();
Map<LongObjectPair<Term>, Task> vv = new HashMap<>();
FasterList<Task> actualTasks = new FasterList();
int centroidGen = 0;
List<Task> gen = narAndTarget.getTwo();
main: while (gg.hasNext() && centroidGen < taskLimitPerCentroid) {
vv.clear();
actualTasks.clear();
long end = Long.MIN_VALUE;
long start = Long.MAX_VALUE;
int dur = nar.dur();
float freq = 1f;
float conf = 1f;
float priMax = Float.NEGATIVE_INFINITY, priMin = Float.POSITIVE_INFINITY;
int vol = 0;
int maxVolume = 0;
do {
if (!gg.hasNext())
break;
Task t = gg.next().id;
// gg.peek().id;
Term xt = t.term();
long zs = Tense.dither(t.start(), ditherTime);
long ze = Tense.dither(t.end(), ditherTime);
// assert (end >= start);
Truth tx = t.truth();
Term xtn = xt.neg();
if (tx.isNegative()) {
xt = xtn;
}
int xtv = xt.volume();
maxVolume = Math.max(maxVolume, xt.volume());
if (vol + xtv + 1 >= volMax || conf * tx.conf() < confMin) {
// cant go any further with this task
continue;
}
boolean involved = false;
LongObjectPair<Term> ps = pair(zs, xt);
Term xtNeg = xt.neg();
if (!vv.containsKey(pair(zs, xtNeg)) && null == vv.putIfAbsent(ps, t)) {
vol += xtv;
if (start > zs)
start = zs;
if (end < zs)
end = zs;
involved = true;
}
if (ze - zs >= dur) {
// endpoint
if (vol + xtv + 1 < volMax) {
LongObjectPair<Term> pe = pair(ze, xt);
if (!vv.containsKey(pair(ze, xtNeg)) && null == vv.putIfAbsent(pe, t)) {
// end point, if different from start
vol += xtv;
if (end < ze)
end = ze;
involved = true;
}
}
}
if (involved) {
actualTasks.add(t);
conf *= tx.conf();
float tf = tx.freq();
// since it will appear as a negated subterm
freq *= tx.isNegative() ? (1f - tf) : tf;
float p = t.priElseZero();
if (p < priMin)
priMin = p;
if (p > priMax)
priMax = p;
}
} while (vol < volMax - 1 && conf > confMin);
int vs = actualTasks.size();
if (vs < 2)
continue;
// the tasks which are actually involved
Task[] uu = actualTasks.toArrayRecycled(Task[]::new);
// TODO discount based on evidential overlap? needs N-way overlapFraction function
ObjectFloatPair<long[]> evidence = Stamp.zip(actualTasks, Param.STAMP_CAPACITY);
float overlap = evidence.getTwo();
float e = c2w(conf) * Param.overlapFactor(overlap);
if (e > 0) {
final Truth t = Truth.theDithered(freq, e, nar);
if (t != null) {
Term cj = Conj.conj(vv.keySet());
if (cj != null) {
cj = cj.normalize();
if (Math.abs(cj.dtRange() - (end - start)) < ditherTime) {
// test if merge collapse occurred and occurrence time needs recalculated
ObjectBooleanPair<Term> cp = Task.tryContent(cj, punc, true);
if (cp != null) {
// TODO use a truth calculated specific to this fixed-size batch, not all the tasks combined
NALTask m = new STMClusterTask(cp, t, start, start, evidence.getOne(), punc, now);
// if (evidence.getTwo() > 0) m.setCyclic(true);
m.cause = Cause.sample(Param.causeCapacity.intValue(), uu);
float p = // priMax;
priMin;
// (priMin + priMax) / 2f;
// complexity deduction
// how much more complex the conjunction is than the most complex of its ingredients
int v = cp.getOne().volume();
float cmplFactor = ((float) v) / (v + maxVolume);
m.priSet(Priority.fund(p * cmplFactor, true, uu));
gen.add(m);
centroidGen++;
}
} else {
// System.out.println("merge collapse, recalcu");
}
}
}
}
}
return gen.isEmpty() ? null : gen;
}
use of org.eclipse.collections.api.tuple.primitive.LongObjectPair in project narchy by automenta.
the class Builtin method registerFunctors.
public static void registerFunctors(NAR nar) {
for (Concept t : Builtin.statik) {
nar.on(t);
}
nar.on(Functor.f1("varIntro", (x) -> {
Pair<Term, Map<Term, Term>> result = DepIndepVarIntroduction.the.apply(x, nar.random());
return result != null ? result.getOne() : Null;
}));
nar.on(Functor.f1((Atom) $.the("termlinkRandom"), (Term t) -> {
@Nullable Concept c = nar.conceptualize(t);
if (c == null)
return Null;
@Nullable PriReference<Term> tl = c.termlinks().sample(nar.random());
if (tl == null)
return Null;
return tl.get();
}));
// nar.on(Functor.f("service", (TermContainer c) ->
// $.sete(
// nar.services().map(
// (e) ->
// $.p(e, $.the(e.getValue().state())))
// .toArray(Term[]::new)
// )
// ));
/**
* subterm, but specifically inside an ellipsis. otherwise pass through
*/
nar.on(Functor.f("esubterm", (Subterms c) -> {
Term x = c.sub(0, null);
if (x == null)
return Null;
Term index = c.sub(1, Null);
if (index == Null)
return Null;
int which;
if (index != null) {
if (index instanceof Variable)
return Null;
which = $.intValue(index, -1);
if (which < 0) {
return Null;
}
} else {
// random
which = nar.random().nextInt(x.subs());
}
return x.sub(which);
}));
nar.on(Functor.f2((Atom) $.the("without"), (Term container, Term content) -> Op.without(container, x -> x.equals(content), nar.random())));
nar.on(Functor.f2((Atom) $.the("withoutPosOrNeg"), (Term container, Term content) -> Op.without(container, x -> x.unneg().equals(content), nar.random())));
/**
* TODO rename this to 'dropAnyCommutive'
* remove an element from a commutive conjunction (or set), at random, and try re-creating
* the compound. wont necessarily work in all situations.
* TODO move the type restriction to another functor to wrap this
*
* this also filter a single variable (depvar) from being a result
*/
nar.on(Functor.f1((Atom) $.the("dropAnySet"), (Term t) -> {
Op oo = t.op();
if (oo == INT) {
if (t instanceof Int.IntRange) {
// select random location in the int and split either up or down
Int.IntRange i = (Int.IntRange) t;
Random rng = nar.random();
if (i.min + 1 == i.max) {
// arity=2
return Int.the(rng.nextBoolean() ? i.min : i.max);
} else if (i.min + 2 == i.max) {
// arity=3
switch(rng.nextInt(4)) {
case 0:
return Int.the(i.min);
case 1:
return Int.range(i.min, i.min + 1);
case 2:
return Int.range(i.min + 1, i.min + 2);
case 3:
return Int.the(i.max);
default:
throw new UnsupportedOperationException();
}
} else {
int split = // midpoint, deterministic
(i.max + i.min) / 2;
// rng.nextInt(i.max-i.min-2);
return (rng.nextBoolean()) ? Int.range(i.min, split + 1) : Int.range(split + 1, i.max);
}
}
// cant drop int by itself
return Null;
}
if (!oo.in(SETi.bit | SETe.bit | SECTi.bit | SECTe.bit))
// returning the original value may cause feedback loop in callees expcting a change in value
return Null;
int size = t.subs();
switch(size) {
case 0:
assert (false) : "empty set impossible here";
return Null;
case 1:
return Null;
/* can't shrink below one element */
case 2:
int n = nar.random().nextInt(2);
return oo.the(t.sub(n));
default:
Term[] y = Terms.dropRandom(nar.random(), t.subterms());
return oo.the(y);
}
}));
/**
* depvar cleaning from commutive conj
*/
nar.on(Functor.f1((Atom) $.the("ifConjCommNoDepVars"), (Term t) -> {
if (!t.hasAny(VAR_DEP))
return t;
Op oo = t.op();
if (oo != CONJ)
return t;
SortedSet<Term> s = t.subterms().toSetSorted();
if (!s.removeIf(x -> x.unneg().op() == VAR_DEP))
return t;
return CONJ.the(t.dt(), s);
}));
/**
* drops a random contained event, whether at first layer or below
*/
nar.on(Functor.f1((Atom) $.the("dropAnyEvent"), (Term t) -> {
Op oo = t.op();
if (oo != CONJ)
// returning the original value may cause feedback loop in callees expcting a change in value
return Null;
FasterList<LongObjectPair<Term>> ee = Conj.eventList(t);
ee.remove(nar.random().nextInt(ee.size()));
return Conj.conj(ee);
// }
// if (r instanceof Variable /*&& r.op()!=VAR_DEP*/)
// return Null; //HACK dont allow returning a variable as an event during decomposition HACK TODO make more careful and return the only result if one subterm is a non-returnable variable
// return r;
}));
nar.on(Functor.f2((Atom) $.the("conjEvent"), (Term c, Term when) -> {
if (c.op() != CONJ || !(when instanceof Atom))
return Null;
// extract earliest or latest &| timeslice of events
throw new TODO();
// if (c.dt() == DTERNAL || c.dt() == 0) {
// return c.sub(nar.random().nextInt(c.subs())); //choose a subterm at random
// }
// assert (c.subs() == 2);
// int target;
// switch (when.toString()) {
// case "early":
// target = 0;
// break;
// case "late":
// target = 1;
// break;
// default:
// throw new UnsupportedOperationException();
// }
// if (c.dt() < 0)
// target = 1 - target;
// return c.sub(target);
}));
/**
* similar to without() but special handling for CONJ sub-events
*/
nar.on(Functor.f2((Atom) $.the("conjWithout"), (Term conj, Term event) -> {
if (conj.op() != CONJ || conj.impossibleSubTerm(event))
return Null;
FasterList<LongObjectPair<Term>> events = Conj.eventList(conj);
IntArrayList found = new IntArrayList(2);
int es = events.size();
assert (es > 1);
for (int i = 0; i < es; i++) {
if (event.equalsRoot(events.get(i).getTwo())) {
found.add(i);
}
}
int fs = found.size(), r;
switch(fs) {
case 0:
return Null;
case 1:
r = found.get(0);
break;
default:
r = found.get(nar.random().nextInt(fs));
break;
}
events.remove(r);
return Conj.conj(events);
// } else {
// return nullToNull(Op.without(conj, event::equalsRoot, nar.random()));
// }
}));
/**
* extracts only the events preceding the specified events
*/
nar.on(Functor.f2((Atom) $.the("conjDropIfLatest"), (Term conj, Term event) -> Conj.conjDrop(conj, event, false)));
nar.on(Functor.f2((Atom) $.the("conjDropIfEarliest"), (Term conj, Term event) -> Conj.conjDrop(conj, event, true)));
nar.on(Functor.f1Concept("belief", nar, (c, n) -> $.quote(n.belief(c, n.time()))));
nar.on(Functor.f1Concept("goal", nar, (c, n) -> $.quote(n.goal(c, n.time()))));
nar.on(f0("self", nar::self));
nar.on(Functor.f1("the", what -> {
if (what instanceof Atom) {
switch(what.toString()) {
case "sys":
return $.p($.quote(nar.emotion.summary()), $.quote(nar.concepts.summary()), $.quote(nar.emotion.summary()), $.quote(nar.exe.toString()));
}
}
Object x = nar.concept(what);
if (x == null)
x = what;
return $.quote($.p($.quote(x.getClass().toString()), $.quote(x.toString())));
}));
// /** slice(<compound>,<selector>)
// selector :-
// a specific integer value index, from 0 to compound size
// (a,b) pair of integers, a range of indices */
nar.on(Functor.f("slice", (args) -> {
if (args.subs() == 2) {
Term x = args.sub(0);
if (x.subs() > 0) {
int len = x.subs();
Term index = args.sub(1);
Op o = index.op();
if (o == INT) {
// specific index
int i = ((Int) index).id;
if (i >= 0 && i < len)
return x.sub(i);
else
return False;
} else if (o == PROD && index.subs() == 2) {
Term start = (index).sub(0);
if (start.op() == INT) {
Term end = (index).sub(1);
if (end.op() == INT) {
int si = ((Int) start).id;
if (si >= 0 && si < len) {
int ei = ((Int) end).id;
if (ei >= 0 && ei <= len) {
if (si == ei)
return Op.EmptyProduct;
if (si < ei) {
return $.p(Arrays.copyOfRange(x.subterms().arrayClone(), si, ei));
}
}
}
// TODO maybe reverse order will return reversed subproduct
return False;
}
}
}
}
}
return null;
}));
}
use of org.eclipse.collections.api.tuple.primitive.LongObjectPair in project narchy by automenta.
the class Revision method dtMergeConjEvents.
/**
* TODO handle common ending suffix, not just prefix
* TODO maybe merge based on the event separation time, preserving the order. currently this may shuffle the order though when events are relative to the sequence beginning this can makes sense
*/
private static Term dtMergeConjEvents(Term a, long bOffset, Term b, float aProp, float curDepth, boolean mergeOrChoose, Random rng, int dither) {
FasterList<LongObjectPair<Term>> ae = a.eventList(0, dither);
FasterList<LongObjectPair<Term>> be = b.eventList(bOffset, dither);
int as = ae.size();
int bs;
if (as != (bs = be.size())) {
int pnn = Math.min(as, bs);
int pn = pnn - 1;
FasterList<LongObjectPair<Term>> shorter = (as < bs) ? ae : be;
/* prefer the shorter for the reconstruction */
if (pn > 0) {
// decide forward or reverse
int matchesForward = 0, matchesReverse = 0;
for (int i = 0; i < pnn; i++) {
if (ae.get(i).getTwo().equals(be.get(i).getTwo()))
matchesForward++;
else
break;
}
if (matchesForward < pnn) {
for (int i = 0; i < pnn; i++) {
Term aa = ae.get((as - 1) - i).getTwo();
Term bb = be.get((bs - 1) - i).getTwo();
if (aa.equals(bb))
matchesReverse++;
else
break;
}
}
if (matchesForward > matchesReverse) {
Term prefix = conjMergeSeqEqualEvents(ae, be, aProp, mergeOrChoose, rng, pn, dither);
if (prefix == Null)
return Null;
Term suffix = Op.conjEternalize(shorter, pn, shorter.size());
if (suffix == Null)
return Null;
return mergeConjSeq(ae, be, pn, aProp, mergeOrChoose, rng, suffix, prefix, dither);
} else {
TreeSet<Term> ete = new TreeSet();
long lastA = 0, lastB = 0;
if (ae.size() != be.size()) {
boolean alarger = ae.size() > be.size();
FasterList<LongObjectPair<Term>> longer = alarger ? ae : be;
int toRemove = Math.abs(ae.size() - be.size());
for (int i = 0; i < toRemove; i++) {
LongObjectPair<Term> lr = longer.remove(0);
long lro = lr.getOne();
if (alarger)
lastA = Math.max(lastA, lro);
else
lastB = Math.max(lastB, lro);
ete.add(lr.getTwo());
}
assert (ae.size() == be.size());
}
while (ae.size() > matchesReverse) {
if (!ae.isEmpty()) {
LongObjectPair<Term> ar = ae.remove(0);
lastA = Math.max(lastA, ar.getOne());
ete.add(ar.getTwo());
}
if (!be.isEmpty()) {
LongObjectPair<Term> br = be.remove(0);
lastB = Math.max(lastB, br.getOne());
ete.add(br.getTwo());
}
}
Term prefix = CONJ.the(DTERNAL, ete);
if (prefix == Null)
return Null;
if (ae.isEmpty() && be.isEmpty()) {
return prefix;
} else {
Term suffix = conjMergeSeqEqualEvents(ae, be, aProp, mergeOrChoose, rng, ae.size(), dither);
if (suffix == Null)
return Null;
int ad = (int) (ae.get(0).getOne() - lastA);
int bd = (int) (be.get(0).getOne() - lastB);
int gap = gap(ad, bd, aProp, mergeOrChoose, rng);
return mergeConjSeq(prefix, suffix, gap, dither);
}
}
} else {
// entirely dternalize
return Op.conjEternalize(shorter, 0, shorter.size());
}
}
return conjMergeSeqEqualEvents(ae, be, aProp, mergeOrChoose, rng, as, dither);
// Map<Term,LongHashSet> events = new HashMap();
// a.eventseventsWhile((w,t)->{
// events.computeIfAbsent(t, (tt)->new LongHashSet()).add(w);
// return true;
// }, 0);
// FasterList<LongObjectPair<Term>> x = new FasterList(events.size());
// for (Map.Entry<Term, LongHashSet> e : events.entrySet()) {
// LongHashSet ww = e.getValue();
// int ws = ww.size();
// long w;
// if (ws == 1) {
// w = ww.longIterator().next();
// } else {
// if (mergeOrChoose) {
// //average
// //TODO more careful calculation here, maybe use BigDecimal in case of large numbers
// w = Math.round(((double)ww.sum()) / ws);
// } else {
// w = ww.toArray()[rng.nextInt(ws)];
// }
// }
// x.add(pair(w, e.getKey()));
// }
//
// //it may not be valid to choose subsets of the events, in a case like where >1 occurrences of $ must remain parent
// int max = 1 + x.size() / 2; //HALF
// int all = x.size();
// int excess = all - max;
// if (excess > 0) {
//
// //decide on some items to remove
// //must keep the endpoints unless a shift and adjustment are reported
// //to the callee which decides this for the revised task
//
// //for now just remove some inner tasks
// if (all - excess < 2)
// return null; //retain the endpoints
// else if (all - excess == 2)
// x = new FasterList(2).addingAll(x.get(0), x.get(all - 1)); //retain only the endpoints
// else {
// for (int i = 0; i < excess; i++) {
// x.remove(rng.nextInt(x.size() - 2) + 1);
// }
// }
// }
// return Op.conjEvents(x);
}
use of org.eclipse.collections.api.tuple.primitive.LongObjectPair in project narchy by automenta.
the class Conj method term.
// private byte id(long w) {
//
// int i = times.indexOf(w);
// if (i!=-1) {
// return (byte) i;
// } else {
// int s = times.size();
// assert(s < Byte.MAX_VALUE);
// times.add(w);
// return (byte)s;
// }
// }
//
// short id(Term t, long w) {
// byte tb = id(t);
// byte wb = id(w);
// return (short) ((tb << 8) | wb);
// }
//
// byte termIndex(short s) {
// return (byte) ((s >> 8) & 0xff);
// }
// byte timeIndex(short s) {
// return (byte) (s & 0xff);
// }
public Term term() {
if (term != null)
return term;
int numTimes = event.size();
switch(numTimes) {
case 0:
return Null;
case 1:
break;
default:
break;
}
event.compact();
IntPredicate validator = null;
Object eternalWhat = event.get(ETERNAL);
Term eternal = term(ETERNAL, eternalWhat);
if (eternal != null) {
if (eternal instanceof Bool)
// override and terminates
return this.term = eternal;
if (numTimes > 1) {
if (eternal.op() == CONJ) {
// Subterms eteSub = eternal.subterms();
if (eternalWhat instanceof byte[]) {
byte[] b = (byte[]) eternalWhat;
validator = (i) -> indexOfZeroTerminated(b, (byte) -i) == -1;
} else {
RoaringBitmap b = (RoaringBitmap) eternalWhat;
validator = (i) -> !b.contains(-i);
}
} else {
Term finalEternal = eternal;
validator = (t) -> !finalEternal.equalsNeg(termsIndex.get(Math.abs(t - 1)).negIf(t < 0));
}
}
}
if (eternal != null && numTimes == 1)
// done
return eternal;
FasterList<LongObjectPair<Term>> e = new FasterList(numTimes - (eternal != null ? 1 : 0));
Iterator<LongObjectPair> ii = event.keyValuesView().iterator();
while (ii.hasNext()) {
LongObjectPair next = ii.next();
long when = next.getOne();
if (when == ETERNAL)
// already handled above
continue;
Term wt = term(when, next.getTwo(), validator);
if (wt == True) {
// canceled out
continue;
} else if (wt == False) {
// short-circuit false
return this.term = False;
} else if (wt == Null) {
// short-circuit null
return this.term = Null;
}
e.add(pair(when, wt));
}
assert (!e.isEmpty());
Term temporal;
if (e.size() > 1) {
e.sortThisBy(LongObjectPair::getOne);
temporal = conjSeq(e);
if (temporal instanceof Bool)
return temporal;
} else {
temporal = e.get(0).getTwo();
}
return eternal != null ? // Op.instance(CONJ, DTERNAL, sorted(eternal, temporal))
CONJ.the(DTERNAL, sorted(eternal, temporal)) : temporal;
}
use of org.eclipse.collections.api.tuple.primitive.LongObjectPair in project narchy by automenta.
the class TimeGraph method solveDT.
boolean solveDT(Term x, Predicate<Event> each) {
assert (x.dt() == XTERNAL);
Subterms xx = x.subterms();
// FasterList<Event> events = new FasterList<>(byTerm.get(x.root()));
// for (int i = 0, eventsSize = events.size(); i < eventsSize; i++) {
// Event r = events.get(i);
// if (r instanceof Absolute) {
// if (r.id.subterms().equals(xx)) {
// if (!each.test(r))
// return false; //done
// }
// }
//
// }
int subs = xx.subs();
if (subs == 2) {
Term a = xx.sub(0);
Term b = xx.sub(1);
boolean aEqB = a.equals(b);
if (!a.hasXternal() && !b.hasXternal() && (aEqB || !commonSubEventsWithMultipleOccurrences(a, b))) {
UnifiedSet<Event> ae = new UnifiedSet(2);
solveOccurrence(event(a, TIMELESS), ax -> {
if (ax instanceof Absolute)
ae.add(ax);
return true;
});
int aes = ae.size();
if (aes > 0) {
if (aEqB) {
// same term, must have >1 absolute timepoints
if (aes > 1) {
Event[] ab = ae.toArray(new Event[aes]);
// Arrays.sort(ab, Comparator.comparingLong(Event::when));
for (int i = 0; i < ab.length; i++) {
Event abi = ab[i];
for (int j = 0; j < ab.length; j++) {
if (i == j)
continue;
if (!solveDT(x, abi.when(), dt(x, abi, ab[j]), each))
return false;
}
}
}
} else {
UnifiedSet<Event> be = new UnifiedSet(2);
solveOccurrence(event(b, TIMELESS), bx -> {
if (bx instanceof Absolute)
be.add(bx);
return true;
});
int bes = be.size();
if (bes > 0) {
// if (aes == 1 || bes == 1) {
if (!ae.allSatisfy(ax -> be.allSatisfyWith((bx, axx) -> solveDT(x, axx.when(), dt(x, axx, bx), each), ax)))
return false;
// }
}
}
}
}
// UnifiedSet<Event>[] abs = new UnifiedSet[2]; //exact occurrences of each subterm
FasterList<Event> rels = new FasterList<>(4);
// int[] phase = new int[]{0};
// int p = phase[0];
// if (z instanceof Absolute) {
// if (abs[p] == null) abs[p] = new UnifiedSet(2);
// abs[p].add(z);
// //}
// }
Consumer<Event> collect = rels::add;
byTerm.get(a).forEach(collect);
if (aEqB) {
// abs[1] = abs[0];
} else {
// phase[0] = 1;
byTerm.get(b).forEach(collect);
// if (abs[1] == null)
// byTerm.get(b.neg()).forEach(collect); //if nothing, look for negations
}
// if (abs[0] != null && abs[1] != null) {
// known exact occurrences for both subterms
// iterate all possibilities
// TODO order in some way
// TODO other simple cases: 1 -> N
// if (abs[0].size() == 1 && abs[1].size() == 1) {
// //simple case:
// Event aa = abs[0].iterator().next();
// Event bb = abs[1].iterator().next();
// if (!solveDT(x, each, aa, bb))
// return false;
// } else {
// if (!abs[0].allSatisfy(ae ->
// abs[1].allSatisfyWith((be, aaee) ->
// solveDT(x, each, aaee, be), ae)))
// return false;
// }
// }
int ns = rels.size();
if (ns > 0) {
if (ns > 1) {
// sort by volume
rels.sortThisByInt(s -> s.id.volume());
}
return bfs(rels, new CrossTimeSolver() {
@Override
protected boolean next(BooleanObjectPair<ImmutableDirectedEdge<Event, TimeSpan>> move, Node<nars.derive.time.TimeGraph.Event, nars.derive.time.TimeGraph.TimeSpan> next) {
// System.out.println(path);
long[] startDT = pathDT(next, a, b, path);
if (startDT == null)
// nothing at this step
return true;
long start = startDT[0];
long ddt = startDT[1];
return TimeGraph.this.solveDT(x, start, ddt, each);
}
});
}
// } else {
// assert (x.op() == CONJ);
// List<LongObjectPair<Term>> when = $.newArrayList();
// for (int ix = 0; ix < subs; ix++) {
// //assert(!z.hasXternal());
// solveOccurrence(event(xx.sub(ix), TIMELESS), (ze) -> {
// if (ze.when() == TIMELESS)
// return true; //keep trying
// when.add(pair(ze.when(), ze.id));
// return false; //just one, for now //TODO see if there are any others
// });
// }
// if (when.size() == subs) {
// when.sort(Comparator.comparingLong(LongObjectPair::getOne));
// long base = when.get(0).getOne();
// Term zz = when.get(0).getTwo();
// for (int i = 1; i < subs; i++) {
// LongObjectPair<Term> wgi = when.get(i);
// zz = Op.conjMerge(zz, 0, wgi.getTwo(), wgi.getOne() - base);
// if (zz instanceof Bool)
// return true; //failure
// }
// return each.test(event(zz, base));
// }
}
// last resort
return each.test(event(x, TIMELESS));
}
Aggregations