Warning: session_start(): open(/var/lib/php/sessions/sess_thj6ifvo3rr51962k9rti989f1, 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
srecord noeq G22MeshMapper_v2(G22Mesh mesh1, G22Mesh mesh2) {
// import the important classes
delegate Anchor, Curve to G22Mesh.
delegate mapAnchor, unmapAnchor to mm.
// params
settable bool chooseAnchor1AtRandom;
// output
G22MeshMapping mm;
// index structures
MultiMap anchorsByArity2;
// EXCEPTIONS (e.g. meshes don't match in signature)
// set to the reason why when a mapping is deemed impossible
settable O rejectedBecause;
bool rejected() { ret rejectedBecause != null; }
// INTERNAL VARS
bool prechecksDone;
S sig1, sig2;
Anchor anchor1; // first anchor to map
G22MeshMapping get() { ret mm; }
// Do the whole search, but in "random" mode (may fail)
void run_random {
search_step1();
while (search_step2());
}
// random mode
void search_step1() {
prechecks(); if (rejected()) ret;
// make empty mapping
mm = new G22MeshMapping(mesh1, mesh2);
anchorsByArity2 = multiMapIndex(mesh2.anchors(), a -> a.arity());
// Choose first anchor to map - this is arbitrary
// (not a backtracking point)
Anchor anchor1 = chooseAnchor1AtRandom ? random(mesh1.anchors()) : first(mesh1.anchors());
// Choose which anchor to map it to
// (first backtracking point)
L options = anchorsByArity2.get(anchor1.arity());
// ret BacktrackingOptions(options, ...); ???
Anchor anchor2 = random(options);
print("G22MeshMapper_v2 step1: Connecting " + anchor1 + " to " + anchor2);
mapAnchor(anchor1, anchor2);
}
// random mode
bool search_step2() {
bool change;
for (curve1 : mesh1.curves()) {
// skip if curve is already mapped
if (mm.isMapped(curve1))
continue with print("Curve is mapped: " + curve1);
// check if anchors are mapped
Anchor start2 = mm.get(curve1.start);
Anchor end2 = mm.get(curve1.end);
// If neither anchor is mapped, postpone this curve
if (start2 == null && end2 == null)
continue with print("Curve is not discovered yet: " + curve1);
// Start at the mapped anchor, choose a viable curve in mesh2 to map to
bool startAtEnd = end2 != null;
Anchor a1other = curve1.anchor(!startAtEnd);
Anchor a2 = mm.get(curve1.anchor(startAtEnd));
new L possibleCurves;
for (c2 : a2.curves()) {
if (mm.isMapped(c2))
continue with print("Curve already mapped: " + c2);
// check for arity match
Anchor a3 = c2.anchorOpposite(a2);
int arity1 = a3.arity(), arity2 = a1other.arity();
if (arity1 != arity2)
continue with print("Arity mismatch (" + arity1 + "/" + arity2 + ") for curve " + c2);
// This curve is viable as a mapping target
possibleCurves.add(c2);
}
print(l(possibleCurves) + "/" + l(a2.curves())
+ " possible curve(s) to map " + curve1 + " to: " + possibleCurves);
if (empty(possibleCurves))
ret false with rejectedBecause("Could not map curve " + curve1);
// Map the curve
Curve c2 = random(possibleCurves);
bool flipped = c2.start() != a2;
print("Mapping curve " + curve1 + " to " + c2);
mm.mapCurve(curve1, c2, flipped);
set change;
}
ret change;
}
Search newSearch() {
ret new Search;
}
// backtracking version
class Search extends VStackComputableWithStep is IMakeEmptyClone {
Anchor anchor2;
public selfType makeEmptyClone() { ret new selfType; }
void step(VStack stack) {
cast stack to BStack>;
if (step == 0) {
prechecks();
if (rejected()) stack.ret();
step = 1;
} else if (step == 1) {
// make empty mapping
mm = new G22MeshMapping(mesh1, mesh2);
anchorsByArity2 = multiMapIndex(mesh2.anchors(), a -> a.arity());
// Choose first anchor to map - this is arbitrary
// (not a backtracking point)
anchor1 = random(mesh1.anchors());
// Choose which anchor to map it to (first backtracking point).
// List should never be empty because we checked the signatures first.
L anchor2options = anchorsByArity2.get(anchor1.arity());
step = 2;
stack.options(this, map(anchor2options, anchor2
-> instance -> instance.anchor2 = anchor2));
} else if (step == 2) {
print("G22MeshMapper_v2 step1: Connecting " + anchor1 + " to " + anchor2);
mapAnchor(anchor1, anchor2);
step = 3;
} else if (step == 3) {
stack.call(new Step2);
step = 4;
} else {
if (isTrue(stack.subResult()))
step = 3;
else
stack.return();
}
}
}
class Step2 extends VStackComputableWithStep is IMakeEmptyClone {
bool change;
Iterator curve1iterator;
Curve curve1;
public selfType makeEmptyClone() { ret new selfType; }
void step(VStack stack) {
cast stack to BStack>;
if (step == 0) {
curve1iterator = iterator(mesh1.curves());
step++;
} else if (step == 1) {
if (!curve1iterator.hasNext())
ret with stack.return(change);
curve1 = curve1iterator.next();
// skip if curve is already mapped
if (mm.isMapped(curve1)) {
print("Curve is mapped: " + curve1);
ret; // continue loop
}
// check if anchors are mapped
Anchor start2 = mm.get(curve1.start);
Anchor end2 = mm.get(curve1.end);
// If neither anchor is mapped, postpone this curve
if (start2 == null && end2 == null) {
print("Curve is not discovered yet: " + curve1);
ret; // continue loop;
}
// Start at the mapped anchor, choose a viable curve in mesh2 to map to
bool startAtEnd = end2 != null;
Anchor a1other = curve1.anchor(!startAtEnd);
Anchor a2 = mm.get(curve1.anchor(startAtEnd));
new L possibleCurves;
for (c2 : a2.curves()) {
if (mm.isMapped(c2)) {
print("Curve already mapped: " + c2);
ret; // continue loop
}
// check for arity match
Anchor a3 = c2.anchorOpposite(a2);
int arity1 = a3.arity(), arity2 = a1other.arity();
if (arity1 != arity2) {
print("Arity mismatch (" + arity1 + "/" + arity2 + ") for curve " + c2);
ret; // continue loop
}
// This curve is viable as a mapping target
possibleCurves.add(c2);
}
print(l(possibleCurves) + "/" + l(a2.curves())
+ " possible curve(s) to map " + curve1 + " to: " + possibleCurves);
if (empty(possibleCurves)) {
stack.temp(tempRejectedBecause("Could not map curve " + curve1));
ret with stack.ret(false);
}
// Map the curve
Curve c2 = random(possibleCurves);
bool flipped = c2.start() != a2;
print("Mapping curve " + curve1 + " to " + c2);
mm.mapCurve(curve1, c2, flipped);
set change;
// loop will continue
}
}
}
protected void prechecks {
set prechecksDone;
sig1 = mesh1.signature();
sig2 = mesh1.signature();
if (!eq(sig1, sig2))
ret with rejectedBecause(G22SignatureMismatch(mesh1, mesh2));
}
AutoCloseable tempRejectedBecause(O reason) {
rejectedBecause(reason);
ret -> rejectedBecause(null);
}
}