Warning: session_start(): open(/var/lib/php/sessions/sess_ofj7eqicf7nb0h3mf9a440gg3p, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
// B is the type of object we handle.
sclass TransformersOnObjects implements Steppable {
replace Trail with O.
// using the oldschool type F1 here because it's a bit easier to handle
new AllOnAll_probabilistic allOnAll;
new Set bs;
new MultiSetMap trails;
new Map backTransformers; // reverse of each transformer
new Map probabilities;
transient bool verboseAddObject = true;
transient new ThreadLocal currentProbability;
srecord TransformationTrail(O transformer, O argument) {
toString { ret squareBracket(str(transformer)) + " on " + squareBracket(str(argument)); }
}
// If this is true and a transformer returns an Iterable,
// we unpack it and discard the Iterable.
bool autoUnpackIterables = true;
// make a trail for each transformer application
bool autoTrails = true;
// keep multiple trails per object
bool allowMultipleTrails = true;
AllOnAllOperation op = new(allOnAll,
(a, b) -> {
if (!functionCallableOn_nonSynthetic(a, b)) ret;
temp tempSetTL(currentProbability, getProbability(a)*getProbability(b));
O out = callFOpt(a, b);
O trail = autoTrails ? makeTrailForTransformerApplication(a, b) : null;
if (out == null) ret;
if (out instanceof WithProbability) {
lowerCurrentProbability(((WithProbability) out).probability);
out = ((WithProbability) out)!;
if (out == null) ret;
}
if (autoUnpackIterables && out instanceof Iterable) // don't use this anymore
for (O x : (Iterable) out) addObject((B) x, trail);
else
addObject((B) out, trail);
});
*() {
allOnAll.probabilityForPair = (a, b) -> getProbability(a) * getProbability(b);
}
bool add(B b) { ret addObject(b); }
bool addObject(B b) {
if (!addIfNotNull(bs, b)) false;
double prob = or(currentProbability!, 1.0);
if (verboseAddObject) print("Added: " + WithProbability(prob, sfu(b)));
allOnAll.addB(b);
true;
}
void addObject(B b, O trail) {
if (b == null) ret;
add(b);
if (trail != null && (allowMultipleTrails || !trails.containsKey(b)))
trails.put(b, trail);
}
void addTransformer(F1 f) {
allOnAll.addA(f);
}
// simple backtransformer only taking the transformed object
void addTransformer(F1 f, F1 backTransformer) {
addTransformer(f, backTransformer == null ? null
: new IF2 {
public O get(O in, O out) { ret callFIfActuallyCallable(backTransformer, out); }
toString { ret str(backTransformer); }
});
}
// complex backtransformer taking the original and the transformed object
void addTransformer(F1 f, IF2 backTransformer) {
addTransformer(f);
mapPut(backTransformers, f, backTransformer);
}
void addTransformer(F2 f) {
addTransformer(func(O a) {
addTransformer(func(O b) {
callableOn_nonSynthetic(f, "get", a, b) ? f.get(a, b) : null
});
null;
});
}
public bool step() { ret op.step(); }
L getObjects() { ret allOnAll.getBs(); }
O makeTrailForTransformerApplication(O transformer, B argument) {
ret new TransformationTrail(transformer, argument);
}
void printWithTrails() {
pnlMap(getObjects(), b -> {
Set _trails = trails.get(b);
ret sfu(b) + (empty(_trails) ? ""
: " [" + nTrails(_trails) + ": " + joinWithComma(_trails) + "]");
});
}
// only returns the actual TransformationTrails
Cl getTrails(B b) {
ret instancesOf TransformationTrail(trails.get(b));
}
Cl getTrailsBy(B b, O transformer) {
ret filter(getTrails(b), t -> eq(((TransformationTrail) t).transformer, transformer));
}
TransformationTrail getTrailBy(B b, O transformer) {
ret firstThat(getTrails(b), t -> eq(((TransformationTrail) t).transformer, transformer));
}
IF2 getBackTransformer(O transformer) {
ret backTransformers.get(transformer);
}
void printTransformers() {
pnl(allOnAll.getAs());
}
double getProbability(O o) {
ret or(probabilities.get(o), 1.0);
}
// Note: works only for transformers that are not rewritten by the addTransformer method
// Works for all objects
A setProbability(A o, double p) {
if (o == null) null;
Double pOld = probabilities.get(p);
if (pOld != null) {
if (p == 1.0)
probabilities.remove(o);
else if (pOld.doubleValue() != p)
probabilities.put(o, p);
} else if (p != 1.0)
probabilities.put(o, p);
ret o;
}
void lowerCurrentProbability(double p) {
currentProbability.set(currentProbability! * p);
}
}