Warning: session_start(): open(/var/lib/php/sessions/sess_g5fjchcdlsn2vl45u09j7d3rlc, 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
cmodule AModule {
switchable S input = "STATICALAFLATTENLISTOFPAIRSLPAIRALLAOUTEMPTYLISTLLFORPAIRAPUNNULLLOUTADDPAOUTADDPBRETOUT";
switchable S words = "ret ll ls static out list pair null";
// basically immutable (we make a new copy for every step)
// to allow evaluating states in parallel and in any order
class GreedySplitIntoWordsCI_Multi implements IF0, LS>> {
S s; // the input to be split
TreeSet wordsSet;
int i = 0, last = 0;
ReverseChain out;
*() {}
*(S *s, Cl words) { wordsSet = asCISet(words); }
// either we return some choices or a final result
Either, LS> get() {
int longestMatch = l(longestPrefixInCISet(substring(s, i), wordsSet));
print("longestMatch at " + i + ": " + longestMatch);
if (longestMatch == 0) { // also true when we're at end of string
flush();
ret eitherB(asList(out));
}
ret eitherA(mapNonNulls(countBackwardsTo1(longestMatch), matchLength -> {
if (!contains(wordsSet, substring(s, i, i+matchLength))) null;
GreedySplitIntoWordsCI_Multi clone = shallowClone(this, new GreedySplitIntoWordsCI_Multi);
clone.i = clone.last = i+longestMatch;
clone.out = revChainPlus(out, substring(s, i, clone.i));
ret clone;
}));
}
void flush {
if (i > last) {
// modifying this object in spite of convention
out = revChainPlus(out, substring(s, last, i));
last = i;
}
}
toString { ret "last word " + quote(last(out)) + ", " + i + "/" + l(s); }
}
visual jDynamicTree(
new GreedySplitIntoWordsCI_Multi(input, splitAtSpace(words))!,
x -> getVars(eitherAOpt(x)));
}