use of nars.truth.PreciseTruth in project narchy by automenta.
the class NAR method input.
public Task input(float pri, Term term, byte punc, long start, long end, float freq, float conf) throws InvalidTaskException {
PreciseTruth tr = Truth.theDithered(freq, c2w(conf), this);
@Nullable Task z = Task.tryTask(term, punc, tr, (c, truth) -> {
Task y = new NALTask(c, punc, truth, time(), start, end, new long[] { time.nextStamp() });
y.priSet(pri);
return y;
}, false);
input(z);
return z;
}
use of nars.truth.PreciseTruth in project narchy by automenta.
the class NAct method actionBipolarFrequencyDifferential.
default GoalActionAsyncConcept[] actionBipolarFrequencyDifferential(@NotNull Term s, boolean fair, boolean latchPreviousIfUndecided, @NotNull FloatToFloatFunction update) {
Term pt = // $.p(s, PLUS);
$.inh(s, PLUS);
// $.prop(s,PLUS);
// $.p(s, ZeroProduct);
// $.p(s,$.the("\"+\""));
Term nt = // $.p(s, NEG);
$.inh(s, NEG);
// $.prop(s, NEG);
// $.p(ZeroProduct, s);
// $.p(s,$.the("\"-\""));
final float[] g = new float[2];
final float[] c = new float[2];
final long[] lastUpdate = { ETERNAL };
final float[] lastX = { 0 };
// hack
GoalActionAsyncConcept[] CC = new GoalActionAsyncConcept[2];
@NotNull BiConsumer<GoalActionAsyncConcept, Truth> u = (action, gg) -> {
NAR n = nar();
long now = n.time();
if (now != lastUpdate[0]) {
lastUpdate[0] = now;
// reset
CC[0] = CC[1] = null;
}
// float freqEps = n.freqResolution.floatValue();
float confMin = n.confMin.floatValue();
// float eviMin = c2wSafe(confMin);
float feedbackConf = // fairly shared to sum to default
w2c(c2w(n.confDefault(BELIEF)) / 2f);
// n.confDefault(BELIEF);
// n.confDefault(GOAL);
// confMin * ...;
boolean p = action.term().equals(pt);
int ip = p ? 0 : 1;
CC[ip] = action;
g[ip] = gg != null ? // gg.freq()
gg.expectation() : 0f;
// 0.5f;
c[ip] = gg != null ? // gg.evi()
gg.conf() : 0f;
// -1..+1
float x;
boolean curious;
if (CC[0] != null && CC[1] != null) /* both ready */
{
float cMax = Math.max(c[0], c[1]);
float cMin = Math.min(c[0], c[1]);
float coherence = cMin / cMax;
Random rng = n.random();
float cur = curiosity().floatValue();
if (cur > 0 && rng.nextFloat() <= cur) {
x = (rng.nextFloat() - 0.5f) * 2f;
// float curiEvi =
// //c2w(n.confDefault(BELIEF));
// //eviMin*2;
// Math.max(c2wSafe(w2cSafe(eviMin)*2), Util.mean(c[0], c[1])); //match desire conf, min=2*minConf
c[0] = c[1] = feedbackConf;
coherence = 1f;
curious = true;
} else {
curious = false;
if (cMax < confMin) {
if (latchPreviousIfUndecided) {
x = lastX[0];
} else {
x = 0;
}
} else {
// //expectation
// float g0 = g[0]-0.5f;
// float g1 = g[1]-0.5f;
// df = 2f * ((g0) - (g1));
// // /Math.max(Math.abs(g0), Math.abs(g1));
// frequency -======================
// A. subtraction
// subtract
x = ((g[0] - g[1]));
// experimental: lessen by a factor of how equally confident each goal is
if (fair) {
// fully fair
x *= coherence;
// x *= Math.sqrt(coherence); //less sharp than linear
// semi-fair
// df *= 0.5f + 0.5f * (eMin / eMax); //reduction by at most half
}
// df *= 1f - Math.abs(e[0] - e[1]) / eMax;
// df *= Util.sqr(eMin / eMax); //more cautious
// df *= Math.min(w2cSafe(e[0]), w2cSafe(e[1])) / w2cSafe(eMax);
}
}
x = Util.clamp(x, -1f, +1f);
lastX[0] = x;
// -1..+1
float y = update.valueOf(x);
// System.out.println(x + " " + y);
// w2c(Math.abs(y) * c2w(restConf));
PreciseTruth Nb, Ng, Pb, Pg;
if (y == y) {
// y: (-1..+1)
float yp, yn;
if (Math.abs(y) >= n.freqResolution.floatValue()) {
yp = 0.5f + y / 2f;
yn = 1f - yp;
} else {
yp = yn = 0.5f;
}
// float yp = 0.5f + y/2f;
// float yn = 1f - yp;
float pbf = yp;
float nbf = yn;
Pb = $.t(pbf, feedbackConf);
Nb = $.t(nbf, feedbackConf);
// float goalEvi =
// eviMin;
// //max(eviMin, max(e[0], e[1]));
// Pg = curious || e[0] == 0 ? new PreciseTruth(yp, goalEvi, false) : null;
// Ng = curious || e[1] == 0 ? new PreciseTruth(yn, goalEvi, false) : null;
// float confBase = confMin*4; //~ alpha, learning rate
// float fThresh = Float.MIN_NORMAL;
// float yp = y > +fThresh ? Util.lerp(+y, confBase, feedbackConf) : confBase;
// float yn = y < -fThresh ? Util.lerp(-y, confBase, feedbackConf) : confBase;
// Pb = $.t(y > +fThresh ? 1 : 0, y > +fThresh ? yp : feedbackConf - yp);
// Nb = $.t(y < -fThresh ? 1 : 0, y < -fThresh ? yn : feedbackConf - yn);
// //Pg = curious || e[0] == 0 ? new PreciseTruth(1, Util.lerp(+y, confMin2, feedbackConf)) : null;
// Pg = null;
// //Ng = curious || e[1] == 0 ? new PreciseTruth(1, Util.lerp(-y, confMin2, feedbackConf)) : null;
// Ng = null;
// float fThresh = nar().freqResolution.floatValue();
// int sign = (y > fThresh ? +1 : (y < -fThresh ? -1 : 0));
//
// float feedConf =
// w2cSafe(c2wSafe(goalConf)/2f); //half/half
// //goalConf;
// //Math.max(confMin, goalConf * coherence);
// switch (sign) {
// case +1:
// //Pb = $.t(1f, Util.lerp(+y, confBase, feedbackConf));
// Pb = $.t(y/2f + 0.5f, feedConf);
// Nb =
// //null;
// $.t(0, feedConf);
// break;
// case -1:
// Pb =
// //null;
// $.t(0, feedConf);
//
// Nb = $.t(-y/2f + 0.5f, feedConf);
// break;
// case 0:
// //Pb = Nb = null; //no signal
// Pb = Nb = $.t(0, feedConf);
// //Math.max(confMin, feedConf);
// //w2cSafe(c2wSafe(feedConf)/2f))); //zero
// break;
// default:
// throw new UnsupportedOperationException();
// }
Pg = null;
Ng = null;
// if (curious) {
// e[0] = e[1] = 0; //reset to get full evidence override
// }
// float g0 = eviMax - e[0];
// Pg = g0 >= eviMin ? new PreciseTruth(yp, g0, false) : null;
// float g1 = eviMax - e[1];
// Ng = g1 >= eviMin ? new PreciseTruth(yn, g1, false) : null;
} else {
Pb = Nb = Pg = Ng = null;
}
// System.out.println(Pb + "," + Nb + " <- " + g[0] + ";" + c[0] + ", " + g[1] + ';' + c[1]);
CC[0].feedback(Pb, Pg, n);
CC[1].feedback(Nb, Ng, n);
}
};
CauseChannel<ITask> cause = nar().newCauseChannel(s);
GoalActionAsyncConcept p = new GoalActionAsyncConcept(pt, this, cause, u);
GoalActionAsyncConcept n = new GoalActionAsyncConcept(nt, this, cause, u);
addAction(p);
addAction(n);
nar().believe($.inh(s, SECTe.the(PLUS, NEG)).neg(), Tense.Eternal);
CC[0] = p;
CC[1] = n;
return CC;
}
use of nars.truth.PreciseTruth in project narchy by automenta.
the class EternalTable method tryRevision.
/**
* @return null: no revision could be applied
* ==newBelief: existing duplicate found
* non-null: revised task
*/
@Nullable
private /*Revision*/
Task tryRevision(/*@NotNull*/
Task y, /* input */
@Nullable NAR nar) {
Object[] list = this.list;
int bsize = list.length;
if (bsize == 0)
// nothing to revise with
return null;
// Try to select a best revision partner from existing beliefs:
Task oldBelief = null;
Truth conclusion = null;
Truth newBeliefTruth = y.truth();
for (int i = 0; i < bsize; i++) {
Task x = (Task) list[i];
if (// the array has trailing nulls from having extra capacity
x == null)
break;
if (x.equals(y)) {
/*if (x!=y && x.isInput())
throw new RuntimeException("different input task instances with same stamp");*/
return x;
}
// same conf, same stamp, both non-cyclic; interpolate to avoid one being preferred over another arbitrarily
float xconf = x.conf();
if (Util.equals(xconf, y.conf(), nar.confResolution.floatValue()) && (!x.isCyclic() && !y.isCyclic()) && Arrays.equals(x.stamp(), y.stamp())) {
conclusion = new PreciseTruth(0.5f * (x.freq() + y.freq()), xconf);
} else if (Stamp.overlapping(y, x)) {
boolean FILTER_WEAKER_BUT_EQUAL = false;
if (FILTER_WEAKER_BUT_EQUAL && !y.isInput() && xconf >= y.conf() && Util.equals(x.freq(), y.freq(), nar.freqResolution.floatValue()) && Arrays.equals(y.stamp(), x.stamp())) {
y.delete();
// subsume by stronger belief with same freq and stamp
return null;
}
// unrevisable
continue;
} else {
//
// float factor = tRel * freqMatch;
// if (factor < best) {
// //even with conf=1.0 it wouldnt be enough to exceed existing best match
// continue;
// }
// float minValidConf = Math.min(newBeliefConf, x.conf());
// if (minValidConf < bestConf) continue;
// float minValidRank = BeliefTable.rankEternalByOriginality(minValidConf, totalEvidence);
// if (minValidRank < bestRank) continue;
Truth xt = x.truth();
// TODO use overlappingFraction?
Truth yt = Revision.revise(newBeliefTruth, xt, 1f, conclusion == null ? 0 : conclusion.evi());
if (yt == null)
continue;
yt = yt.dither(nar);
if (// //avoid a weak or duplicate truth
yt == null || yt.equals(xt, nar) || yt.equals(newBeliefTruth, nar))
continue;
conclusion = yt;
}
oldBelief = x;
}
if (oldBelief == null)
return null;
final float newBeliefWeight = y.evi();
// TODO use Task.tryContent in building the task:
float aProp = newBeliefWeight / (newBeliefWeight + oldBelief.evi());
Term t = Revision.intermpolate(y.term(), oldBelief.term(), aProp, nar);
Task prevBelief = oldBelief;
Task x = Task.tryTask(t, y.punc(), conclusion, (term, revisionTruth) -> new NALTask(term, y.punc(), revisionTruth, nar.time(), /* creation time */
ETERNAL, ETERNAL, Stamp.zip(prevBelief.stamp(), y.stamp(), 0.5f)));
if (x != null) {
x.priSet(Priority.fund(Math.max(prevBelief.priElseZero(), y.priElseZero()), false, prevBelief, y));
((NALTask) x).cause = Cause.sample(Param.causeCapacity.intValue(), y, prevBelief);
if (Param.DEBUG)
x.log("Insertion Revision");
// ((NALTask)y).meta("@",x);
// ((NALTask)prevBelief).meta("@",x);
}
return x;
}
use of nars.truth.PreciseTruth in project narchy by automenta.
the class Revision method revise.
@Nullable
public static Truth revise(/*@NotNull*/
Truthed a, /*@NotNull*/
Truthed b, float factor, float minEvi) {
float ae = a.evi();
float be = b.evi();
float w = ae + be;
float e = w * factor;
return e <= minEvi ? null : new PreciseTruth((ae * a.freq() + be * b.freq()) / w, e, false);
}
use of nars.truth.PreciseTruth in project narchy by automenta.
the class TruthPolation method truth.
public Truth truth(boolean filterCyclic) /*float eviFactor, float eviMin*/
{
if (isEmpty())
return null;
// project temporally, removing if no evidence provided
{
removeIf(tc -> {
Task t = tc.task;
Truth tt = t.truth(start, end, dur, Truth.EVI_MIN);
if (tt != null) {
// not necessarily the task's reported "average" freq in case of Truthlets
tc.freq = tt.freq();
tc.evi = tt.evi();
return false;
} else {
// removed
return true;
}
});
}
// remove overlapping evidence, preferring the strongest contributors of each
if (filterCyclic) {
int s = size();
if (s == 0)
return null;
else if (s > 1) {
// descending by strength
sortThisByFloat(tc -> -tc.evi);
// TODO maybe factor in originality to reduce overlap so evidence can be combined better
// remove the weaker holder of any overlapping evidence
LongHashSet e = new LongHashSet(s * 2);
removeIf(tc -> {
long[] stamp = tc.task.stamp();
for (long ss : stamp) {
if (!e.add(ss))
// overlap
return true;
}
return false;
});
}
}
{
int s = size();
switch(s) {
case 0:
return null;
case 1:
{
TaskComponent only = get(0);
return new PreciseTruth(only.freq, only.evi, false);
}
default:
{
// interpolate
// float eviSum = 0, confSum = 0, wFreqSum = 0;
float eviSum = 0, wFreqSum = 0;
for (int i = 0, thisSize = this.size(); i < thisSize; i++) {
TaskComponent x = this.get(i);
float ee = x.evi;
eviSum += ee;
// float ce = w2cSafe(ee);
// confSum += ce;
// wFreqSum += ce * x.freq;
wFreqSum += ee * x.freq;
}
assert (Float.isFinite(eviSum));
float c = w2cSafe(eviSum);
if (c < Param.TRUTH_EPSILON)
return null;
else {
// float f = (wFreqSum / confSum);
float f = (wFreqSum / eviSum);
return new PreciseTruth(f, c);
}
}
}
}
}
Aggregations