OverviewFilesCommitsIssuesDocsReleasesPeers

atomspace-layer-discovery commits / ae10fee

experiments/ladder/port: merge 1 compared with Linas; left-over pass is order-dependent
Sections merged match exactly (629 of 783); left-over crosses 2696 vs his 2697. Shuffling the left-over order gives 2695-2697 and class crosses 2905-2909 (Sections identical): Linas's result depends on atom-set hash order. Diagnostic CLUSTER_SHUFFLE switch added (off by default). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ae10feeffa940fe4768ec321ce21e5f31aba09b6
by plankatron <fleeky@gmail.com> · 2026-10-18T18:00:34.000Z

Changed files (2) +26 -0

experiments/ladder/port/STAGE_E_SPEC.md +12 -0
……@@ -106,3 +106,15 @@ Measured, not inferred:
106106- **Port:** `cover --as-run` reproduces this (15/15 pairs exact on the small example; Linas's Alice log
107107 line exactly). Without the flag the dot product uses Sections + Shapes, which is what the covering design
108108 describes. Which one the ladder uses is the operator's decision; reporting upstream is too.
109
110## 6. Merge 1 vs Linas (run `g0-E-1792343484`, 2026-10-18)
111
112- Sections: Linas "Merge 629 of 783"; port 629 of 783. Class `? ! .`; sims recomputed for the 3 members.
113- Left-over CrossSections: Linas 2697 of 2901; port 2696 of 2901 in first-seen order.
114- **The left-over pass is order-dependent** (`get-alt-shapes` marks shapes done as a side effect of
115 being considered). Over 8 shuffles of the left-over order (`CLUSTER_SHUFFLE=<seed>`) the port gives
116 2695, 2696 or 2697; class Sections are identical in all (783, count 1509), class CrossSections
117 2905-2909 (count 4200-4204), member count 5620-5622. Linas's order is atom-set (hash) order, which
118 cannot be reproduced outside the AtomSpace. Verification therefore requires his final state to equal
119 **one of** the port's orderings; prediction for his: 2909 crosses, count 4204, member count 5622.
120- Then Linas's run failed on a fifth break (`cog-value?` removed, ORACLE-DEVIATIONS §11), now shimmed.
experiments/ladder/port/cluster.c +14 -0
……@@ -662,6 +662,14 @@ static void merge_majority (long cls, long *g, int n) {
662662 int nleft = 0, mshcnt = 0;
663663 long *left = malloc(sizeof(long) * (ndj + 1));
664664 for (size_t k = 0; k < ndj; k++) if (!is_marked(done, djs[k])) left[nleft++] = djs[k];
665 if (getenv("CLUSTER_SHUFFLE")) { // diagnostic: does the left-over order (Linas: atom-set order) matter?
666 uint64_t z = strtoull(getenv("CLUSTER_SHUFFLE"), NULL, 10) * 0x9e3779b97f4a7c15ULL + 1;
667 for (int k = nleft - 1; k > 0; k--) {
668 z ^= z << 13; z ^= z >> 7; z ^= z << 17;
669 int j = (int) (z % (uint64_t) (k + 1));
670 long t = left[k]; left[k] = left[j]; left[j] = t;
671 }
672 }
665673 for (int k = 0; k < nleft; k++) {
666674 long shp = left[k];
667675 if (once_shape_done(shp)) continue;
……@@ -767,6 +775,12 @@ int main (int argc, char **argv) {
767775 long cls = make_class_node(grp, n);
768776 merge_majority(cls, grp, n);
769777 printf("------ Merged into `%s`\n", aname(cls));
778 if (getenv("CLUSTER_SHUFFLE")) { // diagnostic: class row and member counts after the merge
779 double cs = 0, cx = 0, ns = 0, nx = 0, mc = 0;
780 for (size_t k = 0; k < npairs; k++) if (pairs[k].alive && pairs[k].r == cls) { if (cols[pairs[k].c].shape) { cx += pairs[k].n; nx++; } else { cs += pairs[k].n; ns++; } }
781 for (size_t k = 0; k < nmembs; k++) if (membs[k].cls == cls) mc += membs[k].n;
782 printf("class: sections %.0f (count %.0f) crosses %.0f (count %.0f) member-count %.0f\n", ns, cs, nx, cx, mc);
783 }
770784
771785 recompute(); // marginals of everything touched (full recompute is equivalent)
772786 remove_empty(cls);