use of nars.subterm.Subterms in project narchy by automenta.
the class Compound method unifySubterms.
default boolean unifySubterms(Term ty, Unify u) {
Subterms xsubs = subterms();
Subterms ysubs = ty.subterms();
int xs;
if ((xs = xsubs.subs()) != ysubs.subs())
return false;
if (xs > 1 && isCommutative()) {
return xsubs.unifyCommute(ysubs, u);
} else {
// do not do a fast termcontainer test unless it's linear; in commutive mode we want to allow permutations even if they are initially equal
return xsubs.unifyLinear(ysubs, u);
}
// if (op.temporal) {
// int sdur = subst.dur;
// if (sdur >= 0) {
// if (!matchTemporalDT(this, y, sdur))
// return false;
// }
// }
/*if (op() == CONJ) { //non-commutive, temporal CONJ
return TermContainer.unifyConj(xsubs, dt(), ysubs, y.dt(), u);
} else */
}
use of nars.subterm.Subterms in project narchy by automenta.
the class Compound method evalSafe.
/*@NotNull*/
@Override
default Term evalSafe(TermContext context, Op supertermOp, int subterm, int remain) {
if (remain-- <= 0)
return Null;
// Termed ff = context.applyIfPossible(this);
// if (!ff.equals(this))
// return ff.term();
/*if (subterms().hasAll(opBits))*/
Subterms uu = subterms();
Term[] xy = null;
// any contained evaluables
Op o = op();
// int possiblyFunctional = o == INH ? Op.funcInnerBits : Op.funcBits;
// boolean recurseIfChanged = false;
int ellipsisAdds = 0, ellipsisRemoves = 0;
for (int i = 0, n = uu.subs(); i < n; i++) {
Term xi = xy != null ? xy[i] : uu.sub(i);
Term yi = xi.evalSafe(context, o, i, remain);
if (yi == null) {
return Null;
} else {
if (yi instanceof EllipsisMatch) {
int ys = yi.subs();
ellipsisAdds += ys;
ellipsisRemoves++;
}
if (xi != yi && (xi.getClass() != yi.getClass() || !xi.equals(yi))) {
if (xy == null) {
// begin clone copy
xy = arrayClone();
}
xy[i] = yi;
}
}
}
if (ellipsisAdds > 0) {
// flatten ellipsis
xy = EllipsisMatch.flatten(xy, ellipsisAdds, ellipsisRemoves);
}
Term u;
if (/*changed*/
xy != null) {
u = o.a(dt(), xy);
// refresh root operator in case it has changed
o = u.op();
// refresh subterms
uu = u.subterms();
} else {
u = this;
}
// compute this without necessarily constructing the superterm, which happens after this if it doesnt recurse
if (o == INH && u.hasAll(Op.funcBits)) {
Term pred, subj;
if ((pred = uu.sub(1)) instanceof Functor && (subj = uu.sub(0)).op() == PROD) {
Term v = ((Functor) pred).apply(subj.subterms());
if (v instanceof AbstractPred) {
u = $.the(((AbstractPred) v).test(null));
} else if (v == null) {
// null means to keep 'u' unchanged same
} else {
// continue with the evaluation result
u = v;
}
}
}
if (u != this && (u.equals(this) && u.getClass() == getClass()))
// return to this instance, undoing any substitutions necessary to reach this eval
u = this;
return u;
}
use of nars.subterm.Subterms in project narchy by automenta.
the class Compound method eventsWhile.
// @Override
// default boolean equalsIgnoringVariables(/*@NotNull*/ Term other, boolean requireSameTime) {
// if (other instanceof Variable)
// return true;
//
// // if (op() == NEG)
// // throw new UnsupportedOperationException("left hand side should already be unneg'd");
// //
// // if (other.op()==NEG)
// // other = other.unneg();
//
// Op op = op();
// if (!(other.op() == op))
// return false;
//
// int s = size();
//
// if (other.size() == s) {
//
// if (requireSameTime)
// if (((Compound) other).dt() != dt())
// return false;
//
// Compound o = (Compound) other;
// Term[] a = toArray();
// Term[] b = o.toArray();
// for (int i = 0; i < s; i++) {
// if (!a[i].equalsIgnoringVariables(b[i], requireSameTime))
// return false;
// }
// return true;
// }
// return false;
// }
/* collects any contained events within a conjunction*/
@Override
default boolean eventsWhile(LongObjectPredicate<Term> events, long offset, boolean decomposeConjParallel, boolean decomposeConjDTernal, boolean decomposeXternal, int level) {
Op o = op();
if (o == CONJ) {
int dt = dt();
if ((decomposeConjDTernal || dt != DTERNAL) && (decomposeConjParallel || dt != 0) && (decomposeXternal || dt != XTERNAL)) {
if (dt == DTERNAL)
dt = 0;
else if (// HACK
dt == XTERNAL)
dt = 0;
Subterms tt = subterms();
int s = tt.subs();
long t = offset;
boolean changeDT = t != ETERNAL && t != TIMELESS;
level++;
if (dt >= 0) {
// forward
for (int i = 0; i < s; i++) {
Term st = tt.sub(i);
if (!st.eventsWhile(events, t, decomposeConjParallel, decomposeConjDTernal, decomposeXternal, // recurse
level))
return false;
if (changeDT)
t += dt + st.dtRange();
}
} else {
// reverse
for (int i = s - 1; i >= 0; i--) {
Term st = tt.sub(i);
if (!st.eventsWhile(events, t, decomposeConjParallel, decomposeConjDTernal, decomposeXternal, // recurse
level))
return false;
if (changeDT)
t += -dt + st.dtRange();
}
}
return true;
}
}
return events.accept(offset, this);
}
use of nars.subterm.Subterms in project narchy by automenta.
the class Compound method subTimeSafe.
/**
* TODO do shuffled search to return different repeated results wherever they may appear
*/
@Override
default int subTimeSafe(Term x, int after) {
if (equals(x))
return 0;
Op op = op();
if (op != CONJ)
return DTERNAL;
int dt = dt();
if (// unknown
dt == XTERNAL)
return DTERNAL;
if (impossibleSubTerm(x))
return DTERNAL;
/*@NotNull*/
Subterms yy = subterms();
/*} else */
if (op == CONJ) {
/* HACK apply to other cases too */
if (after >= dt) {
Term yy1 = yy.sub(1);
if (yy.sub(0).equals(yy1)) {
// return yy.sub(1).subTimeSafe(x, after - dt) + dt;
if (x.equals(yy1))
return dt;
}
}
boolean reverse;
int idt;
if (dt == DTERNAL || dt == 0) {
// parallel or eternal, no dt increment
idt = 0;
reverse = false;
} else {
idt = dt;
if (idt < 0) {
idt = -idt;
reverse = true;
} else {
reverse = false;
}
}
int ys = yy.subs();
int offset = 0;
for (int yi = 0; yi < ys; yi++) {
Term yyy = yy.sub(reverse ? ((ys - 1) - yi) : yi);
int sdt = yyy.subTimeSafe(x, after - offset);
if (sdt != DTERNAL)
return sdt + offset;
offset += idt + yyy.dtRange();
}
}
return DTERNAL;
}
use of nars.subterm.Subterms in project narchy by automenta.
the class Term method transform.
@Nullable
default Term transform(/*@NotNull*/
ByteList path, int depth, Term replacement) {
final Term src = this;
int ps = path.size();
if (ps == depth)
return replacement;
if (ps < depth)
throw new RuntimeException("path overflow");
if (!(src instanceof Compound))
// path wont continue inside an atom
return src;
Compound csrc = (Compound) src;
Subterms css = csrc.subterms();
int n = css.subs();
if (n == 0)
return src;
Term[] target = new Term[n];
for (int i = 0; i < n; i++) {
Term x = css.sub(i);
if (path.get(depth) != i)
// unchanged subtree
target[i] = x;
else {
// replacement is in this subtree
target[i] = x.subs() == 0 ? replacement : x.transform(path, depth + 1, replacement);
}
}
return csrc.op().the(csrc.dt(), target);
}
Aggregations