Skip to content

docs: state Wagner's equal-weights placement contract; pass min_steps - #55

Merged
ms609 merged 3 commits into
cpp-searchfrom
feature/wagner-docs
Aug 5, 2026
Merged

docs: state Wagner's equal-weights placement contract; pass min_steps#55
ms609 merged 3 commits into
cpp-searchfrom
feature/wagner-docs

Conversation

@ms609

@ms609 ms609 commented Aug 4, 2026

Copy link
Copy Markdown

Fixes #5
Fixes #6

#5 (T-369)

AdditionTree()'s numeric concavity never affected the returned topology — placement always uses an equal-weights Fitch proxy (fitch_indirect_length_cached), and concavity/min_steps only enter the final score_tree() call. That contract was already documented in a prior commit on @param concavity; this PR:

  • Fixes the remaining gap: searchArgs never passed min_steps, so a finite concavity scored the internal result$score against min_steps = 0 instead of the dataset's real per-character minimum (MinimumLength(dataset, compress = TRUE), matching the idiom already used in MaximizeParsimony()/Resample()/SuccessiveApproximations()). AdditionTree() discards result$score, so this has no user-visible effect — corrected purely for internal correctness and to stop future confusion.
  • Corrects a roxygen inaccuracy an external review caught: the doc claimed numeric concavity "affects only the reported $score", but AdditionTree() never returns a score at all. Reworded to say numeric concavity has no effect on AdditionTree()'s output, full stop.
  • Adds regression tests: a mock-capture test pinning that AdditionTree() forwards real min_steps to ts_wagner_tree (fails pre-fix, confirmed); a direct ts_wagner_tree comparison showing min_steps changes the score but never the edge set; a characterisation test locking in that numeric concavity never moves AdditionTree()'s topology; and two small guards (that concavity = Inf still forwards min_steps = integer(0), and that concavity = "profile" still runs cleanly now that min_steps is computed after profile recoding).

Explicitly left undone (per the issue's own framing, a separate enhancement): using the weighted scorer for placement instead of the EW proxy. That would change start trees package-wide and needs its own wall-clock/reach A/B — out of scope here.

#6 (T-371)

Comment-only. Adds a note on wagner_goloboff_scores()'s tip_ambiguous computation (src/ts_wagner.cpp) recording that it ANDs across all n_states including the NA/inapplicable plane, so a tip coded {0,1} (every applicable state but not -) is scored non-ambiguous/informative despite carrying no information about which applicable state holds. wagner_entropy_scores()'s weight-blindness comment matching Goloboff's was already present on cpp-search from a prior pass, so nothing more was needed there.

Explicitly left undone: changing either behaviour (weight-awareness of the entropy scorer, or treating {0,1} as ambiguous). Both are judgement calls that shift start trees and need their own A/B — this PR only makes the existing behaviour legible.

Validation

  • Build via the tarball recipe (never in-place); .o/.dll cleaned after every roxygen2::roxygenise()/check_man() pass per the debug-contamination gotcha.
  • tests/testthat/test-AdditionTree.R: 36/36 pass against a temp-library install (not load_all()).
  • devtools::check_man(): clean.
  • spelling::spell_check_package() and the exact tests/spelling.R invocation: clean.
  • Reviewed by an external-reviewer agent pass, scoped to correctness of the documented contract and whether min_steps genuinely leaves the topology untouched (verified structurally in src/ts_wagner.cpp and empirically across all 30 inapplicable.phyData datasets: 60/60 topologies identical). Two findings from that review (the $score doc inaccuracy, and a mislabelled/soft test assertion) are fixed in the second commit.
  • GHA (agent-check.yml) is currently failing on this branch, but for an unrelated, already-tracked reason: pak cannot resolve the MaxMin Suggests dependency (agent-check.yml windows job fails on every branch: MaxMin is not published in ms609.github.io/packages, so pak cannot resolve it #43, in-progress), reproduced identically on cpp-search itself at the time of dispatch (run 30929069059, predating this PR's dispatch). Not caused by this change.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

ms609 and others added 2 commits August 4, 2026 18:00
…te tip_ambiguous plane-0 behaviour

AdditionTree() built searchArgs without min_steps, so a finite `concavity`
scored ts_wagner_tree's result against min_steps = 0 instead of the
dataset's real per-character minimum step counts (MinimumLength()). This
corrupted only the internal `result$score`, which AdditionTree() itself
discards, and never moved the returned topology -- placement uses an
equal-weights Fitch proxy regardless of concavity/min_steps.

The equal-weights-proxy placement contract was already documented on
@PARAM concavity in a prior commit; this just fixes the remaining
min_steps gap and adds regression coverage: a mock-capture test pinning
that AdditionTree() forwards real min_steps to ts_wagner_tree, a direct
ts_wagner_tree comparison showing min_steps changes the score but not the
edge set, and a characterisation test locking in that numeric concavity
never moves AdditionTree()'s topology.

Also records, as a comment only, that wagner_goloboff_scores()'s
tip_ambiguous computation ANDs across all n_states including the NA
plane, so a tip coded {0,1} -- every applicable state but not "-" -- is
scored non-ambiguous (informative) despite carrying no information about
which applicable state holds. Left as-is: changing it shifts start trees
and needs an A/B (T-371).

Fixes #5
Fixes #6

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ps tests

External review of the prior commit found the roxygen text factually
wrong: AdditionTree() never returns a $score (it discards result$score),
so "affects only the reported $score" is false -- correct it to state
plainly that numeric concavity has no effect on AdditionTree()'s output.

Also addresses two test gaps the review flagged: the first new test
exercised ts_wagner_tree() directly rather than AdditionTree() (retitled
to make that explicit, and its equality assertion tightened to a
directional/finiteness check so a NaN or sign error couldn't pass), and
two cheap regression tests were missing: that concavity = Inf still
forwards min_steps = integer(0), and that concavity = "profile" still
runs cleanly now min_steps is computed post-recoding.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ms609
ms609 enabled auto-merge August 5, 2026 02:56
@ms609
ms609 merged commit 38115e4 into cpp-search Aug 5, 2026
11 of 12 checks passed
@ms609
ms609 deleted the feature/wagner-docs branch August 5, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant