phino 0.0.151 → 0.0.152
raw patch · 585 files changed
+11652/−390 lines, 585 filesdep +unixPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: unix
API changes (from Hackage documentation)
This diff is very large; some files are shown as “too large to diff”. Download the raw patch for the complete diff.
Files
- README.md +142/−80
- benchmark/Main.hs +1/−0
- compiled/generated/Compiled.hs +23/−9
- phino.cabal +6/−2
- resources/normalize/norho.yaml +14/−0
- src/Bytes.hs +8/−4
- src/CLI.hs +7/−3
- src/CLI/Helpers.hs +47/−14
- src/CLI/Parsers.hs +23/−14
- src/CLI/Runners.hs +38/−14
- src/CLI/Types.hs +3/−0
- src/CLI/Validators.hs +5/−2
- src/Canonizer.hs +50/−41
- src/Emit.hs +2/−2
- src/Evaluate.hs +12/−10
- src/Files.hs +8/−2
- src/Filter.hs +2/−1
- src/Functions.hs +94/−36
- src/LaTeX.hs +20/−8
- src/Lambdas.hs +64/−12
- src/Locator.hs +5/−0
- src/Margin.hs +41/−3
- src/Morph.hs +19/−15
- src/Parser.hs +32/−17
- src/Printer.hs +2/−2
- src/Regexp.hs +36/−22
- src/Render.hs +2/−2
- src/Rewriter.hs +1/−1
- src/Sugar.hs +34/−1
- src/Yaml.hs +12/−1
- test-resources/atoms.yaml +53/−0
- test-resources/cli/expressions/bytes.phi +11/−0
- test-resources/cli/expressions/desugar.phi +5/−0
- test-resources/cli/expressions/dispatch.phi +1/−0
- test-resources/cli/expressions/foo.phi +5/−0
- test-resources/cli/expressions/normalize.phi +3/−0
- test-resources/cli/expressions/number.phi +11/−0
- test-resources/cli/expressions/string.phi +11/−0
- test-resources/cli/expressions/with-$this-attribute.phi +18/−0
- test-resources/cli/rules/evaluate-in-rewrite.yaml +14/−0
- test-resources/cli/rules/first.yaml +22/−0
- test-resources/cli/rules/infinite.yaml +10/−0
- test-resources/cli/rules/join-broken.yaml +14/−0
- test-resources/cli/rules/labeled.yaml +7/−0
- test-resources/cli/rules/malformed-pattern.yaml +10/−0
- test-resources/cli/rules/marker.yaml +9/−0
- test-resources/cli/rules/raising-condition.yaml +12/−0
- test-resources/cli/rules/second.yaml +6/−0
- test-resources/cli/rules/simple.yaml +6/−0
- test-resources/cli/rules/swap-a.yaml +6/−0
- test-resources/cli/rules/swap-b.yaml +6/−0
- test-resources/condition-packs/absolute-application.yaml +7/−0
- test-resources/condition-packs/absolute-dispatch.yaml +7/−0
- test-resources/condition-packs/absolute-formation.yaml +7/−0
- test-resources/condition-packs/absolute-global.yaml +7/−0
- test-resources/condition-packs/absolute-of-a-dispatch-builds-its-meta.yaml +7/−0
- test-resources/condition-packs/absolute-termination.yaml +7/−0
- test-resources/condition-packs/absolute-this.yaml +8/−0
- test-resources/condition-packs/absolute-unbound-meta.yaml +8/−0
- test-resources/condition-packs/alpha-simple.yaml +9/−0
- test-resources/condition-packs/and-fails.yaml +10/−0
- test-resources/condition-packs/and-multiple.yaml +11/−0
- test-resources/condition-packs/disjoint-clean.yaml +9/−0
- test-resources/condition-packs/disjoint-unbound-meta.yaml +10/−0
- test-resources/condition-packs/domain-meta-missing.yaml +10/−0
- test-resources/condition-packs/eq-attr-both-meta-one-unbound.yaml +8/−0
- test-resources/condition-packs/eq-attr-concrete-then-meta-unbound.yaml +10/−0
- test-resources/condition-packs/eq-attr-concrete-then-meta.yaml +9/−0
- test-resources/condition-packs/eq-attr-meta-then-concrete-unbound.yaml +10/−0
- test-resources/condition-packs/eq-expr-both-meta-one-unbound.yaml +8/−0
- test-resources/condition-packs/eq-expr-concrete-then-meta-unbound.yaml +10/−0
- test-resources/condition-packs/eq-expr-concrete-then-meta.yaml +9/−0
- test-resources/condition-packs/eq-expr-meta-then-concrete-unbound.yaml +10/−0
- test-resources/condition-packs/eq-mismatched-comparable-kinds.yaml +10/−0
- test-resources/condition-packs/eq-to-rho.yaml +9/−0
- test-resources/condition-packs/eq-with-attributes.yaml +10/−0
- test-resources/condition-packs/eq-with-expressions.yaml +9/−0
- test-resources/condition-packs/eq-with-formations.yaml +9/−0
- test-resources/condition-packs/eq-with-two-meta-attributes.yaml +7/−0
- test-resources/condition-packs/eq-with-two-meta-expressions.yaml +7/−0
- test-resources/condition-packs/formation-simple.yaml +7/−0
- test-resources/condition-packs/formation-unbound-meta.yaml +8/−0
- test-resources/condition-packs/gt-domain.yaml +9/−0
- test-resources/condition-packs/gt-non-numeric.yaml +8/−0
- test-resources/condition-packs/in-every-attribute.yaml +9/−0
- test-resources/condition-packs/in-missing.yaml +10/−0
- test-resources/condition-packs/in-one-of-attributes.yaml +10/−0
- test-resources/condition-packs/in-simple.yaml +9/−0
- test-resources/condition-packs/in-unbound-attribute.yaml +10/−0
- test-resources/condition-packs/in-void.yaml +9/−0
- test-resources/condition-packs/is-formation.yaml +7/−0
- test-resources/condition-packs/length-meta-missing.yaml +10/−0
- test-resources/condition-packs/length-non-meta-binding.yaml +10/−0
- test-resources/condition-packs/length.yaml +9/−0
- test-resources/condition-packs/matches-cyrillic-skips-latin.yaml +8/−0
- test-resources/condition-packs/matches-cyrillic.yaml +7/−0
- test-resources/condition-packs/matches-unbound-meta.yaml +8/−0
- test-resources/condition-packs/matches-with-line-bounds.yaml +7/−0
- test-resources/condition-packs/matches.yaml +7/−0
- test-resources/condition-packs/metaindex-missing.yaml +10/−0
- test-resources/condition-packs/nf-builds-the-term-from-its-meta.yaml +8/−0
- test-resources/condition-packs/nf-dispatch-global.yaml +7/−0
- test-resources/condition-packs/nf-dispatch-this.yaml +7/−0
- test-resources/condition-packs/nf-dot-recursive.yaml +8/−0
- test-resources/condition-packs/nf-empty-formation.yaml +7/−0
- test-resources/condition-packs/nf-formation-with-delta.yaml +7/−0
- test-resources/condition-packs/nf-formation-with-void.yaml +7/−0
- test-resources/condition-packs/nf-global.yaml +7/−0
- test-resources/condition-packs/nf-of-a-dispatch-builds-its-meta.yaml +8/−0
- test-resources/condition-packs/nf-on-dot.yaml +7/−0
- test-resources/condition-packs/nf-on-phi.yaml +11/−0
- test-resources/condition-packs/nf-simple.yaml +7/−0
- test-resources/condition-packs/nf-termination.yaml +7/−0
- test-resources/condition-packs/nf-this.yaml +7/−0
- test-resources/condition-packs/nf-unbound-meta.yaml +8/−0
- test-resources/condition-packs/not-disjoint-delta.yaml +10/−0
- test-resources/condition-packs/not-disjoint-lambda.yaml +10/−0
- test-resources/condition-packs/not-eq.yaml +8/−0
- test-resources/condition-packs/not-formation.yaml +8/−0
- test-resources/condition-packs/not-gt.yaml +10/−0
- test-resources/condition-packs/not-in-one-of-attributes.yaml +10/−0
- test-resources/condition-packs/not-nf-on-dc.yaml +8/−0
- test-resources/condition-packs/not-nf-on-dd.yaml +8/−0
- test-resources/condition-packs/or-first-match.yaml +9/−0
- test-resources/condition-packs/or.yaml +11/−0
- test-resources/condition-packs/ordinal.yaml +9/−0
- test-resources/condition-packs/part-of-missing.yaml +8/−0
- test-resources/condition-packs/part-of-nested.yaml +7/−0
- test-resources/condition-packs/part-of-simple.yaml +7/−0
- test-resources/condition-packs/stop.yaml +19/−0
- test-resources/cst/printing-packs/basic.yaml +8/−0
- test-resources/cst/printing-packs/dispatch-and-application-sugar-after-inline-voids.yaml +8/−0
- test-resources/cst/printing-packs/dispatch.yaml +8/−0
- test-resources/cst/printing-packs/formation-sugar-after-inline-voids.yaml +12/−0
- test-resources/cst/printing-packs/jeo.yaml +36/−0
- test-resources/cst/printing-packs/lambda-sugar-after-inline-voids.yaml +8/−0
- test-resources/cst/printing-packs/non-finite-doubles.yaml +20/−0
- test-resources/cst/printing-packs/non-primitive-data-object.yaml +8/−0
- test-resources/cst/printing-packs/primitives-without-rhos.yaml +11/−0
- test-resources/cst/printing-packs/simple.yaml +13/−0
- test-resources/cst/printing-packs/sugar-after-inline-voids.yaml +8/−0
- test-resources/cst/printing-packs/sweet-inlined.yaml +14/−0
- test-resources/cst/printing-packs/voids-after-delta.yaml +8/−0
- test-resources/cst/printing-packs/voids-after-lambda.yaml +8/−0
- test-resources/cst/printing-packs/with-void-rho-between.yaml +8/−0
- test-resources/cst/printing-packs/xi-attribute.yaml +8/−0
- test-resources/cst/to-ascii-packs/bytes-meta.yaml +5/−0
- test-resources/cst/to-ascii-packs/complex.yaml +30/−0
- test-resources/cst/to-salty-packs/application-with-alphas.yaml +26/−0
- test-resources/cst/to-salty-packs/application.yaml +26/−0
- test-resources/cst/to-salty-packs/formation-sugar-after-inline-voids.yaml +22/−0
- test-resources/cst/to-salty-packs/non-finite-doubles.yaml +36/−0
- test-resources/cst/to-salty-packs/primitives-with-rhos.yaml +36/−0
- test-resources/cst/to-salty-packs/with-inlined-voids.yaml +14/−0
- test-resources/cst/to-salty-packs/with-num-and-void-rho.yaml +17/−0
- test-resources/cst/to-salty-packs/xi-attr.yaml +10/−0
- test-resources/cst/to-singleline-packs/application.yaml +17/−0
- test-resources/cst/to-singleline-packs/empty-formation.yaml +10/−0
- test-resources/cst/to-singleline-packs/with-inlined-voids.yaml +10/−0
- test-resources/dataization-packs/dataizes-a-chain-of-firings-to-the-manufactured-datum.yaml +10/−0
- test-resources/dataization-packs/dataizes-a-located-reference.yaml +16/−0
- test-resources/dataization-packs/dataizes-a-symbolic-sum-to-the-manufactured-datum.yaml +9/−0
- test-resources/dataization-packs/dataizes-an-attribute-inherited-through-phi.yaml +11/−0
- test-resources/dataization-packs/dataizes-the-branch-an-undecided-condition-picked.yaml +10/−0
- test-resources/dataization-packs/dataizes-the-number-five.yaml +13/−0
- test-resources/dataization-packs/fails-to-dataize-an-empty-formation.yaml +8/−0
- test-resources/dataization-packs/gets-stuck-on-a-lambda-no-entry-answers.yaml +7/−0
- test-resources/evaluate-packs/answers-a-symbol-nobody-has-worked-out.yaml +44/−0
- test-resources/evaluate-packs/answers-a-whole-family-of-names-with-one-entry.yaml +62/−0
- test-resources/evaluate-packs/answers-the-same-under-acyclic.yaml +46/−0
- test-resources/evaluate-packs/blames-the-lambda-the-operand-was-parked-on.yaml +27/−0
- test-resources/evaluate-packs/cuts-a-loop-over-unknown-data-on-its-second-round.yaml +184/−0
- test-resources/evaluate-packs/cuts-a-recursion-that-differs-by-symbols-only.yaml +171/−0
- test-resources/evaluate-packs/defers-a-copy-whose-argument-is-a-bare-symbol.yaml +167/−0
- test-resources/evaluate-packs/fails-on-a-bare-symbol-and-a-branch-holding-one-symbol-when-strict.yaml +43/−0
- test-resources/evaluate-packs/fails-on-a-bare-symbol-and-a-branch-holding-two-symbols-when-lenient.yaml +44/−0
- test-resources/evaluate-packs/fails-on-a-branch-and-a-decorator-of-it-when-strict.yaml +25/−0
- test-resources/evaluate-packs/fails-on-a-fork-whose-branches-do-not-join.yaml +26/−0
- test-resources/evaluate-packs/fails-on-a-lambda-no-entry-answers.yaml +17/−0
- test-resources/evaluate-packs/fails-on-an-operand-that-reaches-the-terminator.yaml +61/−0
- test-resources/evaluate-packs/fires-a-formation-again-where-the-budget-stalled-it.yaml +52/−0
- test-resources/evaluate-packs/fires-a-formation-once-however-often-it-is-met.yaml +96/−0
- test-resources/evaluate-packs/fires-a-lambda-once-however-many-bindings-read-it.yaml +25/−0
- test-resources/evaluate-packs/fires-a-read-once-in-the-copy-it-stands-in.yaml +62/−0
- test-resources/evaluate-packs/fires-a-sibling-at-the-depth-the-head-pass-began-at.yaml +38/−0
- test-resources/evaluate-packs/fires-a-sibling-once-through-a-dispatch-into-its-object.yaml +56/−0
- test-resources/evaluate-packs/fires-a-stalled-formation-again-after-what-its-own-firing-answered.yaml +58/−0
- test-resources/evaluate-packs/fires-a-stalled-formation-again-once-something-was-answered.yaml +54/−0
- test-resources/evaluate-packs/fires-nothing-twice-in-a-binding-a-dispatch-reads.yaml +65/−0
- test-resources/evaluate-packs/joins-a-bare-symbol-with-a-branch-holding-one-symbol-when-lenient.yaml +48/−0
- test-resources/evaluate-packs/joins-a-branch-reached-from-a-literal.yaml +38/−0
- test-resources/evaluate-packs/joins-a-branch-with-a-decorator-of-it-when-lenient.yaml +30/−0
- test-resources/evaluate-packs/joins-a-decorator-with-the-branch-it-decorates-standing-second-when-lenient.yaml +29/−0
- test-resources/evaluate-packs/joins-a-fork-one-branch-of-which-raises.yaml +121/−0
- test-resources/evaluate-packs/joins-a-fork-one-branch-of-which-throws.yaml +126/−0
- test-resources/evaluate-packs/joins-a-fork-that-raises-on-the-left.yaml +120/−0
- test-resources/evaluate-packs/joins-a-fork-whose-branches-a-rewrite-brought-to-one-shape.yaml +42/−0
- test-resources/evaluate-packs/joins-a-negated-bool-whose-literal-a-rewrite-brought-to-one-shape.yaml +163/−0
- test-resources/evaluate-packs/joins-the-branches-a-program-forks-into.yaml +146/−0
- test-resources/evaluate-packs/joins-the-two-branches-of-a-fork.yaml +32/−0
- test-resources/evaluate-packs/joins-two-branches-nothing-tells-apart.yaml +27/−0
- test-resources/evaluate-packs/keeps-a-cut-met-inside-a-firing-for-the-next-firing.yaml +37/−0
- test-resources/evaluate-packs/keeps-a-stuck-firing-for-the-next-firing.yaml +33/−0
- test-resources/evaluate-packs/keeps-the-answer-a-firing-already-gave.yaml +19/−0
- test-resources/evaluate-packs/keeps-the-name-of-an-object-the-walk-computed-inside.yaml +64/−0
- test-resources/evaluate-packs/keeps-the-rho-bindings-a-pack-asks-for.yaml +23/−0
- test-resources/evaluate-packs/leaves-a-method-of-a-copy-without-rho-unwalked.yaml +78/−0
- test-resources/evaluate-packs/leaves-a-rho-void-formation-unwalked.yaml +78/−0
- test-resources/evaluate-packs/leaves-an-abstract-formation-unwalked.yaml +93/−0
- test-resources/evaluate-packs/leaves-the-literals-of-a-method-out-of-a-join.yaml +45/−0
- test-resources/evaluate-packs/mints-a-fresh-symbol-for-every-firing.yaml +60/−0
- test-resources/evaluate-packs/mints-past-the-symbols-a-stuck-firing-minted.yaml +34/−0
- test-resources/evaluate-packs/morphs-a-program-that-already-carries-a-symbol.yaml +43/−0
- test-resources/evaluate-packs/morphs-two-branches-spelling-one-term-through-one-firing.yaml +116/−0
- test-resources/evaluate-packs/nests-the-firing-an-operand-brought-down.yaml +59/−0
- test-resources/evaluate-packs/parks-a-dispatch-off-a-symbol.yaml +70/−0
- test-resources/evaluate-packs/parks-a-firing-whose-operand-dataizes-in-circles.yaml +31/−0
- test-resources/evaluate-packs/parks-a-firing-whose-operand-loops.yaml +31/−0
- test-resources/evaluate-packs/parks-a-firing-whose-operand-never-came-down.yaml +24/−0
- test-resources/evaluate-packs/parks-a-firing-whose-operand-no-rule-dataizes.yaml +21/−0
- test-resources/evaluate-packs/parks-a-firing-whose-operand-reaches-the-terminator.yaml +96/−0
- test-resources/evaluate-packs/parks-a-fork-whose-branches-do-not-join.yaml +27/−0
- test-resources/evaluate-packs/parks-a-lambda-no-entry-answers.yaml +18/−0
- test-resources/evaluate-packs/parks-an-entry-that-answers-with-a-firing-of-itself.yaml +21/−0
- test-resources/evaluate-packs/parks-the-same-dataization-loop-under-partial.yaml +33/−0
- test-resources/evaluate-packs/records-a-parked-site-once.yaml +22/−0
- test-resources/evaluate-packs/reduces-a-carried-symbol-through-morphing.yaml +20/−0
- test-resources/evaluate-packs/reduces-the-branches-of-a-fork-through-morphing.yaml +118/−0
- test-resources/evaluate-packs/spends-the-step-budget-on-an-entry-answering-itself.yaml +36/−0
- test-resources/evaluate-packs/stands-the-data-of-a-term-into-unknowns.yaml +37/−0
- test-resources/evaluate-packs/starts-minting-after-the-symbols-the-program-carries.yaml +45/−0
- test-resources/evaluate-packs/stops-an-accumulator-recursion-under-plausible.yaml +128/−0
- test-resources/evaluate-packs/takes-the-answer-of-a-firing-with-the-same-operands.yaml +50/−0
- test-resources/evaluate-packs/tells-a-budget-stall-to-a-firing-no-shallower.yaml +252/−0
- test-resources/evaluate-packs/tells-two-carried-symbols-apart-in-one-firing.yaml +40/−0
- test-resources/evaluate-packs/tells-two-symbols-of-one-datum-apart-between-firings.yaml +54/−0
- test-resources/evaluate-packs/walks-a-binding-of-an-object-once-however-many-copies-hold-it.yaml +73/−0
- test-resources/evaluate-packs/walks-a-binding-reading-its-copy-in-every-copy.yaml +80/−0
- test-resources/evaluate-packs/walks-on-past-a-binding-it-parked-on.yaml +24/−0
- test-resources/evaluate-packs/walks-on-past-a-firing-it-could-not-make.yaml +36/−0
- test-resources/evaluate-packs/writes-a-symbolized-copy-of-a-term-out-in-full.yaml +30/−0
- test-resources/evaluate-packs/writes-the-binding-a-deep-firing-stands-in.yaml +77/−0
- test-resources/explain-packs/contextualization/ca.yaml +11/−0
- test-resources/explain-packs/contextualization/caa.yaml +11/−0
- test-resources/explain-packs/contextualization/cd.yaml +10/−0
- test-resources/explain-packs/contextualization/cf.yaml +9/−0
- test-resources/explain-packs/contextualization/cg.yaml +9/−0
- test-resources/explain-packs/contextualization/ct.yaml +9/−0
- test-resources/explain-packs/contextualization/cxi.yaml +9/−0
- test-resources/explain-packs/dataization/box.yaml +13/−0
- test-resources/explain-packs/dataization/delta.yaml +11/−0
- test-resources/explain-packs/dataization/fire.yaml +12/−0
- test-resources/explain-packs/dataization/none.yaml +11/−0
- test-resources/explain-packs/dataization/norm.yaml +12/−0
- test-resources/explain-packs/morphing/dead.yaml +9/−0
- test-resources/explain-packs/morphing/ma.yaml +12/−0
- test-resources/explain-packs/morphing/maa.yaml +12/−0
- test-resources/explain-packs/morphing/maad.yaml +11/−0
- test-resources/explain-packs/morphing/mad.yaml +11/−0
- test-resources/explain-packs/morphing/md.yaml +13/−0
- test-resources/explain-packs/morphing/mf.yaml +9/−0
- test-resources/explain-packs/morphing/mg.yaml +10/−0
- test-resources/explain-packs/morphing/ml.yaml +13/−0
- test-resources/explain-packs/morphing/mphi.yaml +13/−0
- test-resources/explain-packs/morphing/universe.yaml +13/−0
- test-resources/explain-packs/morphing/xi.yaml +10/−0
- test-resources/explain-packs/normalize/alpha.yaml +10/−0
- test-resources/explain-packs/normalize/amiss.yaml +10/−0
- test-resources/explain-packs/normalize/copy.yaml +10/−0
- test-resources/explain-packs/normalize/dc.yaml +10/−0
- test-resources/explain-packs/normalize/dca.yaml +10/−0
- test-resources/explain-packs/normalize/dd.yaml +10/−0
- test-resources/explain-packs/normalize/dl.yaml +10/−0
- test-resources/explain-packs/normalize/dot.yaml +10/−0
- test-resources/explain-packs/normalize/miss.yaml +10/−0
- test-resources/explain-packs/normalize/norho.yaml +10/−0
- test-resources/explain-packs/normalize/null.yaml +10/−0
- test-resources/explain-packs/normalize/over.yaml +10/−0
- test-resources/explain-packs/normalize/overa.yaml +10/−0
- test-resources/explain-packs/normalize/skip.yaml +10/−0
- test-resources/explain-packs/normalize/stay.yaml +10/−0
- test-resources/explain-packs/normalize/stop.yaml +10/−0
- test-resources/filter-packs/complex.yaml +10/−0
- test-resources/filter-packs/org-eolang.yaml +7/−0
- test-resources/filter-packs/show-hide.yaml +8/−0
- test-resources/filter-packs/show.yaml +8/−0
- test-resources/filter-packs/simple.yaml +7/−0
- test-resources/filter-packs/with-attributes.yaml +8/−0
- test-resources/filter-packs/with-void.yaml +7/−0
- test-resources/latex-packs/delta-and-phi.yaml +10/−0
- test-resources/latex-packs/dispatch.yaml +10/−0
- test-resources/latex-packs/escaped-labels.yaml +10/−0
- test-resources/latex-packs/escaped-strings.yaml +10/−0
- test-resources/latex-packs/formation-with-voids.yaml +10/−0
- test-resources/latex-packs/fractional-numbers.yaml +10/−0
- test-resources/latex-packs/lambda-and-void.yaml +10/−0
- test-resources/latex-packs/named-application.yaml +10/−0
- test-resources/latex-packs/non-ascii-label.yaml +10/−0
- test-resources/latex-packs/one-binding-sugar.yaml +10/−0
- test-resources/latex-packs/phi-in-label.yaml +10/−0
- test-resources/latex-packs/positional-application.yaml +10/−0
- test-resources/latex-packs/primitives.yaml +10/−0
- test-resources/latex-packs/rho-and-xi.yaml +10/−0
- test-resources/latex-packs/termination.yaml +10/−0
- test-resources/merge-packs/absorbs-an-empty-formation.yaml +6/−0
- test-resources/merge-packs/collapses-identical-bindings.yaml +6/−0
- test-resources/merge-packs/collapses-identical-deltas.yaml +6/−0
- test-resources/merge-packs/collapses-identical-voids.yaml +6/−0
- test-resources/merge-packs/drops-the-package-lambda-from-an-object.yaml +9/−0
- test-resources/merge-packs/drops-the-package-lambda-from-the-left-side-too.yaml +9/−0
- test-resources/merge-packs/fails-deep-inside-a-formation.yaml +6/−0
- test-resources/merge-packs/fails-on-a-formation-against-a-dispatch.yaml +6/−0
- test-resources/merge-packs/fails-on-a-non-formation.yaml +6/−0
- test-resources/merge-packs/fails-on-a-void-against-a-value.yaml +6/−0
- test-resources/merge-packs/fails-on-conflicting-deltas.yaml +6/−0
- test-resources/merge-packs/fails-on-conflicting-lambdas.yaml +6/−0
- test-resources/merge-packs/fails-on-conflicting-values.yaml +6/−0
- test-resources/merge-packs/keeps-a-shared-void-in-its-place.yaml +6/−0
- test-resources/merge-packs/keeps-the-order-of-the-right-side-voids.yaml +6/−0
- test-resources/merge-packs/keeps-the-package-lambda-between-two-packages.yaml +6/−0
- test-resources/merge-packs/puts-a-right-side-void-before-the-shared-one.yaml +6/−0
- test-resources/merge-packs/puts-united-bindings-after-untouched-ones.yaml +6/−0
- test-resources/merge-packs/unites-disjoint-bindings.yaml +6/−0
- test-resources/merge-packs/unites-nested-formations.yaml +6/−0
- test-resources/merge-packs/unites-package-trees.yaml +6/−0
- test-resources/morph-deep-packs/dont-fire-a-lambda-an-unapplied-rho-filled-with-bottom.yaml +10/−0
- test-resources/morph-deep-packs/fails-on-a-stuck-atom-deep-on-a-spine.yaml +7/−0
- test-resources/morph-deep-packs/fires-the-atom-nested-in-an-argument.yaml +20/−0
- test-resources/morph-deep-packs/keeps-the-answer-of-the-last-atom-in-a-chain.yaml +20/−0
- test-resources/morph-deep-packs/leaves-a-lambda-no-entry-answers-alone.yaml +10/−0
- test-resources/morph-deep-packs/leaves-a-lambda-still-waiting-for-arguments-alone.yaml +13/−0
- test-resources/morph-deep-packs/leaves-an-unapplied-formation-reaching-its-rho-alone.yaml +12/−0
- test-resources/morph-deep-packs/parks-a-stuck-atom-deep-on-a-spine.yaml +8/−0
- test-resources/morph-deep-packs/resolves-a-xi-against-the-formation-holding-it.yaml +23/−0
- test-resources/morph-deep-packs/stands-the-answer-of-a-bare-lambda-in-its-place.yaml +20/−0
- test-resources/morph-deep-packs/walks-into-the-argument-of-an-atom-it-cannot-fire.yaml +22/−0
- test-resources/morph-packs/answers-bottom-on-rho-of-a-formation-without-rho.yaml +8/−0
- test-resources/morph-packs/answers-bottom-where-no-formation-is-reachable.yaml +8/−0
- test-resources/morph-packs/fails-on-a-premise-that-runs-out-of-cycles.yaml +34/−0
- test-resources/morph-packs/fails-on-a-stuck-atom-under-ml.yaml +8/−0
- test-resources/morph-packs/fails-on-an-input-that-is-not-a-normal-form.yaml +12/−0
- test-resources/morph-packs/hands-the-top-formation-back-untouched.yaml +7/−0
- test-resources/morph-packs/names-a-nested-object-by-its-path.yaml +13/−0
- test-resources/morph-packs/names-a-top-level-object-in-a-rho-instead-of-copying-it.yaml +17/−0
- test-resources/morph-packs/names-an-applied-top-level-object-in-a-rho.yaml +14/−0
- test-resources/morph-packs/names-the-universe-in-a-rho-instead-of-holding-it.yaml +13/−0
- test-resources/morph-packs/parks-a-premise-that-runs-out-of-cycles.yaml +46/−0
- test-resources/morph-packs/parks-a-stuck-atom-under-ml.yaml +9/−0
- test-resources/parser-packs/all-the-basics.phi +45/−0
- test-resources/parser-packs/ascii-with-braces.phi +21/−0
- test-resources/parser-packs/ascii-with-global.phi +16/−0
- test-resources/parser-packs/inline-voids.phi +1/−0
- test-resources/parser-packs/primitive.phi +1/−0
- test-resources/parser-packs/salty-fibo.phi +41/−0
- test-resources/parser-packs/simple.phi +1/−0
- test-resources/parser-packs/sweet-fibo.phi +16/−0
- test-resources/parser-packs/virtual-map.phi +65/−0
- test-resources/phi-typos-packs/alpha-index-out-of-range.phi +3/−0
- test-resources/phi-typos-packs/attribute-with-quote.phi +3/−0
- test-resources/phi-typos-packs/delta-in-application.phi +3/−0
- test-resources/phi-typos-packs/duplicated-attributes.phi +4/−0
- test-resources/phi-typos-packs/symbol-numbered-minus-zero.phi +3/−0
- test-resources/phi-typos-packs/symbol-numbered-negative.phi +3/−0
- test-resources/phi-typos-packs/symbol-numbered-out-of-range.phi +3/−0
- test-resources/phi-typos-packs/symbol-numbered-with-leading-zero.phi +3/−0
- test-resources/phi-typos-packs/wrong-function-name.phi +5/−0
- test-resources/rewriter-packs/basic/alpha-first.yaml +9/−0
- test-resources/rewriter-packs/basic/alpha-fourth.yaml +9/−0
- test-resources/rewriter-packs/basic/alpha-rho-middle-skipped.yaml +9/−0
- test-resources/rewriter-packs/basic/alpha-rho-void-before-x.yaml +9/−0
- test-resources/rewriter-packs/basic/alpha-second.yaml +9/−0
- test-resources/rewriter-packs/basic/alpha-simple.yaml +9/−0
- test-resources/rewriter-packs/basic/alpha-skips-bound-rho.yaml +9/−0
- test-resources/rewriter-packs/basic/alpha-skips-delta-asset.yaml +9/−0
- test-resources/rewriter-packs/basic/alpha-skips-lambda-asset-hits-rho.yaml +9/−0
- test-resources/rewriter-packs/basic/alpha-skips-lambda-asset-out-of-range.yaml +9/−0
- test-resources/rewriter-packs/basic/alpha-skips-lambda-asset.yaml +9/−0
- test-resources/rewriter-packs/basic/alpha-stops-at-idx.yaml +9/−0
- test-resources/rewriter-packs/basic/alpha-stops-at-length.yaml +9/−0
- test-resources/rewriter-packs/basic/copy-paper-e1.yaml +9/−0
- test-resources/rewriter-packs/basic/copy-paper-e4-dispatch.yaml +9/−0
- test-resources/rewriter-packs/basic/copy-simple.yaml +9/−0
- test-resources/rewriter-packs/basic/copy-with-tail.yaml +9/−0
- test-resources/rewriter-packs/basic/dc-from-paper.yaml +9/−0
- test-resources/rewriter-packs/basic/dc-in-subformation.yaml +10/−0
- test-resources/rewriter-packs/basic/dca-from-paper.yaml +9/−0
- test-resources/rewriter-packs/basic/dd.yaml +11/−0
- test-resources/rewriter-packs/basic/dot-lambda-delta-to-dl.yaml +12/−0
- test-resources/rewriter-packs/basic/dot-lambda-only.yaml +16/−0
- test-resources/rewriter-packs/basic/dot-paper-e2.yaml +9/−0
- test-resources/rewriter-packs/basic/dot-paper-e3-1.yaml +9/−0
- test-resources/rewriter-packs/basic/dot-paper-e3-2.yaml +9/−0
- test-resources/rewriter-packs/basic/dot-paper-e4-1.yaml +10/−0
- test-resources/rewriter-packs/basic/dot-paper-e4-2.yaml +9/−0
- test-resources/rewriter-packs/basic/dot-paper-e5-1.yaml +9/−0
- test-resources/rewriter-packs/basic/dot-paper-e5-2.yaml +10/−0
- test-resources/rewriter-packs/basic/dot-recursive.yaml +9/−0
- test-resources/rewriter-packs/basic/dot-skips-lambda-delta.yaml +15/−0
- test-resources/rewriter-packs/basic/dot-with-dd.yaml +9/−0
- test-resources/rewriter-packs/basic/dot-xi.yaml +12/−0
- test-resources/rewriter-packs/basic/miss-from-paper.yaml too large to diff
- test-resources/rewriter-packs/basic/miss-on-empty.yaml too large to diff
- test-resources/rewriter-packs/basic/miss-spares-rho.yaml too large to diff
- test-resources/rewriter-packs/basic/null-from-parer.yaml too large to diff
- test-resources/rewriter-packs/basic/over-alone.yaml too large to diff
- test-resources/rewriter-packs/basic/over-from-paper.yaml too large to diff
- test-resources/rewriter-packs/basic/over-in-back.yaml too large to diff
- test-resources/rewriter-packs/basic/over-in-front.yaml too large to diff
- test-resources/rewriter-packs/basic/over-inside.yaml too large to diff
- test-resources/rewriter-packs/basic/over-long-binding.yaml too large to diff
- test-resources/rewriter-packs/basic/over-with-rho.yaml too large to diff
- test-resources/rewriter-packs/basic/over-without-over.yaml too large to diff
- test-resources/rewriter-packs/basic/skip-drops-an-undeclared-rho.yaml too large to diff
- test-resources/rewriter-packs/basic/skip-leaves-a-declared-rho.yaml too large to diff
- test-resources/rewriter-packs/basic/stay.yaml too large to diff
- test-resources/rewriter-packs/basic/stop-at-lambda.yaml too large to diff
- test-resources/rewriter-packs/basic/stop-at-phi.yaml too large to diff
- test-resources/rewriter-packs/basic/stop-from-paper.yaml too large to diff
- test-resources/rewriter-packs/custom/anonymous-binding-run.yaml too large to diff
- test-resources/rewriter-packs/custom/anonymous-metas.yaml too large to diff
- test-resources/rewriter-packs/custom/applies-a-match-after-one-swallowed-by-another.yaml too large to diff
- test-resources/rewriter-packs/custom/applies-a-match-equal-to-one-swallowed-by-another.yaml too large to diff
- test-resources/rewriter-packs/custom/attribute-from-string.yaml too large to diff
- test-resources/rewriter-packs/custom/concat-from-expression.yaml too large to diff
- test-resources/rewriter-packs/custom/concat-positional-bytes.yaml too large to diff
- test-resources/rewriter-packs/custom/dataize-and-concat.yaml too large to diff
- test-resources/rewriter-packs/custom/desugar-fibo.yaml too large to diff
- test-resources/rewriter-packs/custom/desugar-strings.yaml too large to diff
- test-resources/rewriter-packs/custom/desugares-without-match.yaml too large to diff
- test-resources/rewriter-packs/custom/desugares.yaml too large to diff
- test-resources/rewriter-packs/custom/does-not-fail-on-ambiguous.yaml too large to diff
- test-resources/rewriter-packs/custom/fast-replacing-respects-condition.yaml too large to diff
- test-resources/rewriter-packs/custom/fast-replacing-respects-having.yaml too large to diff
- test-resources/rewriter-packs/custom/java-boxed-method.yaml too large to diff
- test-resources/rewriter-packs/custom/join-renames-sibling-references.yaml too large to diff
- test-resources/rewriter-packs/custom/negative-condition.yaml too large to diff
- test-resources/rewriter-packs/custom/nested-part-of.yaml too large to diff
- test-resources/rewriter-packs/custom/number.yaml too large to diff
- test-resources/rewriter-packs/custom/part-of-after.yaml too large to diff
- test-resources/rewriter-packs/custom/part-of.yaml too large to diff
- test-resources/rewriter-packs/custom/random-tau-mints-fresh.yaml too large to diff
- test-resources/rewriter-packs/custom/random-tau-skips-program-wide.yaml too large to diff
- test-resources/rewriter-packs/custom/replaces-all-in-inner-cycle.yaml too large to diff
- test-resources/rewriter-packs/custom/replaces-formation-deeper-than-max-depth.yaml too large to diff
- test-resources/rewriter-packs/custom/replaces-formation-in-one-cycle.yaml too large to diff
- test-resources/rewriter-packs/custom/same-exprs-in-formation.yaml too large to diff
- test-resources/rewriter-packs/custom/sed-global-anchored-match.yaml too large to diff
- test-resources/rewriter-packs/custom/sed-matches-unicode-characters.yaml too large to diff
- test-resources/rewriter-packs/custom/sed-with-many-arguments.yaml too large to diff
- test-resources/rewriter-packs/custom/sed-with-slashes.yaml too large to diff
- test-resources/rewriter-packs/custom/sed.yaml too large to diff
- test-resources/rewriter-packs/custom/sequential-rules-bug-714.yaml too large to diff
- test-resources/rewriter-packs/custom/size-of-bindings.yaml too large to diff
- test-resources/rewriter-packs/custom/string.yaml too large to diff
- test-resources/rewriter-packs/custom/sum.yaml too large to diff
- test-resources/rewriter-packs/custom/with-alpha-index.yaml too large to diff
- test-resources/rewriter-packs/custom/with-alpha-meta.yaml too large to diff
- test-resources/rewriter-packs/custom/with-complex-condition.yaml too large to diff
- test-resources/rewriter-packs/custom/with-different-metas.yaml too large to diff
- test-resources/rewriter-packs/custom/with-eq-condition.yaml too large to diff
- test-resources/rewriter-packs/custom/with-meta-names.yaml too large to diff
- test-resources/rewriter-packs/custom/with-simple-condition.yaml too large to diff
- test-resources/rewriter-packs/normalize/adds-no-rho.yaml too large to diff
- test-resources/rewriter-packs/normalize/dispatches-rho-on-a-formation-without-rho.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-ald.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-alp.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-ami.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-app.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-cpy-bot.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-cpy.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-dl.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-dl2.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-fnk.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-int.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-lam.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-mut.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-nf.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-nk.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-np.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-nr.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-nt.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-ov2.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-ova.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-phi.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-rep.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-rha.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-rhi.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-rho.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-self.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-twi.yaml too large to diff
- test-resources/rewriter-packs/normalize/e-xxi.yaml too large to diff
- test-resources/rewriter-packs/normalize/hides-the-dispatched-attribute-from-a-sibling.yaml too large to diff
- test-resources/rewriter-packs/normalize/misses-an-undeclared-rho.yaml too large to diff
- test-resources/rewriter-packs/normalize/reaches-a-declared-rho.yaml too large to diff
- test-resources/xmir-parsing-packs/alpha-dispatch-illegal.yaml too large to diff
- test-resources/xmir-parsing-packs/alpha-name-with-base.yaml too large to diff
- test-resources/xmir-parsing-packs/alpha-name-without-base.yaml too large to diff
- test-resources/xmir-parsing-packs/alpha-non-integer-application-arg.yaml too large to diff
- test-resources/xmir-parsing-packs/application-arg-base-and-text.yaml too large to diff
- test-resources/xmir-parsing-packs/application-arg-with-name.yaml too large to diff
- test-resources/xmir-parsing-packs/application-with-dispatch.yaml too large to diff
- test-resources/xmir-parsing-packs/application.yaml too large to diff
- test-resources/xmir-parsing-packs/as-with-colon.yaml too large to diff
- test-resources/xmir-parsing-packs/atoms.yaml too large to diff
- test-resources/xmir-parsing-packs/attribute-uppercase.yaml too large to diff
- test-resources/xmir-parsing-packs/attribute-with-dot.yaml too large to diff
- test-resources/xmir-parsing-packs/base-dispatch.yaml too large to diff
- test-resources/xmir-parsing-packs/base-dot-no-children.yaml too large to diff
- test-resources/xmir-parsing-packs/base-dot-only.yaml too large to diff
- test-resources/xmir-parsing-packs/base-just-dot.yaml too large to diff
- test-resources/xmir-parsing-packs/base-nonsense.yaml too large to diff
- test-resources/xmir-parsing-packs/base-part-with-colon.yaml too large to diff
- test-resources/xmir-parsing-packs/base-root-dot-only.yaml too large to diff
- test-resources/xmir-parsing-packs/bound-rho.yaml too large to diff
- test-resources/xmir-parsing-packs/data-in-dispatched-formation.yaml too large to diff
- test-resources/xmir-parsing-packs/data-in-named-binding.yaml too large to diff
- test-resources/xmir-parsing-packs/declared-rho.yaml too large to diff
- test-resources/xmir-parsing-packs/dispatch-rho.yaml too large to diff
- test-resources/xmir-parsing-packs/dot-only-base.yaml too large to diff
- test-resources/xmir-parsing-packs/double-dot-invalid.yaml too large to diff
- test-resources/xmir-parsing-packs/empty-name-attribute-2.yaml too large to diff
- test-resources/xmir-parsing-packs/empty-name-attribute.yaml too large to diff
- test-resources/xmir-parsing-packs/formation-dispatch.yaml too large to diff
- test-resources/xmir-parsing-packs/formation.yaml too large to diff
- test-resources/xmir-parsing-packs/lambda-derived-name.yaml too large to diff
- test-resources/xmir-parsing-packs/lambda-with-name.yaml too large to diff
- test-resources/xmir-parsing-packs/multiple-root-formations.yaml too large to diff
- test-resources/xmir-parsing-packs/name-at-sign.yaml too large to diff
- test-resources/xmir-parsing-packs/name-capitalized.yaml too large to diff
- test-resources/xmir-parsing-packs/name-with-colon.yaml too large to diff
- test-resources/xmir-parsing-packs/non-package-meta.yaml too large to diff
- test-resources/xmir-parsing-packs/package-capitalized.yaml too large to diff
- test-resources/xmir-parsing-packs/package-with-empty-part.yaml too large to diff
- test-resources/xmir-parsing-packs/phi-dot-only.yaml too large to diff
- test-resources/xmir-parsing-packs/phi-with-application.yaml too large to diff
- test-resources/xmir-parsing-packs/phi-without-base.yaml too large to diff
- test-resources/xmir-parsing-packs/reverse-dispatch.yaml too large to diff
- test-resources/xmir-parsing-packs/rho-with-base.yaml too large to diff
- test-resources/xmir-parsing-packs/root-application-illegal.yaml too large to diff
- test-resources/xmir-parsing-packs/root-element-name-mismatch.yaml too large to diff
- test-resources/xmir-parsing-packs/root-not-object.yaml too large to diff
- test-resources/xmir-parsing-packs/simple.yaml too large to diff
- test-resources/xmir-parsing-packs/termination-base.yaml too large to diff
- test-resources/xmir-parsing-packs/termination-with-application.yaml too large to diff
- test-resources/xmir-parsing-packs/unnamed-formation-child.yaml too large to diff
- test-resources/xmir-parsing-packs/with-duplicate-attribute.yaml too large to diff
- test-resources/xmir-parsing-packs/with-package.yaml too large to diff
- test-resources/xmir-parsing-packs/with-phi.yaml too large to diff
- test-resources/xmir-parsing-packs/with-pretty-printed-package.yaml too large to diff
- test-resources/xmir-parsing-packs/xi-application-illegal.yaml too large to diff
- test-resources/xmir-parsing-packs/xi-dot-only.yaml too large to diff
- test-resources/xmir-parsing-packs/xi-with-application.yaml too large to diff
- test-resources/xmir-printing-packs/application.yaml too large to diff
- test-resources/xmir-printing-packs/declared-rho.yaml too large to diff
- test-resources/xmir-printing-packs/dispatch-chain.yaml too large to diff
- test-resources/xmir-printing-packs/document-author.yaml too large to diff
- test-resources/xmir-printing-packs/formation-argument.yaml too large to diff
- test-resources/xmir-printing-packs/lambda-and-rho.yaml too large to diff
- test-resources/xmir-printing-packs/legacy-positional-data-object.yaml too large to diff
- test-resources/xmir-printing-packs/simple.yaml too large to diff
- test-resources/yaml-packs/simple.yaml too large to diff
- test-resources/yaml-packs/special-attrs-in-condition.yaml too large to diff
- test-resources/yaml-packs/when.yaml too large to diff
- test-resources/yaml-packs/where-without-args.yaml too large to diff
- test-resources/yaml-typos/duplicate-key.yaml too large to diff
- test-resources/yaml-typos/two-condition-objects.yaml too large to diff
- test-resources/yaml-typos/wrong-condition-name.yaml too large to diff
- test/BrokenPipeSpec.hs too large to diff
- test/CLIHelpersSpec.hs too large to diff
- test/CLISpec.hs too large to diff
- test/CanonizerSpec.hs too large to diff
- test/DataizeSpec.hs too large to diff
- test/EmitSpec.hs too large to diff
- test/FilesSpec.hs too large to diff
- test/FilterSpec.hs too large to diff
- test/Fixtures.hs too large to diff
- test/FunctionsSpec.hs too large to diff
- test/LaTeXSpec.hs too large to diff
- test/LambdasSpec.hs too large to diff
- test/LocatorSpec.hs too large to diff
- test/MarginSpec.hs too large to diff
- test/ParserSpec.hs too large to diff
- test/RegexpSpec.hs too large to diff
- test/RenderSpec.hs too large to diff
- test/YamlSpec.hs too large to diff
@@ -34,7 +34,7 @@ ```bash cabal update-cabal install --overwrite-policy=always phino-0.0.148+cabal install --overwrite-policy=always phino-0.0.151 phino --version ``` @@ -59,7 +59,7 @@ for the runner and puts it on the `PATH`: ```yaml-- uses: objectionary/phino@0.0.150+- uses: objectionary/phino@0.0.151 with: version-file: phino-version.txt - run: phino --version@@ -313,6 +313,42 @@ none of them. A formation whose `φ` chain ends in a datum, or which has no `φ` at all, does not join with a bare symbol. +A fork whose one branch calls a method often meets a decorator. In+`if. (value.gte 0) (0.plus value) value.neg` the first branch comes to a+number `X`, while `value.neg` is a method, `times -1 > @`, and comes to+`⟦ φ ↦ X ⟧`, with the number one level down. The two differ in shape, so the+join is refused. An entry that says `lenient: true` beside its `join` block+lets it through:++```yaml+- λ: L_fork+ morph:+ 𝑛1: $.left+ 𝑛2: $.right+ join:+ 𝑛3: [𝑛1, 𝑛2]+ lenient: true+ 𝑛: 𝑛3+```++Every `join` line of such an entry joins a term with a formation whose `φ` is+that term, in either order, and answers `⟦ φ ↦ X ⟧`, with symbols minted inside+`X` the usual way. Where both terms are formations, the one with the longer `φ`+chain is taken for the decorator. The answer drops the `ρ` and the other+attributes of the decorator, so it is not exactly the object either branch+made, which is why an entry is strict unless it says otherwise. Dataization+still reaches the same data through it. An entry that says `lenient: true` and+has no `join` line is refused when the file is read.++A lenient entry also joins a bare symbol with a term that holds exactly one+symbol anywhere inside. In `bool.and` one branch comes to a bare+`⟦ λ ⤍ 𝜎1 ⟧` and the other to `⟦ φ ↦ Φ.bool( if ↦ 𝑘 ) ⟧`, where `𝑘` is+`⟦ λ ⤍ L_fork, φ ↦ ⟦ λ ⤍ 𝜎2 ⟧ ⟧`. The `φ` of the second is a call, so its+`φ` chain ends in no symbol and a strict join stops there. A lenient one+answers a copy of the second term with `𝜎2` replaced by a fresh `𝜎3`, which+stands for either `𝜎1` or `𝜎2`. The copy keeps every binding of the term, `ρ`+included. A term with no symbol, or with two, is still refused.+ One term being `⊥` is the exception, since `if. cond value ⊥` is how EO spells "raise unless `cond`": the program raises on that side of the condition and has a perfectly good value on the other. The join then mints nothing, binds@@ -323,6 +359,32 @@ such a fork too, since that `⊥` is an argument the program wrote rather than one the reduction made. +EO raises with an object too, a copy of `⟦ message ↦ ∅, λ ⤍ L_throw ⟧`, whose+λ function the file leaves out on purpose, so that an error of the program+stays an error at runtime. An entry names such functions under `terminators`:++```yaml+- λ: L_fork+ dataize:+ 𝛿1: $.φ+ morph:+ 𝑛1: $.left+ 𝑛2: $.right+ join:+ 𝑛3: [𝑛1, 𝑛2]+ terminators: [L_throw]+ 𝑛: 𝑛3+```++A `join` line of such an entry takes a formation with `λ ⤍ L_throw`, or an+application of one, for a branch that raises, exactly as it takes `⊥`: it binds+its meta to the other term and writes `terminate(…)`. The morph of an operand+of the entry that comes to such a term stops there, and `--deep` walks none of+its bindings, since its message is what the program reports at runtime and+there is nothing to reduce in it. A name under `terminators` that a key of the+file matches is refused when the file is read, since that function fires+rather than raises.+ Every symbol a join mints is written into the protocol as a fact of its own, so a reader ties it to the two it stands for without diffing the terms; the section on `--protocol` below shows one.@@ -2405,119 +2467,119 @@ === parse/phi === warmup: 3 iterations batches: 10 x 1- total: 1094396.788 μs- avg: 109439.679 μs- min: 101010.304 μs- max: 128313.535 μs- std dev: 10811.808 μs+ total: 2094387.514 μs+ avg: 209438.751 μs+ min: 192641.231 μs+ max: 232222.007 μs+ std dev: 15432.075 μs === parse/xmir === warmup: 3 iterations batches: 10 x 1- total: 5710303.145 μs- avg: 571030.314 μs- min: 504770.068 μs- max: 662347.068 μs- std dev: 46900.536 μs+ total: 9539874.986 μs+ avg: 953987.499 μs+ min: 891243.312 μs+ max: 1017605.607 μs+ std dev: 44263.498 μs === rewrite/normalize === warmup: 3 iterations batches: 10 x 1- total: 11.392 μs- avg: 1.139 μs- min: 0.970 μs- max: 1.628 μs- std dev: 0.177 μs+ total: 20.489 μs+ avg: 2.049 μs+ min: 1.713 μs+ max: 2.604 μs+ std dev: 0.281 μs === print/sweet/multiline === warmup: 3 iterations batches: 10 x 1- total: 2401437.519 μs- avg: 240143.752 μs- min: 213136.984 μs- max: 272722.750 μs- std dev: 16775.737 μs+ total: 4017888.697 μs+ avg: 401788.870 μs+ min: 367355.222 μs+ max: 451665.532 μs+ std dev: 27750.906 μs === print/sweet/flat === warmup: 3 iterations batches: 10 x 1- total: 2416626.820 μs- avg: 241662.682 μs- min: 233315.703 μs- max: 254494.103 μs- std dev: 5589.090 μs+ total: 4129328.874 μs+ avg: 412932.887 μs+ min: 381222.773 μs+ max: 440759.690 μs+ std dev: 15935.378 μs === print/salty/multiline === warmup: 3 iterations batches: 10 x 1- total: 7328848.511 μs- avg: 732884.851 μs- min: 692672.535 μs- max: 772742.324 μs- std dev: 23401.078 μs+ total: 12486021.615 μs+ avg: 1248602.162 μs+ min: 1210030.931 μs+ max: 1315219.913 μs+ std dev: 29724.975 μs === morph/symbolic/demo/e1 === warmup: 3 iterations- batches: 10 x 3- total: 128456.280 μs- avg: 4281.876 μs- min: 4253.475 μs- max: 4312.886 μs- std dev: 20.874 μs+ batches: 10 x 2+ total: 169315.306 μs+ avg: 8465.765 μs+ min: 8399.346 μs+ max: 8543.902 μs+ std dev: 48.118 μs === morph/symbolic/demo/e2 === warmup: 3 iterations- batches: 10 x 5- total: 198825.013 μs- avg: 3976.500 μs- min: 3937.010 μs- max: 4123.529 μs- std dev: 54.483 μs+ batches: 10 x 2+ total: 161881.224 μs+ avg: 8094.061 μs+ min: 7995.987 μs+ max: 8224.079 μs+ std dev: 55.390 μs === morph/symbolic/demo/e3 === warmup: 3 iterations- batches: 10 x 3- total: 171306.263 μs- avg: 5710.209 μs- min: 5671.534 μs- max: 5828.818 μs- std dev: 45.464 μs+ batches: 10 x 2+ total: 234257.502 μs+ avg: 11712.875 μs+ min: 11591.756 μs+ max: 11897.267 μs+ std dev: 100.821 μs === morph/symbolic/demo/e4 === warmup: 3 iterations- batches: 10 x 6- total: 214186.131 μs- avg: 3569.769 μs- min: 3556.854 μs- max: 3596.001 μs- std dev: 11.389 μs+ batches: 10 x 3+ total: 211951.865 μs+ avg: 7065.062 μs+ min: 6976.291 μs+ max: 7108.785 μs+ std dev: 43.882 μs === morph/symbolic/demo/e5 === warmup: 3 iterations- batches: 10 x 15- total: 190902.360 μs- avg: 1272.682 μs- min: 1266.976 μs- max: 1276.589 μs- std dev: 3.073 μs+ batches: 10 x 9+ total: 201954.992 μs+ avg: 2243.944 μs+ min: 2209.663 μs+ max: 2273.110 μs+ std dev: 20.511 μs === morph/symbolic/native/e5 === warmup: 3 iterations batches: 10 x 1- total: 130864.617 μs- avg: 13086.462 μs- min: 12534.939 μs- max: 13730.337 μs- std dev: 404.303 μs+ total: 252909.974 μs+ avg: 25290.997 μs+ min: 24128.018 μs+ max: 26030.789 μs+ std dev: 686.354 μs === morph/symbolic/accum/0 === warmup: 3 iterations- batches: 10 x 3- total: 217771.785 μs- avg: 7259.060 μs- min: 7183.014 μs- max: 7458.925 μs- std dev: 90.688 μs+ batches: 10 x 2+ total: 203382.050 μs+ avg: 10169.102 μs+ min: 10090.947 μs+ max: 10299.047 μs+ std dev: 60.479 μs === morph/symbolic/accum/400 === warmup: 3 iterations batches: 10 x 1- total: 210258.554 μs- avg: 21025.855 μs- min: 20666.196 μs- max: 23018.525 μs- std dev: 672.165 μs+ total: 336426.864 μs+ avg: 33642.686 μs+ min: 33345.536 μs+ max: 33999.930 μs+ std dev: 201.060 μs ``` The results were calculated in [this GHA job][benchmark-gha]-on 2026-09-29 at 12:02,+on 2026-10-09 at 14:39, on Linux with 4 CPUs. <!-- benchmark_end -->@@ -2568,4 +2630,4 @@ [jna-native]: https://github.com/java-native-access/jna/blob/master/src/com/sun/jna/Native.java [jeo]: https://github.com/objectionary/jeo-maven-plugin [issue-1291]: https://github.com/objectionary/phino/issues/1291-[benchmark-gha]: https://github.com/objectionary/phino/actions/runs/36565203496+[benchmark-gha]: https://github.com/objectionary/phino/actions/runs/37945133395
@@ -87,6 +87,7 @@ [] Map.empty lambdas+ [] (building linked) reduction evaluation
@@ -33,12 +33,12 @@ -- The steps of the built-in rules of normalization, in the order of the rules. normalization :: [Ru.Step]-normalization = [stepAlpha, stepAmiss, stepCopy, stepDc, stepDca, stepDd, stepDl, stepDot, stepMiss, stepNull, stepOver, stepOvera, stepSkip, stepStay, stepStop]+normalization = [stepAlpha, stepAmiss, stepCopy, stepDc, stepDca, stepDd, stepDl, stepDot, stepMiss, stepNorho, stepNull, stepOver, stepOvera, stepSkip, stepStay, stepStop] -- The steps of every rule compiled, by the text of the rule. steps :: Map.Map String Ru.Step steps =- Map.fromList [("Rule {name = \"alpha\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) (ArAlpha \945!i1 (ExMeta \"e1\")), result = ExApplication (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) (ArTau !t1 (ExMeta \"e1\")), when = Just (And [Eq (CmpNum (MetaIndex \"i1\")) (CmpNum (Domain (BiMeta \"B1\"))),Not (Eq (CmpAttr !t1) (CmpAttr \961))]), where_ = Nothing, having = Nothing}", stepAlpha), ("Rule {name = \"amiss\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\"]) (ArAlpha \945!i1 (ExAny (Slot \"e\" 11))), result = ExTermination, when = Just (Not (Gt (CmpNum (Domain (BiMeta \"B1\"))) (CmpNum (MetaIndex \"i1\")))), where_ = Nothing, having = Nothing}", stepAmiss), ("Rule {name = \"copy\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) (ArTau !t1 (ExMeta \"k1\")), result = ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"k1\"),BiMeta \"B2\"], when = Nothing, where_ = Nothing, having = Nothing}", stepCopy), ("Rule {name = \"dc\", label = Nothing, description = Nothing, pattern = ExApplication ExTermination (ArTau !t (ExAny (Slot \"e\" 6))), result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", stepDc), ("Rule {name = \"dca\", label = Nothing, description = Nothing, pattern = ExApplication ExTermination (ArAlpha \945!i (ExAny (Slot \"e\" 7))), result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", stepDca), ("Rule {name = \"dd\", label = Nothing, description = Nothing, pattern = ExDispatch ExTermination !t, result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", stepDd), ("Rule {name = \"dl\", label = Nothing, description = Nothing, pattern = ExFormation [BiMeta \"B1\",BiLambda (FnAny (Slot \"F\" 9)),BiMeta \"B2\"], result = ExTermination, when = Just (In [\916] [BiMeta \"B1\",BiMeta \"B2\"]), where_ = Nothing, having = Nothing}", stepDl), ("Rule {name = \"dot\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"n1\"),BiMeta \"B2\"]) !t1, result = ExApplication (ExMeta \"e1\") (ArTau \961 (ExMeta \"e2\")), when = Just (Not (In [\916,\955] [BiMeta \"B1\",BiMeta \"B2\"])), where_ = Just [Extra {meta = ArgExpression (ExMeta \"e1\"), function = \"contextualize\", args = [ArgExpression (ExMeta \"n1\"),ArgExpression (ExFormation [BiMeta \"B1\",BiMeta \"B2\"])]},Extra {meta = ArgExpression (ExMeta \"e2\"), function = \"named\", args = [ArgExpression (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"n1\"),BiMeta \"B2\"])]}], having = Nothing}", stepDot), ("Rule {name = \"miss\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\"]) (ArTau !t1 (ExAny (Slot \"e\" 10))), result = ExTermination, when = Just (And [Not (In [!t1] [BiMeta \"B1\"]),Not (Eq (CmpAttr !t1) (CmpAttr \961))]), where_ = Nothing, having = Nothing}", stepMiss), ("Rule {name = \"null\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) !t1, result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", stepNull), ("Rule {name = \"over\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"e1\"),BiMeta \"B2\"]) (ArTau !t1 (ExMeta \"e2\")), result = ExTermination, when = Just (Not (Eq (CmpAttr !t1) (CmpAttr \961))), where_ = Nothing, having = Nothing}", stepOver), ("Rule {name = \"overa\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"e1\"),BiMeta \"B2\"]) (ArAlpha \945!i1 (ExMeta \"e2\")), result = ExTermination, when = Just (And [Eq (CmpNum (MetaIndex \"i1\")) (CmpNum (Domain (BiMeta \"B1\"))),Not (Eq (CmpAttr !t1) (CmpAttr \961))]), where_ = Nothing, having = Nothing}", stepOvera), ("Rule {name = \"skip\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\"]) (ArTau \961 (ExMeta \"e1\")), result = ExFormation [BiMeta \"B1\"], when = Just (Not (In [\961] [BiMeta \"B1\"])), where_ = Nothing, having = Nothing}", stepSkip), ("Rule {name = \"stay\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiTau \961 (ExMeta \"e1\"),BiMeta \"B2\"]) (ArTau \961 (ExMeta \"e2\")), result = ExFormation [BiMeta \"B1\",BiTau \961 (ExMeta \"e1\"),BiMeta \"B2\"], when = Nothing, where_ = Nothing, having = Nothing}", stepStay), ("Rule {name = \"stop\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\"]) !t1, result = ExTermination, when = Just (Disjoint [!t1,\966,\955] [BiMeta \"B1\"]), where_ = Nothing, having = Nothing}", stepStop)]+ Map.fromList [("Rule {name = \"alpha\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) (ArAlpha \945!i1 (ExMeta \"e1\")), result = ExApplication (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) (ArTau !t1 (ExMeta \"e1\")), when = Just (And [Eq (CmpNum (MetaIndex \"i1\")) (CmpNum (Domain (BiMeta \"B1\"))),Not (Eq (CmpAttr !t1) (CmpAttr \961))]), where_ = Nothing, having = Nothing}", stepAlpha), ("Rule {name = \"amiss\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\"]) (ArAlpha \945!i1 (ExAny (Slot \"e\" 11))), result = ExTermination, when = Just (Not (Gt (CmpNum (Domain (BiMeta \"B1\"))) (CmpNum (MetaIndex \"i1\")))), where_ = Nothing, having = Nothing}", stepAmiss), ("Rule {name = \"copy\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) (ArTau !t1 (ExMeta \"k1\")), result = ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"k1\"),BiMeta \"B2\"], when = Nothing, where_ = Nothing, having = Nothing}", stepCopy), ("Rule {name = \"dc\", label = Nothing, description = Nothing, pattern = ExApplication ExTermination (ArTau !t (ExAny (Slot \"e\" 6))), result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", stepDc), ("Rule {name = \"dca\", label = Nothing, description = Nothing, pattern = ExApplication ExTermination (ArAlpha \945!i (ExAny (Slot \"e\" 7))), result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", stepDca), ("Rule {name = \"dd\", label = Nothing, description = Nothing, pattern = ExDispatch ExTermination !t, result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", stepDd), ("Rule {name = \"dl\", label = Nothing, description = Nothing, pattern = ExFormation [BiMeta \"B1\",BiLambda (FnAny (Slot \"F\" 9)),BiMeta \"B2\"], result = ExTermination, when = Just (In [\916] [BiMeta \"B1\",BiMeta \"B2\"]), where_ = Nothing, having = Nothing}", stepDl), ("Rule {name = \"dot\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"n1\"),BiMeta \"B2\"]) !t1, result = ExApplication (ExMeta \"e1\") (ArTau \961 (ExMeta \"e2\")), when = Just (Not (In [\916,\955] [BiMeta \"B1\",BiMeta \"B2\"])), where_ = Just [Extra {meta = ArgExpression (ExMeta \"e1\"), function = \"contextualize\", args = [ArgExpression (ExMeta \"n1\"),ArgExpression (ExFormation [BiMeta \"B1\",BiMeta \"B2\"])]},Extra {meta = ArgExpression (ExMeta \"e2\"), function = \"named\", args = [ArgExpression (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"n1\"),BiMeta \"B2\"])]}], having = Nothing}", stepDot), ("Rule {name = \"miss\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\"]) (ArTau !t1 (ExAny (Slot \"e\" 10))), result = ExTermination, when = Just (And [Not (In [!t1] [BiMeta \"B1\"]),Not (Eq (CmpAttr !t1) (CmpAttr \961))]), where_ = Nothing, having = Nothing}", stepMiss), ("Rule {name = \"norho\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\"]) \961, result = ExTermination, when = Just (Not (In [\961] [BiMeta \"B1\"])), where_ = Nothing, having = Nothing}", stepNorho), ("Rule {name = \"null\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) !t1, result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", stepNull), ("Rule {name = \"over\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"e1\"),BiMeta \"B2\"]) (ArTau !t1 (ExMeta \"e2\")), result = ExTermination, when = Just (Not (Eq (CmpAttr !t1) (CmpAttr \961))), where_ = Nothing, having = Nothing}", stepOver), ("Rule {name = \"overa\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"e1\"),BiMeta \"B2\"]) (ArAlpha \945!i1 (ExMeta \"e2\")), result = ExTermination, when = Just (And [Eq (CmpNum (MetaIndex \"i1\")) (CmpNum (Domain (BiMeta \"B1\"))),Not (Eq (CmpAttr !t1) (CmpAttr \961))]), where_ = Nothing, having = Nothing}", stepOvera), ("Rule {name = \"skip\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\"]) (ArTau \961 (ExMeta \"e1\")), result = ExFormation [BiMeta \"B1\"], when = Just (Not (In [\961] [BiMeta \"B1\"])), where_ = Nothing, having = Nothing}", stepSkip), ("Rule {name = \"stay\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiTau \961 (ExMeta \"e1\"),BiMeta \"B2\"]) (ArTau \961 (ExMeta \"e2\")), result = ExFormation [BiMeta \"B1\",BiTau \961 (ExMeta \"e1\"),BiMeta \"B2\"], when = Nothing, where_ = Nothing, having = Nothing}", stepStay), ("Rule {name = \"stop\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\"]) !t1, result = ExTermination, when = Just (Disjoint [!t1,\966,\955] [BiMeta \"B1\"]), where_ = Nothing, having = Nothing}", stepStop)] -- The rules of 𝕄, in the order of their files. morphings :: [In.Inference Expression]@@ -50,7 +50,7 @@ -- The texts of the built-in rules of all four judgments this module is made of. sources :: [String]-sources = ["Rule {name = \"alpha\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) (ArAlpha \945!i1 (ExMeta \"e1\")), result = ExApplication (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) (ArTau !t1 (ExMeta \"e1\")), when = Just (And [Eq (CmpNum (MetaIndex \"i1\")) (CmpNum (Domain (BiMeta \"B1\"))),Not (Eq (CmpAttr !t1) (CmpAttr \961))]), where_ = Nothing, having = Nothing}", "Rule {name = \"amiss\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\"]) (ArAlpha \945!i1 (ExAny (Slot \"e\" 11))), result = ExTermination, when = Just (Not (Gt (CmpNum (Domain (BiMeta \"B1\"))) (CmpNum (MetaIndex \"i1\")))), where_ = Nothing, having = Nothing}", "Rule {name = \"copy\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) (ArTau !t1 (ExMeta \"k1\")), result = ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"k1\"),BiMeta \"B2\"], when = Nothing, where_ = Nothing, having = Nothing}", "Rule {name = \"dc\", label = Nothing, description = Nothing, pattern = ExApplication ExTermination (ArTau !t (ExAny (Slot \"e\" 6))), result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", "Rule {name = \"dca\", label = Nothing, description = Nothing, pattern = ExApplication ExTermination (ArAlpha \945!i (ExAny (Slot \"e\" 7))), result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", "Rule {name = \"dd\", label = Nothing, description = Nothing, pattern = ExDispatch ExTermination !t, result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", "Rule {name = \"dl\", label = Nothing, description = Nothing, pattern = ExFormation [BiMeta \"B1\",BiLambda (FnAny (Slot \"F\" 9)),BiMeta \"B2\"], result = ExTermination, when = Just (In [\916] [BiMeta \"B1\",BiMeta \"B2\"]), where_ = Nothing, having = Nothing}", "Rule {name = \"dot\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"n1\"),BiMeta \"B2\"]) !t1, result = ExApplication (ExMeta \"e1\") (ArTau \961 (ExMeta \"e2\")), when = Just (Not (In [\916,\955] [BiMeta \"B1\",BiMeta \"B2\"])), where_ = Just [Extra {meta = ArgExpression (ExMeta \"e1\"), function = \"contextualize\", args = [ArgExpression (ExMeta \"n1\"),ArgExpression (ExFormation [BiMeta \"B1\",BiMeta \"B2\"])]},Extra {meta = ArgExpression (ExMeta \"e2\"), function = \"named\", args = [ArgExpression (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"n1\"),BiMeta \"B2\"])]}], having = Nothing}", "Rule {name = \"miss\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\"]) (ArTau !t1 (ExAny (Slot \"e\" 10))), result = ExTermination, when = Just (And [Not (In [!t1] [BiMeta \"B1\"]),Not (Eq (CmpAttr !t1) (CmpAttr \961))]), where_ = Nothing, having = Nothing}", "Rule {name = \"null\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) !t1, result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", "Rule {name = \"over\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"e1\"),BiMeta \"B2\"]) (ArTau !t1 (ExMeta \"e2\")), result = ExTermination, when = Just (Not (Eq (CmpAttr !t1) (CmpAttr \961))), where_ = Nothing, having = Nothing}", "Rule {name = \"overa\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"e1\"),BiMeta \"B2\"]) (ArAlpha \945!i1 (ExMeta \"e2\")), result = ExTermination, when = Just (And [Eq (CmpNum (MetaIndex \"i1\")) (CmpNum (Domain (BiMeta \"B1\"))),Not (Eq (CmpAttr !t1) (CmpAttr \961))]), where_ = Nothing, having = Nothing}", "Rule {name = \"skip\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\"]) (ArTau \961 (ExMeta \"e1\")), result = ExFormation [BiMeta \"B1\"], when = Just (Not (In [\961] [BiMeta \"B1\"])), where_ = Nothing, having = Nothing}", "Rule {name = \"stay\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiTau \961 (ExMeta \"e1\"),BiMeta \"B2\"]) (ArTau \961 (ExMeta \"e2\")), result = ExFormation [BiMeta \"B1\",BiTau \961 (ExMeta \"e1\"),BiMeta \"B2\"], when = Nothing, where_ = Nothing, having = Nothing}", "Rule {name = \"stop\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\"]) !t1, result = ExTermination, when = Just (Disjoint [!t1,\966,\955] [BiMeta \"B1\"]), where_ = Nothing, having = Nothing}", "ContextualizeRule {name = \"ca\", label = Nothing, match = ExApplication (ExMeta \"n1\") (ArTau !t1 (ExMeta \"e1\")), cmatch = ExMeta \"k1\", cresult = ExApplication (ExMeta \"n2\") (ArTau !t1 (ExMeta \"n3\")), premises = [Premise {result = \"n2\", operation = OpContextualize (ExMeta \"n1\") (ExMeta \"k1\")},Premise {result = \"n3\", operation = OpContextualize (ExMeta \"e1\") (ExMeta \"k1\")}]}", "ContextualizeRule {name = \"caa\", label = Nothing, match = ExApplication (ExMeta \"n1\") (ArAlpha \945!i1 (ExMeta \"e1\")), cmatch = ExMeta \"k1\", cresult = ExApplication (ExMeta \"n2\") (ArAlpha \945!i1 (ExMeta \"n3\")), premises = [Premise {result = \"n2\", operation = OpContextualize (ExMeta \"n1\") (ExMeta \"k1\")},Premise {result = \"n3\", operation = OpContextualize (ExMeta \"e1\") (ExMeta \"k1\")}]}", "ContextualizeRule {name = \"cd\", label = Nothing, match = ExDispatch (ExMeta \"n1\") !t1, cmatch = ExMeta \"k1\", cresult = ExDispatch (ExMeta \"n2\") !t1, premises = [Premise {result = \"n2\", operation = OpContextualize (ExMeta \"n1\") (ExMeta \"k1\")}]}", "ContextualizeRule {name = \"cf\", label = Nothing, match = ExFormation [BiMeta \"B1\"], cmatch = ExMeta \"k1\", cresult = ExFormation [BiMeta \"B1\"], premises = []}", "ContextualizeRule {name = \"cg\", label = Nothing, match = ExRoot, cmatch = ExMeta \"k1\", cresult = ExRoot, premises = []}", "ContextualizeRule {name = \"ct\", label = Nothing, match = ExTermination, cmatch = ExMeta \"k1\", cresult = ExTermination, premises = []}", "ContextualizeRule {name = \"cxi\", label = Nothing, match = ExXi, cmatch = ExMeta \"k1\", cresult = ExMeta \"k1\", premises = []}", "MorphRule {name = \"dead\", label = Nothing, match = ExTermination, ematch = ExMeta \"e1\", nresult = ExTermination, when = Nothing, premises = []}", "MorphRule {name = \"ma\", label = Nothing, match = ExApplication (ExMeta \"n1\") (ArTau !t1 (ExMeta \"k1\")), ematch = ExMeta \"e1\", nresult = ExMeta \"n4\", when = Nothing, premises = [Premise {result = \"n2\", operation = OpMorph (ExMeta \"n1\") (ExMeta \"e1\")},Premise {result = \"n3\", operation = OpNormalize (ExApplication (ExMeta \"n2\") (ArTau !t1 (ExMeta \"k1\")))},Premise {result = \"n4\", operation = OpMorph (ExMeta \"n3\") (ExMeta \"e1\")}]}", "MorphRule {name = \"maa\", label = Nothing, match = ExApplication (ExMeta \"n1\") (ArAlpha \945!i1 (ExMeta \"k1\")), ematch = ExMeta \"e1\", nresult = ExMeta \"n4\", when = Nothing, premises = [Premise {result = \"n2\", operation = OpMorph (ExMeta \"n1\") (ExMeta \"e1\")},Premise {result = \"n3\", operation = OpNormalize (ExApplication (ExMeta \"n2\") (ArAlpha \945!i1 (ExMeta \"k1\")))},Premise {result = \"n4\", operation = OpMorph (ExMeta \"n3\") (ExMeta \"e1\")}]}", "MorphRule {name = \"maad\", label = Nothing, match = ExApplication (ExAny (Slot \"n\" 0)) (ArAlpha \945!i (ExMeta \"n1\")), ematch = ExMeta \"e1\", nresult = ExMeta \"n2\", when = Just (Not (Absolute (ExMeta \"n1\"))), premises = [Premise {result = \"n2\", operation = OpMorph ExTermination (ExMeta \"e1\")}]}", "MorphRule {name = \"mad\", label = Nothing, match = ExApplication (ExAny (Slot \"n\" 0)) (ArTau !t (ExMeta \"n1\")), ematch = ExMeta \"e1\", nresult = ExMeta \"n2\", when = Just (Not (Absolute (ExMeta \"n1\"))), premises = [Premise {result = \"n2\", operation = OpMorph ExTermination (ExMeta \"e1\")}]}", "MorphRule {name = \"md\", label = Nothing, match = ExDispatch (ExMeta \"n1\") !t1, ematch = ExMeta \"e1\", nresult = ExMeta \"n4\", when = Just (Not (IsFormation (ExMeta \"n1\"))), premises = [Premise {result = \"n2\", operation = OpMorph (ExMeta \"n1\") (ExMeta \"e1\")},Premise {result = \"n3\", operation = OpNormalize (ExDispatch (ExMeta \"n2\") !t1)},Premise {result = \"n4\", operation = OpMorph (ExMeta \"n3\") (ExMeta \"e1\")}]}", "MorphRule {name = \"mf\", label = Nothing, match = ExFormation [BiMeta \"B1\"], ematch = ExMeta \"e1\", nresult = ExFormation [BiMeta \"B1\"], when = Nothing, premises = []}", "MorphRule {name = \"mg\", label = Nothing, match = ExRoot, ematch = ExRoot, nresult = ExMeta \"n1\", when = Nothing, premises = [Premise {result = \"n1\", operation = OpMorph ExTermination ExRoot}]}", "MorphRule {name = \"ml\", label = Just \"\\\\lambda\", match = ExDispatch (ExFormation [BiMeta \"B1\",BiLambda (FnMeta \"F1\"),BiMeta \"B2\"]) !t1, ematch = ExMeta \"e1\", nresult = ExMeta \"n3\", when = Nothing, premises = [Premise {result = \"n1\", operation = OpEvaluate (ExFormation [BiMeta \"B1\",BiLambda (FnMeta \"F1\"),BiMeta \"B2\"]) (ExMeta \"e1\")},Premise {result = \"n2\", operation = OpNormalize (ExDispatch (ExMeta \"n1\") !t1)},Premise {result = \"n3\", operation = OpMorph (ExMeta \"n2\") (ExMeta \"e1\")}]}", "MorphRule {name = \"mphi\", label = Just \"\\\\varphi\", match = ExDispatch (ExFormation [BiMeta \"B1\"]) !t1, ematch = ExMeta \"e1\", nresult = ExMeta \"n2\", when = Just (And [In [\966] [BiMeta \"B1\"],Disjoint [!t1,\955] [BiMeta \"B1\"]]), premises = [Premise {result = \"n1\", operation = OpNormalize (ExDispatch (ExDispatch (ExFormation [BiMeta \"B1\"]) \966) !t1)},Premise {result = \"n2\", operation = OpMorph (ExMeta \"n1\") (ExMeta \"e1\")}]}", "MorphRule {name = \"universe\", label = Just \"\\\\Phi\", match = ExRoot, ematch = ExMeta \"e1\", nresult = ExMeta \"n2\", when = Just (Not (Eq (CmpExpr (ExMeta \"e1\")) (CmpExpr ExRoot))), premises = [Premise {result = \"n1\", operation = OpNormalize (ExMeta \"e1\")},Premise {result = \"n2\", operation = OpMorph (ExMeta \"n1\") (ExMeta \"e1\")}]}", "MorphRule {name = \"xi\", label = Nothing, match = ExXi, ematch = ExMeta \"e1\", nresult = ExMeta \"n1\", when = Nothing, premises = [Premise {result = \"n1\", operation = OpMorph ExTermination (ExMeta \"e1\")}]}", "DataizeRule {name = \"box\", label = Nothing, match = ExFormation [BiMeta \"B1\",BiTau \966 (ExMeta \"e2\"),BiMeta \"B2\"], ematch = ExMeta \"e1\", dresult = BtMeta \"d1\", when = Just (Disjoint [\916,\955] [BiMeta \"B1\",BiMeta \"B2\"]), premises = [Premise {result = \"e3\", operation = OpContextualize (ExMeta \"e2\") (ExFormation [BiMeta \"B1\",BiTau \966 (ExMeta \"e2\"),BiMeta \"B2\"])},Premise {result = \"n1\", operation = OpNormalize (ExMeta \"e3\")},Premise {result = \"d1\", operation = OpDataize (ExMeta \"n1\") (ExMeta \"e1\")}]}", "DataizeRule {name = \"delta\", label = Just \"\\\\Delta\", match = ExFormation [BiMeta \"B1\",BiDelta (BtMeta \"d1\"),BiMeta \"B2\"], ematch = ExMeta \"e1\", dresult = BtMeta \"d1\", when = Just (Disjoint [\955] [BiMeta \"B1\",BiMeta \"B2\"]), premises = []}", "DataizeRule {name = \"fire\", label = Nothing, match = ExFormation [BiMeta \"B1\",BiLambda (FnMeta \"F1\"),BiMeta \"B2\"], ematch = ExMeta \"e1\", dresult = BtMeta \"d1\", when = Just (Disjoint [\916] [BiMeta \"B1\",BiMeta \"B2\"]), premises = [Premise {result = \"n1\", operation = OpEvaluate (ExFormation [BiMeta \"B1\",BiLambda (FnMeta \"F1\"),BiMeta \"B2\"]) (ExMeta \"e1\")},Premise {result = \"d1\", operation = OpDataize (ExMeta \"n1\") (ExMeta \"e1\")}]}", "DataizeRule {name = \"none\", label = Nothing, match = ExFormation [BiMeta \"B1\"], ematch = ExMeta \"e1\", dresult = BtMeta \"d1\", when = Just (Disjoint [\916,\955,\966] [BiMeta \"B1\"]), premises = [Premise {result = \"d1\", operation = OpDataize ExTermination (ExMeta \"e1\")}]}", "DataizeRule {name = \"norm\", label = Nothing, match = ExMeta \"n1\", ematch = ExMeta \"e1\", dresult = BtMeta \"d1\", when = Just (And [Not (IsFormation (ExMeta \"n1\")),Not (Eq (CmpExpr (ExMeta \"n1\")) (CmpExpr ExTermination))]), premises = [Premise {result = \"n2\", operation = OpMorph (ExMeta \"n1\") (ExMeta \"e1\")},Premise {result = \"d1\", operation = OpDataize (ExMeta \"n2\") (ExMeta \"e1\")}]}"]+sources = ["Rule {name = \"alpha\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) (ArAlpha \945!i1 (ExMeta \"e1\")), result = ExApplication (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) (ArTau !t1 (ExMeta \"e1\")), when = Just (And [Eq (CmpNum (MetaIndex \"i1\")) (CmpNum (Domain (BiMeta \"B1\"))),Not (Eq (CmpAttr !t1) (CmpAttr \961))]), where_ = Nothing, having = Nothing}", "Rule {name = \"amiss\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\"]) (ArAlpha \945!i1 (ExAny (Slot \"e\" 11))), result = ExTermination, when = Just (Not (Gt (CmpNum (Domain (BiMeta \"B1\"))) (CmpNum (MetaIndex \"i1\")))), where_ = Nothing, having = Nothing}", "Rule {name = \"copy\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) (ArTau !t1 (ExMeta \"k1\")), result = ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"k1\"),BiMeta \"B2\"], when = Nothing, where_ = Nothing, having = Nothing}", "Rule {name = \"dc\", label = Nothing, description = Nothing, pattern = ExApplication ExTermination (ArTau !t (ExAny (Slot \"e\" 6))), result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", "Rule {name = \"dca\", label = Nothing, description = Nothing, pattern = ExApplication ExTermination (ArAlpha \945!i (ExAny (Slot \"e\" 7))), result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", "Rule {name = \"dd\", label = Nothing, description = Nothing, pattern = ExDispatch ExTermination !t, result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", "Rule {name = \"dl\", label = Nothing, description = Nothing, pattern = ExFormation [BiMeta \"B1\",BiLambda (FnAny (Slot \"F\" 9)),BiMeta \"B2\"], result = ExTermination, when = Just (In [\916] [BiMeta \"B1\",BiMeta \"B2\"]), where_ = Nothing, having = Nothing}", "Rule {name = \"dot\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"n1\"),BiMeta \"B2\"]) !t1, result = ExApplication (ExMeta \"e1\") (ArTau \961 (ExMeta \"e2\")), when = Just (Not (In [\916,\955] [BiMeta \"B1\",BiMeta \"B2\"])), where_ = Just [Extra {meta = ArgExpression (ExMeta \"e1\"), function = \"contextualize\", args = [ArgExpression (ExMeta \"n1\"),ArgExpression (ExFormation [BiMeta \"B1\",BiMeta \"B2\"])]},Extra {meta = ArgExpression (ExMeta \"e2\"), function = \"named\", args = [ArgExpression (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"n1\"),BiMeta \"B2\"])]}], having = Nothing}", "Rule {name = \"miss\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\"]) (ArTau !t1 (ExAny (Slot \"e\" 10))), result = ExTermination, when = Just (And [Not (In [!t1] [BiMeta \"B1\"]),Not (Eq (CmpAttr !t1) (CmpAttr \961))]), where_ = Nothing, having = Nothing}", "Rule {name = \"norho\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\"]) \961, result = ExTermination, when = Just (Not (In [\961] [BiMeta \"B1\"])), where_ = Nothing, having = Nothing}", "Rule {name = \"null\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\",BiVoid !t1,BiMeta \"B2\"]) !t1, result = ExTermination, when = Nothing, where_ = Nothing, having = Nothing}", "Rule {name = \"over\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"e1\"),BiMeta \"B2\"]) (ArTau !t1 (ExMeta \"e2\")), result = ExTermination, when = Just (Not (Eq (CmpAttr !t1) (CmpAttr \961))), where_ = Nothing, having = Nothing}", "Rule {name = \"overa\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiTau !t1 (ExMeta \"e1\"),BiMeta \"B2\"]) (ArAlpha \945!i1 (ExMeta \"e2\")), result = ExTermination, when = Just (And [Eq (CmpNum (MetaIndex \"i1\")) (CmpNum (Domain (BiMeta \"B1\"))),Not (Eq (CmpAttr !t1) (CmpAttr \961))]), where_ = Nothing, having = Nothing}", "Rule {name = \"skip\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\"]) (ArTau \961 (ExMeta \"e1\")), result = ExFormation [BiMeta \"B1\"], when = Just (Not (In [\961] [BiMeta \"B1\"])), where_ = Nothing, having = Nothing}", "Rule {name = \"stay\", label = Nothing, description = Nothing, pattern = ExApplication (ExFormation [BiMeta \"B1\",BiTau \961 (ExMeta \"e1\"),BiMeta \"B2\"]) (ArTau \961 (ExMeta \"e2\")), result = ExFormation [BiMeta \"B1\",BiTau \961 (ExMeta \"e1\"),BiMeta \"B2\"], when = Nothing, where_ = Nothing, having = Nothing}", "Rule {name = \"stop\", label = Nothing, description = Nothing, pattern = ExDispatch (ExFormation [BiMeta \"B1\"]) !t1, result = ExTermination, when = Just (Disjoint [!t1,\966,\955] [BiMeta \"B1\"]), where_ = Nothing, having = Nothing}", "ContextualizeRule {name = \"ca\", label = Nothing, match = ExApplication (ExMeta \"n1\") (ArTau !t1 (ExMeta \"e1\")), cmatch = ExMeta \"k1\", cresult = ExApplication (ExMeta \"n2\") (ArTau !t1 (ExMeta \"n3\")), premises = [Premise {result = \"n2\", operation = OpContextualize (ExMeta \"n1\") (ExMeta \"k1\")},Premise {result = \"n3\", operation = OpContextualize (ExMeta \"e1\") (ExMeta \"k1\")}]}", "ContextualizeRule {name = \"caa\", label = Nothing, match = ExApplication (ExMeta \"n1\") (ArAlpha \945!i1 (ExMeta \"e1\")), cmatch = ExMeta \"k1\", cresult = ExApplication (ExMeta \"n2\") (ArAlpha \945!i1 (ExMeta \"n3\")), premises = [Premise {result = \"n2\", operation = OpContextualize (ExMeta \"n1\") (ExMeta \"k1\")},Premise {result = \"n3\", operation = OpContextualize (ExMeta \"e1\") (ExMeta \"k1\")}]}", "ContextualizeRule {name = \"cd\", label = Nothing, match = ExDispatch (ExMeta \"n1\") !t1, cmatch = ExMeta \"k1\", cresult = ExDispatch (ExMeta \"n2\") !t1, premises = [Premise {result = \"n2\", operation = OpContextualize (ExMeta \"n1\") (ExMeta \"k1\")}]}", "ContextualizeRule {name = \"cf\", label = Nothing, match = ExFormation [BiMeta \"B1\"], cmatch = ExMeta \"k1\", cresult = ExFormation [BiMeta \"B1\"], premises = []}", "ContextualizeRule {name = \"cg\", label = Nothing, match = ExRoot, cmatch = ExMeta \"k1\", cresult = ExRoot, premises = []}", "ContextualizeRule {name = \"ct\", label = Nothing, match = ExTermination, cmatch = ExMeta \"k1\", cresult = ExTermination, premises = []}", "ContextualizeRule {name = \"cxi\", label = Nothing, match = ExXi, cmatch = ExMeta \"k1\", cresult = ExMeta \"k1\", premises = []}", "MorphRule {name = \"dead\", label = Nothing, match = ExTermination, ematch = ExMeta \"e1\", nresult = ExTermination, when = Nothing, premises = []}", "MorphRule {name = \"ma\", label = Nothing, match = ExApplication (ExMeta \"n1\") (ArTau !t1 (ExMeta \"k1\")), ematch = ExMeta \"e1\", nresult = ExMeta \"n4\", when = Nothing, premises = [Premise {result = \"n2\", operation = OpMorph (ExMeta \"n1\") (ExMeta \"e1\")},Premise {result = \"n3\", operation = OpNormalize (ExApplication (ExMeta \"n2\") (ArTau !t1 (ExMeta \"k1\")))},Premise {result = \"n4\", operation = OpMorph (ExMeta \"n3\") (ExMeta \"e1\")}]}", "MorphRule {name = \"maa\", label = Nothing, match = ExApplication (ExMeta \"n1\") (ArAlpha \945!i1 (ExMeta \"k1\")), ematch = ExMeta \"e1\", nresult = ExMeta \"n4\", when = Nothing, premises = [Premise {result = \"n2\", operation = OpMorph (ExMeta \"n1\") (ExMeta \"e1\")},Premise {result = \"n3\", operation = OpNormalize (ExApplication (ExMeta \"n2\") (ArAlpha \945!i1 (ExMeta \"k1\")))},Premise {result = \"n4\", operation = OpMorph (ExMeta \"n3\") (ExMeta \"e1\")}]}", "MorphRule {name = \"maad\", label = Nothing, match = ExApplication (ExAny (Slot \"n\" 0)) (ArAlpha \945!i (ExMeta \"n1\")), ematch = ExMeta \"e1\", nresult = ExMeta \"n2\", when = Just (Not (Absolute (ExMeta \"n1\"))), premises = [Premise {result = \"n2\", operation = OpMorph ExTermination (ExMeta \"e1\")}]}", "MorphRule {name = \"mad\", label = Nothing, match = ExApplication (ExAny (Slot \"n\" 0)) (ArTau !t (ExMeta \"n1\")), ematch = ExMeta \"e1\", nresult = ExMeta \"n2\", when = Just (Not (Absolute (ExMeta \"n1\"))), premises = [Premise {result = \"n2\", operation = OpMorph ExTermination (ExMeta \"e1\")}]}", "MorphRule {name = \"md\", label = Nothing, match = ExDispatch (ExMeta \"n1\") !t1, ematch = ExMeta \"e1\", nresult = ExMeta \"n4\", when = Just (Not (IsFormation (ExMeta \"n1\"))), premises = [Premise {result = \"n2\", operation = OpMorph (ExMeta \"n1\") (ExMeta \"e1\")},Premise {result = \"n3\", operation = OpNormalize (ExDispatch (ExMeta \"n2\") !t1)},Premise {result = \"n4\", operation = OpMorph (ExMeta \"n3\") (ExMeta \"e1\")}]}", "MorphRule {name = \"mf\", label = Nothing, match = ExFormation [BiMeta \"B1\"], ematch = ExMeta \"e1\", nresult = ExFormation [BiMeta \"B1\"], when = Nothing, premises = []}", "MorphRule {name = \"mg\", label = Nothing, match = ExRoot, ematch = ExRoot, nresult = ExMeta \"n1\", when = Nothing, premises = [Premise {result = \"n1\", operation = OpMorph ExTermination ExRoot}]}", "MorphRule {name = \"ml\", label = Just \"\\\\lambda\", match = ExDispatch (ExFormation [BiMeta \"B1\",BiLambda (FnMeta \"F1\"),BiMeta \"B2\"]) !t1, ematch = ExMeta \"e1\", nresult = ExMeta \"n3\", when = Nothing, premises = [Premise {result = \"n1\", operation = OpEvaluate (ExFormation [BiMeta \"B1\",BiLambda (FnMeta \"F1\"),BiMeta \"B2\"]) (ExMeta \"e1\")},Premise {result = \"n2\", operation = OpNormalize (ExDispatch (ExMeta \"n1\") !t1)},Premise {result = \"n3\", operation = OpMorph (ExMeta \"n2\") (ExMeta \"e1\")}]}", "MorphRule {name = \"mphi\", label = Just \"\\\\varphi\", match = ExDispatch (ExFormation [BiMeta \"B1\"]) !t1, ematch = ExMeta \"e1\", nresult = ExMeta \"n2\", when = Just (And [In [\966] [BiMeta \"B1\"],Disjoint [!t1,\955] [BiMeta \"B1\"]]), premises = [Premise {result = \"n1\", operation = OpNormalize (ExDispatch (ExDispatch (ExFormation [BiMeta \"B1\"]) \966) !t1)},Premise {result = \"n2\", operation = OpMorph (ExMeta \"n1\") (ExMeta \"e1\")}]}", "MorphRule {name = \"universe\", label = Just \"\\\\Phi\", match = ExRoot, ematch = ExMeta \"e1\", nresult = ExMeta \"n2\", when = Just (Not (Eq (CmpExpr (ExMeta \"e1\")) (CmpExpr ExRoot))), premises = [Premise {result = \"n1\", operation = OpNormalize (ExMeta \"e1\")},Premise {result = \"n2\", operation = OpMorph (ExMeta \"n1\") (ExMeta \"e1\")}]}", "MorphRule {name = \"xi\", label = Nothing, match = ExXi, ematch = ExMeta \"e1\", nresult = ExMeta \"n1\", when = Nothing, premises = [Premise {result = \"n1\", operation = OpMorph ExTermination (ExMeta \"e1\")}]}", "DataizeRule {name = \"box\", label = Nothing, match = ExFormation [BiMeta \"B1\",BiTau \966 (ExMeta \"e2\"),BiMeta \"B2\"], ematch = ExMeta \"e1\", dresult = BtMeta \"d1\", when = Just (Disjoint [\916,\955] [BiMeta \"B1\",BiMeta \"B2\"]), premises = [Premise {result = \"e3\", operation = OpContextualize (ExMeta \"e2\") (ExFormation [BiMeta \"B1\",BiTau \966 (ExMeta \"e2\"),BiMeta \"B2\"])},Premise {result = \"n1\", operation = OpNormalize (ExMeta \"e3\")},Premise {result = \"d1\", operation = OpDataize (ExMeta \"n1\") (ExMeta \"e1\")}]}", "DataizeRule {name = \"delta\", label = Just \"\\\\Delta\", match = ExFormation [BiMeta \"B1\",BiDelta (BtMeta \"d1\"),BiMeta \"B2\"], ematch = ExMeta \"e1\", dresult = BtMeta \"d1\", when = Just (Disjoint [\955] [BiMeta \"B1\",BiMeta \"B2\"]), premises = []}", "DataizeRule {name = \"fire\", label = Nothing, match = ExFormation [BiMeta \"B1\",BiLambda (FnMeta \"F1\"),BiMeta \"B2\"], ematch = ExMeta \"e1\", dresult = BtMeta \"d1\", when = Just (Disjoint [\916] [BiMeta \"B1\",BiMeta \"B2\"]), premises = [Premise {result = \"n1\", operation = OpEvaluate (ExFormation [BiMeta \"B1\",BiLambda (FnMeta \"F1\"),BiMeta \"B2\"]) (ExMeta \"e1\")},Premise {result = \"d1\", operation = OpDataize (ExMeta \"n1\") (ExMeta \"e1\")}]}", "DataizeRule {name = \"none\", label = Nothing, match = ExFormation [BiMeta \"B1\"], ematch = ExMeta \"e1\", dresult = BtMeta \"d1\", when = Just (Disjoint [\916,\955,\966] [BiMeta \"B1\"]), premises = [Premise {result = \"d1\", operation = OpDataize ExTermination (ExMeta \"e1\")}]}", "DataizeRule {name = \"norm\", label = Nothing, match = ExMeta \"n1\", ematch = ExMeta \"e1\", dresult = BtMeta \"d1\", when = Just (And [Not (IsFormation (ExMeta \"n1\")),Not (Eq (CmpExpr (ExMeta \"n1\")) (CmpExpr ExTermination))]), premises = [Premise {result = \"n2\", operation = OpMorph (ExMeta \"n1\") (ExMeta \"e1\")},Premise {result = \"d1\", operation = OpDataize (ExMeta \"n2\") (ExMeta \"e1\")}]}"] -- Whether the term is a normal form: no built-in rule of normalization -- matches anywhere inside it.@@ -72,12 +72,13 @@ , (6, True, rewriteDl) , (7, True, rewriteDot) , (8, True, rewriteMiss)- , (9, True, rewriteNull)- , (10, True, rewriteOver)- , (11, True, rewriteOvera)- , (12, True, rewriteSkip)- , (13, True, rewriteStay)- , (14, True, rewriteStop)+ , (9, True, rewriteNorho)+ , (10, True, rewriteNull)+ , (11, True, rewriteOver)+ , (12, True, rewriteOvera)+ , (13, True, rewriteSkip)+ , (14, True, rewriteStay)+ , (15, True, rewriteStop) ] -- The Contextualization function 𝒞, the conclusion of the one rule matching@@ -221,6 +222,19 @@ | ExApplication x1 (ArTau x2 _) <- [term] , ExFormation x4 <- [x1] , (not (all (`Ru.presentIn` concat [x4]) [x2]) && not (x2 == AtRho))+ ]++-- The rule 'norho'.+stepNorho :: Ru.Step+stepNorho = R.direct "norho" True rewriteNorho++rewriteNorho :: Maybe Expression -> Expression -> [Expression]+rewriteNorho _ term =+ [ ExTermination+ | ExDispatch x1 x2 <- [term]+ , x2 == AtRho+ , ExFormation x3 <- [x1]+ , not (all (`Ru.presentIn` concat [x3]) [AtRho]) ] -- The rule 'null'.
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: phino-version: 0.0.151+version: 0.0.152 license: MIT synopsis: Command-Line Manipulator of 𝜑-Calculus Expressions description: Please see the README on GitHub at <https://github.com/objectionary/phino#readme>@@ -12,7 +12,7 @@ copyright: 2025 Objectionary.com category: Language, Code Analysis build-type: Simple-extra-source-files: resources/normalize/*.yaml resources/morphing/*.yaml resources/dataization/*.yaml resources/contextualization/*.yaml benchmark/demo.phi benchmark/atoms.yaml benchmark/accum.phi benchmark/accum.yaml+extra-source-files: resources/normalize/*.yaml resources/morphing/*.yaml resources/dataization/*.yaml resources/contextualization/*.yaml benchmark/demo.phi benchmark/atoms.yaml benchmark/accum.phi benchmark/accum.yaml test-resources/**/*.yaml test-resources/**/*.phi extra-doc-files: README.md source-repository head@@ -152,6 +152,7 @@ other-modules: AbridgeSpec ASTSpec+ BrokenPipeSpec BuilderSpec BytesSpec CanonizerSpec@@ -226,6 +227,9 @@ time >=1.12 && <1.17, xml-conduit >=1.9 && <1.11, yaml >=0.11.8 && <0.12,++ if !os(windows)+ build-depends: unix >=2.8 && <2.9 build-tool-depends: hspec-discover:hspec-discover >=2.11.0 && <2.12
@@ -0,0 +1,14 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A formation declares a receiver only when it lists ρ among its voids, so a+# dispatch of ρ on one that does not is ⊥. 'stop' leaves it alone while the+# formation has a φ, and morphing would then read ρ through φ (#1859).+name: norho+pattern: ⟦𝐵1⟧.ρ+result: ⊥+when:+ not:+ in:+ - ρ+ - 𝐵1
@@ -92,8 +92,10 @@ val = wordToDouble word in if isNaN val || isInfinite val || isNegativeZero val then Right val- else case properFraction val of- (n, 0.0) -> Left n+ else case properFraction val :: (Integer, Double) of+ (n, 0.0)+ | n >= toInteger (minBound :: Int) && n <= toInteger (maxBound :: Int) ->+ Left (fromInteger n) _ -> Right val where toWord64BE :: [Word8] -> Word64@@ -193,7 +195,7 @@ chr (0x10000 + (code - 0xD800) * 0x400 + (low - 0xDC00)) : go rest' _ -> chr code : go rest else chr code : go rest- goUnicode rest = go rest+ goUnicode rest = '\\' : 'u' : go rest hexQuad :: Char -> Char -> Char -> Char -> Maybe Int hexQuad a b c d = case readHex [a, b, c, d] of [(code, "")] -> Just code@@ -244,11 +246,13 @@ btsSlice :: Int -> Int -> Bytes -> Maybe Bytes btsSlice start len bts- | start < 0 || len < 0 || start + len > length octets = Nothing+ | start < 0 || len < 0 || start > size || len > size - start = Nothing | otherwise = Just (word8ToBytes (take len (drop start octets))) where octets :: [Word8] octets = btsToWord8 bts+ size :: Int+ size = length octets btsShift :: Int -> Bytes -> Bytes btsShift bits bts
@@ -15,11 +15,13 @@ import Data.List (dropWhileEnd) import Data.Version (showVersion) import Files (ensuredFile)+import GHC.IO.Exception (IOErrorType (ResourceVanished)) import Logger import Options.Applicative import Paths_phino (version) import System.Exit (ExitCode (..), exitFailure, exitWith) import System.IO (hPutStrLn, stderr)+import System.IO.Error (ioeGetErrorType) runCLI :: [String] -> IO () runCLI args = handle handler $ do@@ -54,9 +56,11 @@ handler e = case fromException e of Just ExitSuccess -> pure () Just (ExitFailure _) -> exitFailure- _ -> do- logError (show e)- exitFailure+ _ -> case fromException e of+ Just (ioe :: IOError) | ioeGetErrorType ioe == ResourceVanished -> exitWith (ExitFailure 141)+ _ -> do+ logError (show e)+ exitFailure setLogger :: Command -> IO () setLogger cmd = let (level, lns) = case cmd of
@@ -15,14 +15,15 @@ import Canonizer (canonizeExpr, lambdaNames) import Compiled (compiled) import Control.Exception-import Control.Monad ((>=>))-import Data.Char (toLower)+import Control.Monad (when, (>=>))+import Data.Char (isDigit, toLower) import Data.Functor ((<&>)) import Data.IORef import Data.List (intercalate, nub) import qualified Data.Map.Strict as M import Data.Maybe import qualified Data.Text as T+import qualified Data.Yaml as Yaml import Deps (Evaluation (EvRun), Judgment, SaveEvalFunc, SaveStepFunc, dontSaveEval, emptyNesting, emptyProgress, emptyProtocol, endEval, endEvalXml, progressed, saveEval, saveEvalXml, saveStep) import Encoding import Engine (Engine, fresh, yaml)@@ -41,8 +42,8 @@ import qualified Random as R import Rewriter (Rewrittens', stepHeaders) import Sugar (SugarType (SALTY), withoutRho)-import System.Directory (createDirectoryIfMissing)-import System.FilePath (takeDirectory, takeExtension)+import System.Directory (createDirectoryIfMissing, doesDirectoryExist, doesFileExist, listDirectory, removeFile)+import System.FilePath (splitExtension, takeDirectory, takeExtension, (</>)) import System.IO (Handle, IOMode (WriteMode), getContents', hClose, hSetEncoding, openFile, utf8) import Text.Printf (printf) import XMIR (Atoms, expressionToXMIR, parseXMIRThrows, printXMIR, renameAtoms, xmirAtoms, xmirToPhi)@@ -55,8 +56,27 @@ justMeetLength :: Maybe Int -> Int justMeetLength = fromMaybe defaultMeetLength +isStepFileName :: FilePath -> Bool+isStepFileName name = length base == 5 && all isDigit base && ext `elem` [".phi", ".xmir", ".tex"]+ where+ (base, ext) = splitExtension name++clearedStepsDir :: Maybe FilePath -> IO ()+clearedStepsDir Nothing = pure ()+clearedStepsDir (Just dir) = do+ exists <- doesDirectoryExist dir+ when exists (listDirectory dir >>= mapM_ removedIfStepFile)+ where+ removedIfStepFile :: FilePath -> IO ()+ removedIfStepFile name = when (isStepFileName name) (removedFile (dir </> name))+ removedFile :: FilePath -> IO ()+ removedFile path = do+ isFile <- doesFileExist path+ when isFile (removeFile path)+ saveStepFunc :: Maybe FilePath -> PrintContext -> [Expression] -> [Expression] -> IO SaveStepFunc saveStepFunc stepsDir ctx@PrintCtx{..} included excluded = do+ clearedStepsDir stepsDir counter <- newIORef (0 :: Int) let ioToExt :: String ioToExt@@ -152,14 +172,19 @@ (printf "The option --inside requires the input expression to be a formation, but given: %s" (P.printExpression expr)) readInput :: Maybe FilePath -> IO String-readInput inputFile' = case inputFile' of- Just pth -> do- logDebug (printf "Reading from file: '%s'" pth)- readFile =<< ensuredFile pth- Nothing -> do- logDebug "Reading from stdin"- getContents' `catch` (\(e :: SomeException) -> throwIO (CouldNotReadFromStdin (show e)))+readInput inputFile' =+ withoutBOM <$> case inputFile' of+ Just pth -> do+ logDebug (printf "Reading from file: '%s'" pth)+ readFile =<< ensuredFile pth+ Nothing -> do+ logDebug "Reading from stdin"+ getContents' `catch` (\(e :: SomeException) -> throwIO (CouldNotReadFromStdin (show e))) +withoutBOM :: String -> String+withoutBOM ('\xFEFF' : rest) = rest+withoutBOM input = input+ parseInput :: String -> IOFormat -> IO Expression parseInput phi PHI = parseExpressionThrows phi parseInput xmir XMIR = parseXMIRThrows xmir >>= xmirToPhi@@ -236,7 +261,7 @@ printCtxToLatexCtx :: PrintContext -> LatexContext printCtxToLatexCtx PrintCtx{..} =- LatexContext _sugar _line _margin _nonumber _compress _canonize _meetPopularity _meetLength _focus _expression _label _meetPrefix _headers+ LatexContext _sugar _line _margin _nonumber _compress _canonize _meetPopularity _meetLength _focus _expression _label _meetPrefix _headers _hideRho getRules :: Bool -> Bool -> [FilePath] -> IO [Y.Rule] getRules normalize shuffle rules = do@@ -261,8 +286,16 @@ | otherwise = do logDebug (printf "Using rules from files: [%s]" (intercalate ", " rules)) yamls <- mapM ensuredFile (nub rules)- mapM (Y.yamlRule >=> validateRewriteRule) yamls+ mapM (loadRule >=> validateRewriteRule) yamls +loadRule :: FilePath -> IO Y.Rule+loadRule file =+ catch (Y.yamlRule file) reportInvalidRule+ where+ reportInvalidRule :: Yaml.ParseException -> IO Y.Rule+ reportInvalidRule err =+ invalidCLIArguments (printf "Could not load rule from '%s'\n%s" file (Yaml.prettyPrintParseException err))+ validateRewriteRule :: Y.Rule -> IO Y.Rule validateRewriteRule rule = let used = maybe [] (map Y.function) rule.where_@@ -281,7 +314,7 @@ putStrLn content Just file -> do logDebug (printf "The option '--target' is specified, printing to '%s'..." file)- overwrite file content+ overwrite file (content ++ "\n") logDebug (printf "The command result was saved in '%s'" file) engine :: IO Engine
@@ -23,6 +23,13 @@ | cmp num = return num | otherwise = readerError msg +boundedIntOption :: ReadM Int+boundedIntOption = do+ num <- auto :: ReadM Integer+ if num < toInteger (minBound :: Int) || num > toInteger (maxBound :: Int)+ then readerError (printf "value must be between %d and %d" (minBound :: Int) (maxBound :: Int))+ else return (fromInteger num)+ optLogLevel :: Parser LogLevel optLogLevel = option@@ -46,7 +53,7 @@ optLogLines :: Parser Int optLogLines = option- (auto >>= validateIntOption (>= -1) "--log-lines must be >= -1")+ (boundedIntOption >>= validateIntOption (>= -1) "--log-lines must be >= -1") (long "log-lines" <> metavar "LINES" <> help "Amount of lines printed to console per each log operation (0 - print nothing, -1 - no limits)" <> value 25 <> showDefault) optRule :: Parser [FilePath]@@ -74,26 +81,26 @@ optMaxDepth :: Parser Int optMaxDepth = option- (auto >>= validateIntOption (> 0) "--max-depth must be positive")+ (boundedIntOption >>= validateIntOption (> 0) "--max-depth must be positive") (long "max-depth" <> metavar "DEPTH" <> help "Maximum number of rewriting iterations per rule" <> value 25 <> showDefault) optMaxCycles :: Parser Int optMaxCycles = option- (auto >>= validateIntOption (> 0) "--max-cycles must be positive")+ (boundedIntOption >>= validateIntOption (> 0) "--max-cycles must be positive") (long "max-cycles" <> metavar "CYCLES" <> help "Maximum number of rewriting cycles across all rules" <> value 25 <> showDefault) optMaxSteps :: Parser Int optMaxSteps = option- (auto >>= validateIntOption (> 0) "--max-steps must be positive")+ (boundedIntOption >>= validateIntOption (> 0) "--max-steps must be positive") (long "max-steps" <> metavar "STEPS" <> help "Maximum number of nested morphing and dataization steps" <> value 1000 <> showDefault) optMaxFirings :: Parser (Maybe Int) optMaxFirings = optional ( option- (auto >>= validateIntOption (> 0) "--max-firings must be positive")+ (boundedIntOption >>= validateIntOption (> 0) "--max-firings must be positive") (long "max-firings" <> metavar "FIRINGS" <> help "Maximum number of λ functions the whole run may fire, unlimited unless given") ) @@ -101,21 +108,21 @@ optMaxSeconds = optional ( option- (auto >>= validateIntOption (> 0) "--max-seconds must be positive")+ (boundedIntOption >>= validateIntOption (> 0) "--max-seconds must be positive") (long "max-seconds" <> metavar "SECONDS" <> help "Maximum number of seconds the whole run may take, unlimited unless given") ) optMargin :: Parser Int optMargin = option- (auto >>= validateIntOption (> 0) "--margin must be positive")+ (boundedIntOption >>= validateIntOption (> 0) "--margin must be positive") (long "margin" <> help "The maximum right margin for the printed 𝜑-expressions" <> value defaultMargin <> showDefault) optMeetPopularity :: Parser (Maybe Int) optMeetPopularity = optional ( option- ( auto+ ( boundedIntOption >>= validateIntOption (> 0) "--meet-popularity must be positive" >>= validateIntOption (<= 100) "--meet-popularity must be <= 100" )@@ -129,7 +136,7 @@ optMeetLength = optional ( option- (auto >>= validateIntOption (> 0) "--meet-length must be positive")+ (boundedIntOption >>= validateIntOption (> 0) "--meet-length must be positive") ( long "meet-length" <> metavar "NODES" <> help (printf "The minimum length of an expression that fits into \\phinoMeet{}, in AST nodes (default: %d)" defaultMeetLength)@@ -229,7 +236,7 @@ optJobs :: Parser Int optJobs = option- (auto >>= validateIntOption (> 0) "--jobs must be positive")+ (boundedIntOption >>= validateIntOption (> 0) "--jobs must be positive") (long "jobs" <> metavar "JOBS" <> help "Number of workers the --deep walk morphs the bindings of the formation it starts at on, side by side, each with a memo, a tally and fresh names of its own" <> value 1 <> showDefault) optAcyclic :: Parser (Maybe Acyclic)@@ -251,7 +258,9 @@ \over λ names under \"λ\", naming the operands it brings down to data under \"dataize\", the ones \ \it reduces to a normal form under \"morph\", the terms it rewrites by rules of its own under \ \\"rewrite\", the terms of those it stands the data of into unknowns under \"symbolize\" and the \- \pairs of branches it joins into one term under \"join\", and answering with the term under \"𝑛\""+ \pairs of branches it joins into one term under \"join\", whether a join takes a term and a \+ \formation whose φ is that term for one under \"lenient\", the λ functions whose objects a join \+ \takes for a branch that raises under \"terminators\", and answering with the term under \"𝑛\"" ) ) @@ -340,7 +349,7 @@ auto ( long "must" <> metavar "RANGE"- <> help "Must-rewrite range (e.g., '3', '..5', '3..', '3..5'). Stops execution if number of rules applied is not in range. Use 0 to disable."+ <> help "Must-rewrite range (e.g., '3', '..5', '3..', '3..5'). Stops execution if number of rewriting cycles is not in range. Use 0 to disable." <> value MtDisabled <> showDefaultWith show )@@ -539,8 +548,8 @@ <$> ( OptsMatch <$> optLogLevel <*> optLogLines- <*> optSugar- <*> optLineFormat+ <*> optSugar'+ <*> optLineFormat' <*> optional (strOption (long "pattern" <> metavar "EXPRESSION" <> help "Pattern expression to match against")) <*> optional (strOption (long "when" <> metavar "CONDITION" <> help "Predicate for matched substitutions")) <*> argInputFile
@@ -20,7 +20,7 @@ import Data.List (intercalate) import qualified Data.List.NonEmpty as NE import qualified Data.Map.Strict as Map-import Data.Maybe (fromJust, isJust, isNothing)+import Data.Maybe (fromJust, isJust, isNothing, listToMaybe) import qualified Data.Text as T import Dataize import Deps (Judgment (..), dontSaveMade)@@ -34,6 +34,7 @@ import Logger import Margin (defaultMargin) import Merge (merge)+import Metas (Metas (..)) import Morph import Parser (parseExpressionThrows) import qualified Printer as P@@ -41,8 +42,9 @@ import Rewriter import Rule (RuleContext (..), matchExpressionWithRule) import Slots (anonymous)-import System.Directory (doesFileExist, getModificationTime)+import System.Directory (canonicalizePath, doesFileExist, getModificationTime) import System.Exit (exitSuccess)+import System.FilePath (takeDirectory, (</>)) import System.Random (mkStdGen, setStdGen) import Tau (seedTaus) import Text.Printf (printf)@@ -86,10 +88,13 @@ validateOpts = do when (_inPlace && isNothing _inputFile) (invalidCLIArguments "The option --in-place requires an input file") when (_inPlace && isJust _targetFile) (invalidCLIArguments "The options --in-place and --target cannot be used together")- when (_inPlace && _outputFormat /= PHI) (invalidCLIArguments "The option --in-place can only be used together with --output=phi")+ when (_inPlace && _outputFormat /= _inputFormat) (invalidCLIArguments "The option --in-place requires the output format to match the input format") when (_inPlace && _sequence) (invalidCLIArguments "The options --in-place and --sequence cannot be used together, since the file must keep one program")- when (_inPlace && _focus /= "Q") (invalidCLIArguments "The options --in-place and --focus cannot be used together, since the file must keep the whole program")+ focusedExpr <- parseExpressionThrows _focus+ when (_inPlace && focusedExpr /= ExRoot) (invalidCLIArguments "The options --in-place and --focus cannot be used together, since the file must keep the whole program") when (_inPlace && not (null _show)) (invalidCLIArguments "The options --in-place and --show cannot be used together, since the file must keep the whole program")+ when (_inPlace && not (null _hide)) (invalidCLIArguments "The options --in-place and --hide cannot be used together, since the file must keep the whole program")+ when (_inPlace && _hideRho) (invalidCLIArguments "The options --in-place and --hide-rho cannot be used together, since the file must keep the whole program") when (_update && _inPlace) (invalidCLIArguments "The options --update and --in-place cannot be used together") when (_update && isNothing _targetFile) (invalidCLIArguments "The option --update requires --target") when (_update && isNothing _inputFile) (invalidCLIArguments "The option --update requires an input file")@@ -122,13 +127,13 @@ output target expr = case (_inPlace, target, _inputFile) of (True, _, Just file) -> do logDebug (printf "The option '--in-place' is specified, writing back to '%s'..." file)- overwrite file expr+ overwrite file (expr ++ "\n") logDebug (printf "The file '%s' was modified in-place" file) (True, _, Nothing) -> error "The option --in-place requires an input file" (False, Just file, _) -> do logDebug (printf "The option '--target' is specified, printing to '%s'..." file)- overwrite file expr+ overwrite file (expr ++ "\n") logDebug (printf "The command result was saved in '%s'" file) (False, Nothing, _) -> do logDebug "The option '--target' is not specified, printing to console..."@@ -183,7 +188,7 @@ _protocol printCtx ( \record -> do- let ctx = ReduceContext loc loc Nothing _maxDepth _maxCycles (Steps _maxSteps 0) tally minted deadline memo 1 (Just (1, Dataization, loc)) _depthSensitive _shuffle _partial False 1 _acyclic Dataization [] Map.empty lambdas (building linked) reduction evaluation fired save record linked+ let ctx = ReduceContext loc loc Nothing _maxDepth _maxCycles (Steps _maxSteps 0) tally minted deadline memo 1 (Just (1, Dataization, loc)) _depthSensitive _shuffle _partial False 1 _acyclic Dataization [] Map.empty lambdas [] (building linked) reduction evaluation fired save record linked (universe, aiming) <- aimed printCtx Dataization _inside expr ctx started universe aiming dataize universe emptyState aiming@@ -265,7 +270,7 @@ _protocol printCtx ( \record -> do- let ctx = ReduceContext loc loc Nothing _maxDepth _maxCycles (Steps _maxSteps 0) tally minted deadline memo 1 (Just (1, Morphing, loc)) _depthSensitive _shuffle _partial _deep _jobs _acyclic Morphing [] Map.empty lambdas (building linked) reduction evaluation fired save record linked+ let ctx = ReduceContext loc loc Nothing _maxDepth _maxCycles (Steps _maxSteps 0) tally minted deadline memo 1 (Just (1, Morphing, loc)) _depthSensitive _shuffle _partial _deep _jobs _acyclic Morphing [] Map.empty lambdas [] (building linked) reduction evaluation fired save record linked (universe, aiming) <- aimed printCtx Morphing _inside expr ctx started universe aiming morph universe emptyState aiming@@ -400,6 +405,7 @@ ptn <- parseExpressionThrows (fromJust _pattern) condition <- traverse parseConditionThrows _when traverse_ (throwIO . AnonymousMetaInCondition . T.unpack) (anonymous condition)+ traverse_ (throwIO . UnboundMetaInCondition . T.unpack) (listToMaybe (unboundMetas ptn condition)) linked <- engine substs <- matchExpressionWithRule expr (rule ptn condition) (RuleContext (building linked) Nothing linked._normal) if null substs@@ -408,6 +414,10 @@ where rule :: Expression -> Maybe Y.Condition -> Y.Rule rule ptn cnd = Y.Rule "custom" Nothing Nothing ptn ExRoot cnd Nothing Nothing+ unboundMetas :: Expression -> Maybe Y.Condition -> [T.Text]+ unboundMetas ptn condition = filter (`notElem` namedMetas ptn) (namedMetas condition)+ namedMetas :: (Metas a) => a -> [T.Text]+ namedMetas term = filter ((> 1) . T.length) (metas term) runCompile :: OptsCompile -> IO () runCompile OptsCompile{..} = do@@ -415,9 +425,23 @@ source <- either (throwIO . CouldNotCompile) pure (emitted Y.normalizationRules custom Y.contextualizationRules Y.morphingRules Y.dataizationRules current) overwrite _targetFile source logInfo (printf "The rules were compiled into '%s'" _targetFile)- exists <- doesFileExist "cabal.project.local"- if exists- then putStrLn "The file 'cabal.project.local' exists, so add these lines to it to link the compiled rules in:\npackage phino\n flags: +compiled"- else do- overwrite "cabal.project.local" "package phino\n flags: +compiled\n"- logInfo "The file 'cabal.project.local' was written, so the next build links the compiled rules in"+ root <- projectRootOf (takeDirectory _targetFile)+ case root of+ Nothing -> putStrLn "package phino\n flags: +compiled"+ Just dir -> do+ let localFile = dir </> "cabal.project.local"+ exists <- doesFileExist localFile+ if exists+ then putStrLn (printf "The file '%s' exists, so add these lines to it to link the compiled rules in:\npackage phino\n flags: +compiled" localFile)+ else do+ overwrite localFile "package phino\n flags: +compiled\n"+ logInfo (printf "The file '%s' was written, so the next build links the compiled rules in" localFile)+ where+ projectRootOf :: FilePath -> IO (Maybe FilePath)+ projectRootOf dir = do+ full <- canonicalizePath dir+ found <- doesFileExist (full </> "phino.cabal")+ let parent = takeDirectory full+ if found+ then pure (Just full)+ else if parent == full then pure Nothing else projectRootOf parent
@@ -45,6 +45,7 @@ | CouldNotPrintExpressionInXMIR | EmptySubstsOnMatch | AnonymousMetaInCondition String+ | UnboundMetaInCondition String | VersionMismatch String String | CouldNotCompile String | StaleEngine@@ -58,6 +59,8 @@ show EmptySubstsOnMatch = "Provided pattern was not matched, no substitutions are built" show (AnonymousMetaInCondition kind) = printf "Anonymous meta '!%s' cannot be referenced in --when, only a named one can" kind+ show (UnboundMetaInCondition kind) =+ printf "The --when condition reads the meta '!%s' it never binds, since neither --pattern binds it" kind show (VersionMismatch expected actual) = printf "Version mismatch: --pin requires '%s', but this is phino %s" expected actual show (CouldNotCompile reason) = reason
@@ -15,6 +15,7 @@ import Must import Parser (parseExpressionThrows) import Printer+import Sugar (revealXi) import Text.Printf (printf) invalidCLIArguments :: String -> IO a@@ -34,7 +35,7 @@ ( printf "Only dispatch expression started with Φ (or Q) can be used in --%s, but given: %s" opt- (printExpression' expr logPrintConfig)+ (printExpressionWith revealXi expr logPrintConfig) ) validateNoOverlap :: String -> [Expression] -> String -> [Expression] -> IO ()@@ -85,7 +86,9 @@ validateMust' must = for_ (validateMust must) invalidCLIArguments validateXmirOptions :: IOFormat -> [(Bool, String)] -> String -> IO ()-validateXmirOptions XMIR _ focus = when (focus /= "Q") (invalidCLIArguments "Only --focus=Q is allowed to be used with --output=xmir")+validateXmirOptions XMIR _ focus = do+ parsed <- parseExpressionThrows focus+ when (parsed /= ExRoot) (invalidCLIArguments "Only --focus=Q is allowed to be used with --output=xmir") validateXmirOptions _ bools _ = let (bools', opts) = unzip bools in validateBoolOpts (zip bools' (map (printf "The --%s can be used only with --output=xmir") opts))
@@ -4,52 +4,61 @@ module Canonizer (canonize, canonizeExpr, lambdaNames) where import AST+import qualified Data.Map as Map import qualified Data.Text as T import Rewriter (Rewritten) -canonizeBindings :: [Binding] -> Int -> ([Binding], Int)-canonizeBindings [] idx = ([], idx)-canonizeBindings ((BiLambda (Function name)) : rest) idx+type CanonState = (Map.Map T.Text T.Text, Int)++canonizeBindings :: [Binding] -> CanonState -> ([Binding], CanonState)+canonizeBindings [] st = ([], st)+canonizeBindings ((BiLambda (Function name)) : rest) st | name == T.pack "Package" =- let (bds', idx') = canonizeBindings rest idx- in (BiLambda (Function name) : bds', idx')-canonizeBindings ((BiLambda (Function _)) : rest) idx =- let (bds', idx') = canonizeBindings rest (idx + 1)- in (BiLambda (Function (T.pack ("Fn" <> show idx))) : bds', idx')-canonizeBindings (BiTau attr expr : rest) idx =- let (expr', idx') = canonizeExpression expr idx- (bds', idx'') = canonizeBindings rest idx'- in (BiTau attr expr' : bds', idx'')-canonizeBindings (bd : rest) idx =- let (bds', idx') = canonizeBindings rest idx- in (bd : bds', idx')+ let (bds', st') = canonizeBindings rest st+ in (BiLambda (Function name) : bds', st')+canonizeBindings ((BiLambda (Function name)) : rest) (names, idx) =+ case Map.lookup name names of+ Just canonical ->+ let (bds', st') = canonizeBindings rest (names, idx)+ in (BiLambda (Function canonical) : bds', st')+ Nothing ->+ let canonical = T.pack ("Fn" <> show idx)+ (bds', st') = canonizeBindings rest (Map.insert name canonical names, idx + 1)+ in (BiLambda (Function canonical) : bds', st')+canonizeBindings (BiTau attr expr : rest) st =+ let (expr', st') = canonizeExpression expr st+ (bds', st'') = canonizeBindings rest st'+ in (BiTau attr expr' : bds', st'')+canonizeBindings (bd : rest) st =+ let (bds', st') = canonizeBindings rest st+ in (bd : bds', st') -canonizeExpression :: Expression -> Int -> (Expression, Int)-canonizeExpression (ExFormation bds) idx =- let (bds', idx') = canonizeBindings bds idx- in (ExFormation bds', idx')-canonizeExpression (ExDispatch expr attr) idx =- let (expr', idx') = canonizeExpression expr idx- in (ExDispatch expr' attr, idx')-canonizeExpression (ExApplication expr arg) idx =- let (expr', idx') = canonizeExpression expr idx- (arg', idx'') = canonizeArgument arg idx'- in (ExApplication expr' arg', idx'')-canonizeExpression (ExPhiMeet prefix num expr) idx =- let (expr', idx') = canonizeExpression expr idx- in (ExPhiMeet prefix num expr', idx')-canonizeExpression (ExPhiAgain prefix num expr) idx =- let (expr', idx') = canonizeExpression expr idx- in (ExPhiAgain prefix num expr', idx')-canonizeExpression expr idx = (expr, idx)+canonizeExpression :: Expression -> CanonState -> (Expression, CanonState)+canonizeExpression (ExFormation bds) st =+ let (bds', st') = canonizeBindings bds st+ in (ExFormation bds', st')+canonizeExpression (ExDispatch expr attr) st =+ let (expr', st') = canonizeExpression expr st+ in (ExDispatch expr' attr, st')+canonizeExpression (ExApplication expr arg) st =+ let (expr', st') = canonizeExpression expr st+ (arg', st'') = canonizeArgument arg st'+ in (ExApplication expr' arg', st'')+canonizeExpression (ExPhiMeet prefix num expr) st =+ let (expr', st') = canonizeExpression expr st+ in (ExPhiMeet prefix num expr', st')+canonizeExpression (ExPhiAgain prefix num expr) st =+ let (expr', st') = canonizeExpression expr st+ in (ExPhiAgain prefix num expr', st')+canonizeExpression expr st = (expr, st) -canonizeArgument :: Argument -> Int -> (Argument, Int)-canonizeArgument (ArTau attr expr) idx =- let (expr', idx') = canonizeExpression expr idx- in (ArTau attr expr', idx')-canonizeArgument (ArAlpha alpha expr) idx =- let (expr', idx') = canonizeExpression expr idx- in (ArAlpha alpha expr', idx')+canonizeArgument :: Argument -> CanonState -> (Argument, CanonState)+canonizeArgument (ArTau attr expr) st =+ let (expr', st') = canonizeExpression expr st+ in (ArTau attr expr', st')+canonizeArgument (ArAlpha alpha expr) st =+ let (expr', st') = canonizeExpression expr st+ in (ArAlpha alpha expr', st') lambdaNames :: Expression -> [T.Text] lambdaNames (ExFormation bds) = concatMap named bds@@ -66,7 +75,7 @@ lambdaNames _ = [] canonizeExpr :: Expression -> Expression-canonizeExpr expr = fst (canonizeExpression expr 1)+canonizeExpr expr = fst (canonizeExpression expr (Map.empty, 1)) canonize :: [Rewritten] -> [Rewritten] canonize [] = []
@@ -12,7 +12,7 @@ import Data.Char (isAlphaNum, isDigit, toLower, toUpper) import Data.List (intercalate, nub) import qualified Data.Map.Strict as Map-import Data.Maybe (fromMaybe, isJust)+import Data.Maybe (fromMaybe, isJust, isNothing) import qualified Data.Set as Set import qualified Data.Text as T import Deps (Judgment)@@ -217,7 +217,7 @@ refused :: Either String () refused | isJust rule.having = Left (printf "The rule '%s' cannot be compiled, since it has a 'having' condition" rule.name)- | fast rule.pattern rule.result = Left (printf "The rule '%s' cannot be compiled, since it rewrites a formation into a formation the fast way" rule.name)+ | isNothing rule.when && fast rule.pattern rule.result = Left (printf "The rule '%s' cannot be compiled, since it rewrites a formation into a formation the fast way" rule.name) | rooted rule.pattern = Left (printf "The rule '%s' cannot be compiled, since its pattern applies Φ to a ρ" rule.name) | otherwise = Right () walked :: Emitting a -> Either String a
@@ -18,7 +18,7 @@ import qualified Data.Text as T import Deps (Evaluation (..), Judgment (Morphing), State (..), resited) import Engine (Engine (..))-import Lambdas (Lambda (..), Meta (..), joined, matched, minted, symbolized)+import Lambdas (Lambda (..), Meta (..), joined, matched, minted, symbolized, thrown) import Matcher (MetaValue (..), Subst, combine, substEmpty, substSingle, substSlot) import Morph (Answer, Firing (..), Kept (..), ReduceContext (..), ReduceException (..), Refused (..), Steps (..), admitted, charged, counted, deeper, isLambda, lambda, morphing, normalized, opening, recalled, refused, remember, remembered, retained, settled, starved, unparked) import Printer (printFunction)@@ -70,7 +70,7 @@ let ctx = caller{_nesting = caller._nesting + 1} outcome <- try $ do (bound, dataized, conditions) <- foldM (down ctx) (substEmpty, state, []) entry._dataized- (bound', morphed, normals) <- foldM (through ctx) (bound, dataized, []) entry._morphed+ (bound', morphed, normals) <- foldM (through ctx{_throwing = entry._terminators}) (bound, dataized, []) entry._morphed let firing = Firing func (reverse conditions) (reverse normals) known <- remembered caller._memo firing maybe (worked ctx entry firing bound' morphed) (\answer -> (answer, morphed) <$ shown ctx._nesting answer) known@@ -87,7 +87,7 @@ worked ctx entry firing@(Firing _ operands _) bound state' = do rewrote <- foldM (reshaped ctx) bound entry._rewritten stood <- foldM (masked ctx) rewrote entry._symbolized- forked <- foldM (paired ctx (listToMaybe operands)) stood entry._paired+ forked <- foldM (paired ctx entry (listToMaybe operands)) stood entry._paired (answer, state'') <- answered ctx entry operands forked state' remember caller._memo firing answer pure (answer, state'')@@ -156,19 +156,21 @@ where fact :: (Int, Bytes) -> Evaluation fact (fresh, bytes) = EvKnown ctx._nesting fresh bytes- paired :: ReduceContext -> Maybe (Either Int Bytes) -> Subst -> (Meta, (Meta, Meta)) -> IO Subst- paired ctx condition bound (meta, (left, right)) = do+ paired :: ReduceContext -> Lambda -> Maybe (Either Int Bytes) -> Subst -> (Meta, (Meta, Meta)) -> IO Subst+ paired ctx entry condition bound (meta, (left, right)) = do one <- branch left two <- branch right- case (one, two) of- (ExTermination, ExTermination) -> both one two- (ExTermination, _) -> terminating "left" left two- (_, ExTermination) -> terminating "right" right one+ case (raising one, raising two) of+ (True, False) -> terminating "left" left two+ (False, True) -> terminating "right" right one _ -> both one two where+ raising :: Expression -> Bool+ raising ExTermination = True+ raising term = thrown entry._terminators term both :: Expression -> Expression -> IO Subst both one two = do- outcome <- joined one two <$> readIORef ctx._minted+ outcome <- joined entry._lenient one two <$> readIORef ctx._minted case outcome of Nothing -> throwIO (Stuck func) Just (term, made, spent) -> do
@@ -17,16 +17,22 @@ data FsException = FileDoesNotExist {_file :: FilePath} | DirectoryDoesNotExist {_dir :: FilePath}+ | PathIsDirectory {_path :: FilePath} deriving (Exception) instance Show FsException where show FileDoesNotExist{..} = printf "File '%s' does not exist" _file show DirectoryDoesNotExist{..} = printf "Directory '%s' does not exist" _dir+ show PathIsDirectory{..} = printf "'%s' is a directory, while a file is expected" _path ensuredFile :: FilePath -> IO FilePath ensuredFile pth = do- exists <- doesFileExist pth- if exists then pure pth else throwIO (FileDoesNotExist pth)+ isDir <- doesDirectoryExist pth+ if isDir+ then throwIO (PathIsDirectory pth)+ else do+ exists <- doesFileExist pth+ if exists then pure pth else throwIO (FileDoesNotExist pth) overwrite :: FilePath -> String -> IO () overwrite path content = do
@@ -7,12 +7,13 @@ import AST import Control.Exception (throwIO)-import Locator (LocatorException (CanNotFindObjectByLocator, InvalidLocatorProvided))+import Locator (LocatorException (CanNotFindObjectByLocator, CanNotHideWholeProgram, InvalidLocatorProvided)) import Misc import Rewriter exclude' :: Expression -> [Expression] -> IO Expression exclude' expr [] = pure expr+exclude' _ (ExRoot : _) = throwIO (CanNotHideWholeProgram ExRoot) exclude' expr (fqn : remaining) = case fqnToAttrs fqn of Just attrs@(_ : _) -> maybe (throwIO (CanNotFindObjectByLocator fqn)) (`exclude'` remaining) (excludedFormation expr attrs) _ -> throwIO (InvalidLocatorProvided fqn)
@@ -13,6 +13,7 @@ import Control.Monad (when) import qualified Data.ByteString.Char8 as B import Data.Functor+import qualified Data.Map.Strict as Map import qualified Data.Set as Set import qualified Data.Text as T import qualified Data.Text.Encoding as T@@ -21,7 +22,7 @@ import Logger (logDebug) import Matcher import Misc-import Parser (parseAttributeThrows, parseNumberThrows)+import Parser (ParserException (CouldNotParseAttribute), parseAttributeThrows, parseNumberThrows) import Printer (printAttribute, printExpression, printExtraArg) import Random (randomString) import Regexp@@ -101,6 +102,7 @@ case expr' of DataObject _ bytes -> pure (TeBytes bytes) ExApplication (BaseObject "bytes") (ArTau AtPhi (ExFormation bds)) | Just bytes <- delta bds -> pure (TeBytes bytes)+ ExApplication (BaseObject "bytes") (ArAlpha (Alpha 0) (ExFormation bds)) | Just bytes <- delta bds -> pure (TeBytes bytes) ExFormation bds | Just bytes <- delta bds -> pure (TeBytes bytes) _ -> throwIO (userError "Only data objects and bytes are supported by 'dataize' function now") where@@ -142,21 +144,24 @@ parse input = case B.stripPrefix "s/" input of Just body ->- let (pat, rest) = nextUntilSlash body B.empty False- (rep, flag) = nextUntilSlash rest B.empty True- in case flag of- "g" -> pure (pat, rep, True)- "" -> pure (pat, rep, False)- _ -> throwIO (userError "sed pattern must be in format s/pat/rep/[g]")+ let (pat, rest, separator) = nextUntilSlash body B.empty False+ in if separator+ then+ let (rep, flag, _) = nextUntilSlash rest B.empty True+ in case flag of+ "g" -> pure (pat, rep, True)+ "" -> pure (pat, rep, False)+ _ -> throwIO (userError "sed pattern must be in format s/pat/rep/[g]")+ else throwIO (userError "sed pattern must be in format s/pat/rep/[g]") _ -> throwIO (userError "sed pattern must start with s/")- nextUntilSlash :: B.ByteString -> B.ByteString -> Bool -> (B.ByteString, B.ByteString)+ nextUntilSlash :: B.ByteString -> B.ByteString -> Bool -> (B.ByteString, B.ByteString, Bool) nextUntilSlash input acc escape = case B.uncons input of- Nothing -> (acc, B.empty)+ Nothing -> (acc, B.empty, False) Just (h, rest) | h == '\\' -> case B.uncons rest of Just (h', rest') -> nextUntilSlash rest' ((if escape then acc else B.snoc acc '\\') `B.append` B.singleton h') escape- Nothing -> (if escape then acc else B.snoc acc '\\', B.empty)- | h == '/' -> (acc, rest)+ Nothing -> (if escape then acc else B.snoc acc '\\', B.empty, False)+ | h == '/' -> (acc, rest, True) | otherwise -> nextUntilSlash rest (B.snoc acc h) escape _randomString :: BuildTermMethod@@ -175,8 +180,13 @@ _tau :: BuildTermMethod _tau [Y.ArgExpression expr] subst = do TeBytes bts <- _dataize [Y.ArgExpression expr] subst- attr <- parseAttributeThrows (btsToUnescapedStr bts)- pure (TeAttribute attr)+ let str = btsToUnescapedStr bts+ attr <- parseAttributeThrows str+ let notReal = throwIO (CouldNotParseAttribute (printf "'%s' is a meta attribute, not a real one" str))+ case attr of+ AtMeta _ -> notReal+ AtAny _ -> notReal+ _ -> pure (TeAttribute attr) _tau _ _ = throwIO (userError "Function tau() requires exactly 1 argument as expression") _string :: BuildTermMethod@@ -221,37 +231,85 @@ _join :: BuildTermMethod _join [] _ = pure (TeBindings []) _join args subst = do- bds <- buildBindings args+ bds <- buildBindingGroups args TeBindings <$> go bds Set.empty where- buildBindings :: [Y.ExtraArgument] -> IO [Binding]- buildBindings [] = pure []- buildBindings (Y.ArgBinding bd : args') = do+ buildBindingGroups :: [Y.ExtraArgument] -> IO [[Binding]]+ buildBindingGroups [] = pure []+ buildBindingGroups (Y.ArgBinding bd : args') = do bds <- buildBindingThrows bd subst- next <- buildBindings args'- pure (bds ++ next)- buildBindings _ = throwIO (userError "Function join() can work with bindings only")- go :: [Binding] -> Set.Set Attribute -> IO [Binding]+ next <- buildBindingGroups args'+ pure (bds : next)+ buildBindingGroups _ = throwIO (userError "Function join() can work with bindings only")+ go :: [[Binding]] -> Set.Set Attribute -> IO [Binding] go [] _ = pure []- go (bd : bds) attrs =+ go (group : groups) attrs = do+ (renamed, next) <- renameGroup group attrs+ rest <- go groups next+ pure (renamed ++ rest)+ renameGroup :: [Binding] -> Set.Set Attribute -> IO ([Binding], Set.Set Attribute)+ renameGroup bds attrs = do+ let groupAttrs = Set.fromList [attr | bd <- bds, Just attr <- [attributeFromBinding bd]]+ (renamed, used, changes) <- renameBindings bds attrs (Set.union attrs groupAttrs) Map.empty+ pure (map (renameValue changes) renamed, used)+ renameBindings ::+ [Binding] ->+ Set.Set Attribute ->+ Set.Set Attribute ->+ Map.Map Attribute Attribute ->+ IO ([Binding], Set.Set Attribute, Map.Map Attribute Attribute)+ renameBindings [] attrs _ changes = pure ([], attrs, changes)+ renameBindings (bd : bds) attrs unavailable changes = case attributeFromBinding bd of Just attr- | Set.member attr attrs ->- if attr == AtRho || attr == AtDelta || attr == AtLambda- then go bds attrs- else do- new <- case bd of- BiTau _ ex -> (`BiTau` ex) <$> freshAttr- BiVoid _ -> BiVoid <$> freshAttr- other -> pure other- (new :) <$> go bds attrs- | otherwise -> (bd :) <$> go bds (Set.insert attr attrs)- Nothing -> (bd :) <$> go bds attrs- freshAttr :: IO Attribute- freshAttr = do+ | Set.member attr attrs && (attr == AtRho || attr == AtDelta || attr == AtLambda) ->+ renameBindings bds attrs unavailable changes+ | Set.member attr attrs -> do+ new <- freshAttr unavailable+ let renamed = case bd of+ BiTau _ ex -> BiTau new ex+ BiVoid _ -> BiVoid new+ other -> other+ (rest, used, next) <-+ renameBindings+ bds+ (Set.insert new attrs)+ (Set.insert new unavailable)+ (Map.insert attr new changes)+ pure (renamed : rest, used, next)+ | otherwise -> do+ (rest, used, next) <-+ renameBindings+ bds+ (Set.insert attr attrs)+ unavailable+ changes+ pure (bd : rest, used, next)+ Nothing -> do+ (rest, used, next) <- renameBindings bds attrs unavailable changes+ pure (bd : rest, used, next)+ renameValue :: Map.Map Attribute Attribute -> Binding -> Binding+ renameValue changes (BiTau attr expr) = BiTau attr (renameExpression changes expr)+ renameValue _ binding = binding+ renameExpression :: Map.Map Attribute Attribute -> Expression -> Expression+ renameExpression changes expression = case expression of+ ExFormation _ -> expression+ ExApplication expr arg -> ExApplication (renameExpression changes expr) (renameArgument changes arg)+ ExDispatch ExXi attr -> ExDispatch ExXi (Map.findWithDefault attr attr changes)+ ExDispatch expr attr -> ExDispatch (renameExpression changes expr) attr+ ExPhiMeet prefix idx expr -> ExPhiMeet prefix idx (renameExpression changes expr)+ ExPhiAgain prefix idx expr -> ExPhiAgain prefix idx (renameExpression changes expr)+ other -> other+ renameArgument :: Map.Map Attribute Attribute -> Argument -> Argument+ renameArgument changes (ArTau attr expr) = ArTau attr (renameExpression changes expr)+ renameArgument changes (ArAlpha alpha expr) = ArAlpha alpha (renameExpression changes expr)+ freshAttr :: Set.Set Attribute -> IO Attribute+ freshAttr unavailable = do term <- _randomTau [] subst case term of- TeAttribute attr' -> pure attr'+ TeAttribute attr'+ | Set.member attr' unavailable -> freshAttr unavailable+ | otherwise -> pure attr' _ -> throwIO (userError "random-tau() did not return an attribute, internal invariant violated") _unsupported :: BuildTermFunc
@@ -28,6 +28,7 @@ import Bytes (nonFiniteName) import CST import Canonizer (canonize, canonizeExpr)+import Data.Char (isAscii, ord) import Data.List (intercalate, nub, zipWith4) import Data.Maybe (isJust) import qualified Data.Text as T@@ -35,14 +36,14 @@ import Encoding import Lining import Locator (locatedExpression)-import Margin (WithMargin, defaultMargin, withMargin)+import Margin (WithMargin, defaultMargin, withLines) import Matcher import Metas (lonely) import Misc import Render (Render (render)) import Replacer (replaceExpression) import Rewriter (Rewritten, Rewrittens', stepHeaders)-import Sugar (SugarType (SWEET), ToSalty, withSugarType)+import Sugar (SugarType (SWEET), ToSalty, withSugarType, withoutRho) import Text.Printf (printf) import Text.Read (readMaybe) import qualified Yaml as Y@@ -61,10 +62,11 @@ , _label :: Maybe String , _meetPrefix :: Maybe String , _headers :: Bool+ , _hideRho :: Bool } defaultLatexContext :: LatexContext-defaultLatexContext = LatexContext SWEET SINGLELINE defaultMargin False False False defaultMeetPopularity defaultMeetLength ExRoot Nothing Nothing Nothing False+defaultLatexContext = LatexContext SWEET SINGLELINE defaultMargin False False False defaultMeetPopularity defaultMeetLength ExRoot Nothing Nothing Nothing False False defaultMeetPopularity :: Int defaultMeetPopularity = 50@@ -133,7 +135,7 @@ popularity = toDouble _meetPopularity / 100.0 renderToLatex :: (ToSalty a, ToASCII a, ToSingleLine a, ToLaTeX a, WithMargin a, Render a) => a -> LatexContext -> String-renderToLatex renderable LatexContext{..} = T.unpack $ render (toLaTeX $ withLineFormat _line $ withMargin _margin $ withEncoding ASCII $ withSugarType _sugar renderable)+renderToLatex renderable LatexContext{..} = T.unpack $ render (toLaTeX $ withLines _line _margin $ withEncoding ASCII $ withSugarType _sugar renderable) phiquation :: LatexContext -> String phiquation LatexContext{_nonumber = True} = "phiquation*"@@ -220,7 +222,7 @@ pure ( concat [ preamble ctx- , body (stepComments rewrittens ctx) (canonizedRewrittens (compressedRewrittens rewrittens ctx) ctx) (\tabs expr -> renderToLatex (expressionToCSTFrom tabs expr) ctx)+ , body (stepComments rewrittens ctx) (canonizedRewrittens (compressedRewrittens rewrittens ctx) ctx) (\tabs expr -> renderToLatex (shown ctx (expressionToCSTFrom tabs expr)) ctx) , ending exceeded (last (arrows (map snd rewrittens))) ctx ] )@@ -230,16 +232,21 @@ pure ( concat [ preamble ctx- , body (stepComments rewrittens ctx) (zip (canonizedExpressions (compressedExpressions focused ctx) ctx) rules) (\tabs expr -> renderToLatex (expressionToCSTFrom tabs expr) ctx)+ , body (stepComments rewrittens ctx) (zip (canonizedExpressions (compressedExpressions focused ctx) ctx) rules) (\tabs expr -> renderToLatex (shown ctx (expressionToCSTFrom tabs expr)) ctx) , ending exceeded (last (arrows (map snd rewrittens))) ctx ] ) +shown :: LatexContext -> EXPRESSION -> EXPRESSION+shown LatexContext{..}+ | _hideRho = withoutRho _sugar+ | otherwise = id+ expressionToLaTeX :: Expression -> LatexContext -> String expressionToLaTeX ex ctx = concat [ preamble ctx- , renderToLatex (expressionToCST ex) ctx+ , renderToLatex (shown ctx (expressionToCST ex)) ctx , period ctx ] @@ -357,7 +364,12 @@ escape '{' = "\\char123{}" escape '}' = "\\char125{}" escape '~' = "\\char126{}"- escape ch = T.singleton ch+ escape 'ρ' = render RHO'+ escape 'ξ' = render XI'+ escape 'φ' = "\\phiTerminal{\\varphi}"+ escape ch+ | isAscii ch = T.singleton ch+ | otherwise = T.pack (printf "[U+%04X]" (ord ch)) instance ToLaTeX SET where toLaTeX ST_BINDING{..} = ST_BINDING (toLaTeX binding)
@@ -18,15 +18,17 @@ , readLambdas , symbolized , taken+ , thrown ) where import AST+import Control.Applicative ((<|>)) import Control.Exception (Exception, throwIO) import Control.Monad (void) import Data.Aeson (FromJSON (parseJSON), Key, Object, Value (Object), withObject, (.!=), (.:), (.:?)) import Data.Char (isDigit)-import Data.List (find, sortOn)+import Data.List (find, nub, sortOn) import Data.Map.Strict (Map) import qualified Data.Map.Strict as Map import Data.Maybe (listToMaybe)@@ -57,6 +59,8 @@ , _rewritten :: [(Meta, (Meta, [Y.Rule]))] , _symbolized :: [(Meta, Expression)] , _paired :: [(Meta, (Meta, Meta))]+ , _lenient :: Bool+ , _terminators :: [Text] , _answer :: Expression } @@ -81,6 +85,8 @@ <*> rewrites (T.unpack key) entry <*> operands key expressionMeta entry "symbolize" <*> pairs (T.unpack key) entry+ <*> entry .:? "lenient" .!= False+ <*> entry .:? "terminators" .!= [] <*> pure answer sigmas (T.unpack key) lambda._answer dataless (T.unpack key) lambda._answer@@ -89,6 +95,7 @@ mapM_ (metaless (T.unpack key) "dataize") lambda._dataized mapM_ (metaless (T.unpack key) "morph") lambda._morphed answered (T.unpack key) lambda+ lonely (T.unpack key) lambda pure lambda where operands :: Text -> (Text -> Yaml.Parser Meta) -> Object -> Key -> Yaml.Parser [(Meta, Expression)]@@ -236,6 +243,10 @@ ++ map (_name . fst) lambda._rewritten ++ map (_name . fst) lambda._symbolized ++ map (_name . fst) lambda._paired+ lonely :: String -> Lambda -> Yaml.Parser ()+ lonely key lambda+ | lambda._lenient && null lambda._paired = fail (printf "The λ function '%s' is lenient but has no 'join' line to be lenient in" key)+ | otherwise = pure () dataless :: String -> Expression -> Yaml.Parser () dataless key answer | computes answer = fail (printf "The '𝑛' of λ function '%s' reads data, while a symbolic answer may mention nothing but 𝜎" key)@@ -281,6 +292,7 @@ mapM_ (unique entries) entries registered <- mapM keyed entries overlaps path registered+ mapM_ (unanswered registered) entries logDebug (printf "Loaded %d λ function(s) from '%s'" (length entries) path) pure (Lambdas registered) where@@ -297,6 +309,15 @@ unreadable :: Text -> (a, String) -> IO b unreadable key (_, failure) = throwIO (BrokenLambdas path (printf "the key '%s' is not a regular expression: %s" (T.unpack key) failure))+ unanswered :: [(Regex, Lambda)] -> Lambda -> IO ()+ unanswered registered entry = case [(name, other) | name <- entry._terminators, Just other <- [matched (Lambdas registered) name]] of+ [] -> pure ()+ (name, other) : _ ->+ throwIO+ ( BrokenLambdas+ path+ (printf "the terminator '%s' of the key '%s' is answered by the key '%s'" (T.unpack name) (T.unpack entry._key) (T.unpack other._key))+ ) overlaps :: FilePath -> [(Regex, Lambda)] -> IO () overlaps _ [_] = pure ()@@ -325,6 +346,11 @@ matched :: Lambdas -> Text -> Maybe Lambda matched (Lambdas entries) func = snd <$> find (\(key, _) -> matchTest key (encodeUtf8 func)) entries +thrown :: [Text] -> Expression -> Bool+thrown names (ExApplication expr _) = thrown names expr+thrown names (ExFormation bds) = any (`elem` [BiLambda (Function name) | name <- names]) bds+thrown _ _ = False+ minted :: Expression -> Int -> ([(Slot, Function)], Int) minted answer spent = (zip fresh [FnSymbol idx | idx <- [spent + 1 ..]], spent + length fresh) where@@ -381,40 +407,62 @@ type Joining = (Int, Map (Int, Int) Int, [(Int, (Int, Int))]) -joined :: Expression -> Expression -> Int -> Maybe (Expression, [(Int, (Int, Int))], Int)-joined left right spent = taking <$> goExpr left right (spent, Map.empty, [])+joined :: Bool -> Expression -> Expression -> Int -> Maybe (Expression, [(Int, (Int, Int))], Int)+joined lenient left right spent = taking <$> goExpr left right (spent, Map.empty, []) where taking :: (Expression, Joining) -> (Expression, [(Int, (Int, Int))], Int) taking (term, (spent', _, made)) = (term, reverse made, spent') goExpr :: Expression -> Expression -> Joining -> Maybe (Expression, Joining)- goExpr one@(ExFormation _) two@(ExFormation _) joining+ goExpr one two joining = goAlike one two joining <|> goSole one two joining <|> goDecorated one two joining+ goAlike :: Expression -> Expression -> Joining -> Maybe (Expression, Joining)+ goAlike one@(ExFormation _) two@(ExFormation _) joining | bare one /= bare two = do mine <- ending one theirs <- ending two (bd, joining') <- goBinding mine theirs joining pure (ExFormation [bd], joining')- goExpr (ExFormation one) (ExFormation two) joining = do+ goAlike (ExFormation one) (ExFormation two) joining = do (bds, joining') <- goBindings one two joining pure (ExFormation bds, joining')- goExpr (ExApplication one arg) (ExApplication two arg') joining = do+ goAlike (ExApplication one arg) (ExApplication two arg') joining = do (expr, joining') <- goExpr one two joining (applied, joining'') <- goArgument arg arg' joining' pure (ExApplication expr applied, joining'')- goExpr (ExDispatch one attr) (ExDispatch two attr') joining+ goAlike (ExDispatch one attr) (ExDispatch two attr') joining | attr == attr' = do (expr, joining') <- goExpr one two joining pure (ExDispatch expr attr, joining')- goExpr (ExPhiMeet prefix idx one) (ExPhiMeet prefix' idx' two) joining+ goAlike (ExPhiMeet prefix idx one) (ExPhiMeet prefix' idx' two) joining | prefix == prefix' && idx == idx' = do (expr, joining') <- goExpr one two joining pure (ExPhiMeet prefix idx expr, joining')- goExpr (ExPhiAgain prefix idx one) (ExPhiAgain prefix' idx' two) joining+ goAlike (ExPhiAgain prefix idx one) (ExPhiAgain prefix' idx' two) joining | prefix == prefix' && idx == idx' = do (expr, joining') <- goExpr one two joining pure (ExPhiAgain prefix idx expr, joining')- goExpr one two joining+ goAlike one two joining | one == two = Just (one, joining) | otherwise = Nothing+ goSole :: Expression -> Expression -> Joining -> Maybe (Expression, Joining)+ goSole (ExFormation [BiLambda (FnSymbol mine)]) two joining+ | lenient, [theirs] <- nub (symbols two) = Just (renamed theirs two (picked (mine, theirs) joining))+ goSole one (ExFormation [BiLambda (FnSymbol theirs)]) joining+ | lenient, [mine] <- nub (symbols one) = Just (renamed mine one (picked (mine, theirs) joining))+ goSole _ _ _ = Nothing+ renamed :: Int -> Expression -> (Int, Joining) -> (Expression, Joining)+ renamed old term (fresh, joining) = (lifted (old - 1) (fresh - old) term, joining)+ goDecorated :: Expression -> Expression -> Joining -> Maybe (Expression, Joining)+ goDecorated one two joining+ | bare one || bare two = Nothing+ | lenient && depth one < depth two = peeled (goExpr one) two+ | lenient && depth two < depth one = peeled (`goExpr` two) one+ | otherwise = Nothing+ where+ peeled :: (Expression -> Joining -> Maybe (Expression, Joining)) -> Expression -> Maybe (Expression, Joining)+ peeled pairing decorator = do+ inner <- decorated decorator+ (expr, joining') <- pairing inner joining+ pure (ExFormation [BiTau AtPhi expr], joining') goBindings :: [Binding] -> [Binding] -> Joining -> Maybe ([Binding], Joining) goBindings [] [] joining = Just ([], joining) goBindings (one : rest) (two : rest') joining = do@@ -439,8 +487,12 @@ bare _ = False ending :: Expression -> Maybe Binding ending (ExFormation [bd@(BiLambda (FnSymbol _))]) = Just bd- ending (ExFormation bds) = listToMaybe [body | BiTau AtPhi body <- bds] >>= ending- ending _ = Nothing+ ending term = decorated term >>= ending+ decorated :: Expression -> Maybe Expression+ decorated (ExFormation bds) = listToMaybe [body | BiTau AtPhi body <- bds]+ decorated _ = Nothing+ depth :: Expression -> Int+ depth term = maybe 0 (succ . depth) (decorated term) goArgument :: Argument -> Argument -> Joining -> Maybe (Argument, Joining) goArgument (ArTau attr one) (ArTau attr' two) joining | attr == attr' = do
@@ -16,6 +16,7 @@ data LocatorException = InvalidLocatorProvided {fqn :: Expression} | CanNotFindObjectByLocator {fqn :: Expression}+ | CanNotHideWholeProgram {fqn :: Expression} deriving (Exception) instance Show LocatorException where@@ -24,6 +25,10 @@ "Invalid locator is provided. 'Q' or dispatch started with 'Q' expected, but got: '%s'" (printExpression fqn) show CanNotFindObjectByLocator{..} = printf "Can't find object by locator: '%s'" (printExpression fqn)+ show CanNotHideWholeProgram{..} =+ printf+ "The --hide locator must name an attribute, '%s' would hide the whole program"+ (printExpression fqn) locatedExpression :: Expression -> Expression -> IO Expression locatedExpression ExRoot expr = pure expr
@@ -5,11 +5,11 @@ -- SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com -- SPDX-License-Identifier: MIT -module Margin (defaultMargin, withMargin, WithMargin) where+module Margin (defaultMargin, withMargin, withLines, WithMargin) where import CST import qualified Data.Text as T-import Lining (ToSingleLine (..))+import Lining (LineFormat (..), ToSingleLine (..)) import Render (Render (..)) defaultMargin :: Int@@ -18,6 +18,10 @@ withMargin :: (WithMargin a) => Int -> a -> a withMargin margin = withMargin' (0, margin) +withLines :: (WithMargin a, ToSingleLine a) => LineFormat -> Int -> a -> a+withLines SINGLELINE _ = toSingleLine+withLines MULTILINE margin = withMargin margin+ class WithMargin a where withMargin' :: (Int, Int) -> a -> a @@ -102,4 +106,38 @@ withMargin' _ = id lengthOf :: Render a => a -> Int-lengthOf renderable = T.length (render renderable)+lengthOf renderable = displayWidth (render renderable)++displayWidth :: T.Text -> Int+displayWidth = T.foldl' addWidth 0+ where+ addWidth :: Int -> Char -> Int+ addWidth acc character = acc + charWidth character++charWidth :: Char -> Int+charWidth character+ | isWideCodePoint (fromEnum character) = 2+ | otherwise = 1+ where+ isWideCodePoint :: Int -> Bool+ isWideCodePoint codePoint = any (inRange codePoint) wideRanges++ inRange :: Int -> (Int, Int) -> Bool+ inRange codePoint (lo, hi) = codePoint >= lo && codePoint <= hi++ wideRanges :: [(Int, Int)]+ wideRanges =+ [ (0x1100, 0x115F)+ , (0x2E80, 0x303E)+ , (0x3041, 0x33FF)+ , (0x3400, 0x4DBF)+ , (0x4E00, 0x9FFF)+ , (0xA000, 0xA4CF)+ , (0xAC00, 0xD7A3)+ , (0xF900, 0xFAFF)+ , (0xFE30, 0xFE4F)+ , (0xFF00, 0xFF60)+ , (0xFFE0, 0xFFE6)+ , (0x1F300, 0x1FAFF)+ , (0x20000, 0x3FFFD)+ ]
@@ -31,7 +31,7 @@ import Engine (Engine (..)) import GHC.Clock (getMonotonicTime) import qualified Inference as In-import Lambdas (Lambdas, emptyLambdas)+import Lambdas (Lambdas, emptyLambdas, thrown) import Locator (locatedExpression, withLocatedExpression) import Matcher (substEmpty) import Must (Must (..))@@ -110,6 +110,7 @@ , _parked :: [T.Text] , _entered :: Seen , _symbolic :: Lambdas+ , _throwing :: [T.Text] , _buildTerm :: BuildTermFunc , _reduce :: ReductionFunc , _evaluate :: EvaluationFunc@@ -120,7 +121,7 @@ } data Budget- = Depth Int+ = Depth Judgment Int | Firings Int | Cycles Int @@ -137,8 +138,8 @@ deriving anyclass (Exception) instance Show ReduceException where- show (OutOfSteps (Depth limit)) =- printf "Dataization did not finish before reaching the limit of steps: --max-steps=%d" limit+ show (OutOfSteps (Depth judgment limit)) =+ printf "%s did not finish before reaching the limit of steps: --max-steps=%d" (show judgment) limit show (OutOfSteps (Firings limit)) = printf "Evaluation did not finish before reaching the limit of firings: --max-firings=%d" limit show (OutOfSteps (Cycles limit)) =@@ -151,7 +152,7 @@ show (Looping term) = printf "Reduction entered a formation it is already inside: %s" (printExpression term) show (LoopingAt term _ _) = show (Looping term) show (Undataizable ExTermination _) = "dataization reached the terminator ⊥, which signals an error and cannot be dataized"- show (Undataizable _ _) = "no dataization rule matched"+ show (Undataizable term _) = printf "no dataization rule matched, while dataization expects a normal form: %s" (printExpression term) show (Unmorphable term) = printf "Morphing expects a normal form, but no morphing rule matches: %s" (printExpression term) data Refused = Refused Acyclic Expression State@@ -172,7 +173,7 @@ when (spent >= limit) $ do starve ctx._memo ctx._saveEval (EvStarved ctx._nesting limit ctx._judgment ctx._site)- throwIO (OutOfSteps (Depth limit))+ throwIO (OutOfSteps (Depth ctx._judgment limit)) pure ctx{_steps = Steps limit (spent + 1)} where starve :: Maybe Memo -> IO ()@@ -400,7 +401,7 @@ marked ctx func = (walking ctx){_parked = func : _parked} walked :: ReduceContext -> Expression -> NonEmpty Rewritten -> State -> IO (Expression, [Rewritten], State) walked walker morphed seq state'- | not _deep = pure (morphed, reverse (NE.toList seq), state')+ | not _deep || thrown _throwing morphed = pure (morphed, reverse (NE.toList seq), state') | otherwise = do (deep, state'') <- deepened Nothing morphed universe state' walker seq' <- leadsTo seq (Morphing, "deep") deep walker@@ -555,36 +556,39 @@ (entered, state'') <- pooled caller._jobs jobs (gathered floor') ([], state') pure (ExFormation (reverse entered), state'') where- planned :: Int -> Maybe (Expression, [Attribute]) -> (Int, Binding) -> IO (IO ([Evaluation], Int, Either SomeException (Int -> IO (Binding, Maybe State))))+ planned :: Int -> Maybe (Expression, [Attribute]) -> (Int, Binding) -> IO (IO ([Evaluation], [Expression], Int, Either SomeException (Int -> IO (Binding, Maybe State)))) planned floor' alias (idx, BiTau attr body) | attr /= AtRho = do new <- if closed body then fresh alias attr caller else pure True pure (if new then worker floor' idx attr body else kept (BiTau attr body)) planned _ _ (_, bd) = pure (kept bd)- kept :: Binding -> IO ([Evaluation], Int, Either SomeException (Int -> IO (Binding, Maybe State)))- kept bd = pure ([], 0, Right (const (pure (bd, Nothing))))- worker :: Int -> Int -> Attribute -> Expression -> IO ([Evaluation], Int, Either SomeException (Int -> IO (Binding, Maybe State)))+ kept :: Binding -> IO ([Evaluation], [Expression], Int, Either SomeException (Int -> IO (Binding, Maybe State)))+ kept bd = pure ([], [], 0, Right (const (pure (bd, Nothing))))+ worker :: Int -> Int -> Attribute -> Expression -> IO ([Evaluation], [Expression], Int, Either SomeException (Int -> IO (Binding, Maybe State))) worker floor' idx attr body = do buffer <- newIORef []+ steps <- newIORef [] tau <- tausOf idx tally <- tallied (fmap (\(Tally cap _) -> cap) caller._tally) minted <- newIORef floor' memo <- memoized caller._acyclic copy <- newIORef =<< readIORef world (store, path) <- home standing copy form- let own = caller{_jobs = 1, _tally = tally, _minted = minted, _memo = memo, _saveEval = modifyIORef' buffer . (:), _buildTerm = minting tau caller._buildTerm}+ let own = caller{_jobs = 1, _tally = tally, _minted = minted, _memo = memo, _saveEval = modifyIORef' buffer . (:), _saveStep = modifyIORef' steps . (:), _buildTerm = minting tau caller._buildTerm} outcome <- try (try (go (fmap (`ExDispatch` attr) standing) Nothing (Frame copy store path (Just attr)) body state' own)) records <- reverse <$> readIORef buffer+ taken' <- reverse <$> readIORef steps spent <- subtract floor' <$> readIORef minted- pure (records, spent, fmap (either (severed floor') (\(term, walked) offset -> pure (BiTau attr (lifted floor' offset term), Just (moved floor' offset walked)))) outcome)+ pure (records, taken', spent, fmap (either (severed floor') (\(term, walked) offset -> pure (BiTau attr (lifted floor' offset term), Just (moved floor' offset walked)))) outcome) severed :: Int -> Severed -> Int -> IO (Binding, Maybe State) severed floor' (Severed answer reached) offset = throwIO (Severed (lifted floor' offset answer) (moved floor' offset reached)) moved :: Int -> Int -> State -> State moved floor' offset walked = walked{_manufactured = fmap (\sym -> if sym > floor' then sym + offset else sym) walked._manufactured}- gathered :: Int -> ([Binding], State) -> ([Evaluation], Int, Either SomeException (Int -> IO (Binding, Maybe State))) -> IO ([Binding], State)- gathered floor' (done, current) (records, spent, outcome) = do+ gathered :: Int -> ([Binding], State) -> ([Evaluation], [Expression], Int, Either SomeException (Int -> IO (Binding, Maybe State))) -> IO ([Binding], State)+ gathered floor' (done, current) (records, taken', spent, outcome) = do offset <- subtract floor' <$> readIORef caller._minted mapM_ (caller._saveEval . renumbered floor' offset) records+ mapM_ caller._saveStep taken' modifyIORef' caller._minted (+ spent) (bd, walked) <- either throwIO ($ offset) outcome pure (bd : done, fromMaybe current walked)
@@ -9,6 +9,7 @@ , parseExpressionThrows , parseAttribute , parseAttributeThrows+ , ParserException (..) , parseAlpha , parseIndex , parseNumber@@ -284,18 +285,26 @@ choice [ rb >> return [] , do- voids' <- map BiVoid <$> void' `sepBy1` symbol ","+ voids' <- ((,) <$> getOffset <*> (BiVoid <$> void')) `sepBy1` symbol "," rb >> return voids' ] _ <- arrow- opened <- expression- case opened of- ExFormation bds -> ExFormation <$> validatedBindings (voids ++ bds)- _ -> fail "Inline voids open a formation, so nothing but a formation may follow their arrow"+ choice+ [ do+ bds <- formationBindingsOffsets+ tailed <- option False (True <$ lookAhead (oneOf ".(:"))+ if tailed+ then reportDuplicates bds >>= exTail . ExFormation >>= opening voids+ else ExFormation <$> reportDuplicates (voids ++ bds)+ , expression >>= opening voids+ ] ] where rb :: Parser String rb = symbol ")"+ opening :: [(Int, Binding)] -> Expression -> Parser Expression+ opening voids (ExFormation bds) = ExFormation <$> validatedBindings (map snd voids ++ bds)+ opening _ _ = fail "Inline voids open a formation, so nothing but a formation may follow their arrow" lambdaName :: Parser Function lambdaName = choice [Function . T.pack <$> function, try (either FnAny FnMeta <$> metaVar 'F' "𝑓"), sigma]@@ -394,31 +403,37 @@ Left msg -> fail msg Right bds' -> return bds' -formationBindings :: Parser [Binding]-formationBindings = do+reportDuplicates :: [(Int, Binding)] -> Parser [Binding]+reportDuplicates bs = do+ either (parseError . FancyError (repeating [] bs) . Set.singleton . ErrorFail) (const (pure ())) (uniqueBindings (map snd bs))+ return (map snd bs)+ where+ repeating :: [Attribute] -> [(Int, Binding)] -> Int+ repeating _ [] = 0+ repeating seen ((offset, bd) : rest)+ | any (`elem` seen) (attributesFromBindings [bd]) = offset+ | otherwise = repeating (seen ++ attributesFromBindings [bd]) rest++formationBindingsOffsets :: Parser [(Int, Binding)]+formationBindingsOffsets = do _ <- choice [symbol "[[", symbol "⟦"] choice [ rsb >> return [] , do bs <- ((,) <$> getOffset <*> binding) `sepBy1` symbol ","- either (parseError . FancyError (repeating [] bs) . Set.singleton . ErrorFail) (const (pure ())) (uniqueBindings (map snd bs))- rsb >> return (map snd bs)+ rsb >> return bs ] where rsb :: Parser String rsb = choice [symbol "]]", symbol "⟧"]- repeating :: [Attribute] -> [(Int, Binding)] -> Int- repeating _ [] = 0- repeating seen ((offset, bd) : rest)- | any (`elem` seen) (attributesFromBindings [bd]) = offset- | otherwise = repeating (seen ++ attributesFromBindings [bd]) rest +formationBindings :: Parser [Binding]+formationBindings = formationBindingsOffsets >>= reportDuplicates+ exHead :: Parser Expression exHead = choice- [ do- bs <- formationBindings >>= validatedBindings- return (ExFormation bs)+ [ ExFormation <$> formationBindings , do _ <- choice [symbol "$", symbol "ξ"] return ExXi
@@ -29,7 +29,7 @@ import qualified Data.Text as T import Encoding import Lining-import Margin (defaultMargin, withMargin)+import Margin (defaultMargin, withLines) import Matcher import Render import Sugar@@ -52,7 +52,7 @@ printExpressionWith :: (SugarType -> EXPRESSION -> EXPRESSION) -> Expression -> PrintConfig -> String printExpressionWith hide ex (sugar, encoding, line, margin) =- T.unpack $ render (withLineFormat line $ withMargin margin $ withEncoding encoding $ hide sugar $ withSugarType sugar $ expressionToCST ex)+ T.unpack $ render (withLines line margin $ withEncoding encoding $ hide sugar $ withSugarType sugar $ expressionToCST ex) printExpression :: Expression -> String printExpression ex = printExpression' ex defaultPrintConfig
@@ -11,27 +11,37 @@ import Text.Read (readMaybe) import qualified Text.Regex.PCRE.ByteString as R -compile :: B.ByteString -> IO R.Regex+data Regex = Regex R.Regex R.Regex++compile :: B.ByteString -> IO Regex compile pat = do- compiled <- R.compile R.compBlank R.execBlank pat- case compiled of- Left (_, err) -> throwIO (userError ("Regex compilation failed: " ++ err))- Right regex -> pure regex+ first <- compileWith R.execBlank+ continuation <- compileWith R.execNotBOL+ pure (Regex first continuation)+ where+ compileWith option = do+ compiled <- R.compile R.compUTF8 option pat+ case compiled of+ Left (_, err) -> throwIO (userError ("Regex compilation failed: " ++ err))+ Right regex -> pure regex match :: B.ByteString -> B.ByteString -> IO Bool match pattern input = do- regex <- compile pattern+ Regex regex _ <- compile pattern res <- R.execute regex input case res of- Left _ -> pure False+ Left err -> regexExecutionFailed err Right Nothing -> pure False Right (Just _) -> pure True -extractGroups :: R.Regex -> B.ByteString -> IO [B.ByteString]-extractGroups regex input = do+extractGroups :: Regex -> B.ByteString -> IO [B.ByteString]+extractGroups (Regex regex _) input = extractGroupsWith regex input++extractGroupsWith :: R.Regex -> B.ByteString -> IO [B.ByteString]+extractGroupsWith regex input = do result <- R.execute regex input case result of- Left _ -> pure []+ Left err -> regexExecutionFailed err Right Nothing -> pure [] Right (Just arr) -> let (start, end) = bounds arr@@ -62,42 +72,43 @@ | i >= 0 && i < length xs = Just (xs !! i) | otherwise = Nothing -replaceFirst :: R.Regex -> B.ByteString -> B.ByteString -> IO B.ByteString-replaceFirst regex rep input = do+replaceFirst :: Regex -> B.ByteString -> B.ByteString -> IO B.ByteString+replaceFirst (Regex regex _) rep input = do result <- R.execute regex input case result of- Left _ -> return input+ Left err -> regexExecutionFailed err Right Nothing -> return input Right (Just arr) -> do- groups <- extractGroups regex input+ groups <- extractGroupsWith regex input let (off, len) = arr ! 0 (before, rest) = B.splitAt off input (_, after) = B.splitAt len rest replacement = substituteGroups rep groups return $ B.concat [before, replacement, after] -replaceAll :: R.Regex -> B.ByteString -> B.ByteString -> IO B.ByteString-replaceAll regex rep input = go input B.empty+replaceAll :: Regex -> B.ByteString -> B.ByteString -> IO B.ByteString+replaceAll (Regex first continuation) rep input = go True input B.empty where- go :: B.ByteString -> B.ByteString -> IO B.ByteString- go bs acc = do+ go :: Bool -> B.ByteString -> B.ByteString -> IO B.ByteString+ go initial bs acc = do+ let regex = if initial then first else continuation result <- R.execute regex bs case result of- Left _ -> return $ B.append acc bs+ Left err -> regexExecutionFailed err Right Nothing -> return $ B.append acc bs Right (Just arr) -> do let (off, len) = arr ! 0 (before, rest1) = B.splitAt off bs (_, rest2) = B.splitAt len rest1- groups <- extractGroups regex bs+ groups <- extractGroupsWith regex bs let replacement = substituteGroups rep groups if len == 0 then let next = B.take (utf8Width rest2) rest2 in if B.null next then return $ B.concat [acc, before, replacement]- else go (B.drop (B.length next) rest2) (B.concat [acc, before, replacement, next])- else go rest2 (B.concat [acc, before, replacement])+ else go False (B.drop (B.length next) rest2) (B.concat [acc, before, replacement, next])+ else go False rest2 (B.concat [acc, before, replacement]) utf8Width :: B.ByteString -> Int utf8Width bytes = case B.uncons bytes of@@ -115,3 +126,6 @@ else 1 isContinuation :: Char -> Bool isContinuation byte = ord byte >= 0x80 && ord byte < 0xC0++regexExecutionFailed :: Show err => err -> IO value+regexExecutionFailed err = throwIO (userError ("Regex execution failed: " ++ show err))
@@ -255,8 +255,8 @@ render ST_ATTRIBUTES{..} = "[ " <> T.intercalate " \\char44{} " (map render attrs) <> " ]" instance Render LOGIC_OPERATOR where- render AND = "\\;\\text{and}\\;"- render OR = "\\;\\text{or}\\;"+ render AND = "\\phiText{and}"+ render OR = "\\phiText{or}" instance Render NUMBER where render IDX_META{..} = render meta
@@ -158,7 +158,7 @@ R.matchExpressionWithRule expr rule ctx >>= \case [] -> pure Nothing matched- | isNothing rule.when -> Just <$> tryBuildAndReplaceFast (expr, rule.pattern, rule.result, matched)+ | isNothing rule.when && isNothing rule.having -> Just <$> tryBuildAndReplaceFast (expr, rule.pattern, rule.result, matched) | otherwise -> Just <$> buildAndReplace' (expr, rule.pattern, rule.result, matched) replaceExpression direct :: String -> Bool -> (Maybe Expression -> Expression -> [Expression]) -> Step
@@ -7,7 +7,7 @@ -- SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com -- SPDX-License-Identifier: MIT -module Sugar (toSalty, withSugarType, withoutRho, SugarType (..), ToSalty) where+module Sugar (toSalty, withSugarType, withoutRho, revealXi, SugarType (..), ToSalty) where import AST import Bytes (nonFiniteBts, numToBts, strToBts, unescapeStr)@@ -115,6 +115,39 @@ isRho PA_TAU{attr = AT_RHO _} = True isRho PA_FORMATION{attr = AT_RHO _} = True isRho _ = False++revealXi :: SugarType -> EXPRESSION -> EXPRESSION+revealXi _ = goExpr+ where+ goExpr :: EXPRESSION -> EXPRESSION+ goExpr EX_ATTR{..} = EX_DISPATCH (EX_XI XI) NO_SPACE attr+ goExpr EX_DISPATCH{..} = EX_DISPATCH (goExpr expr) space attr+ goExpr EX_APPLICATION{..} = EX_APPLICATION (goExpr expr) space eol tab (goArgument argument) eol' tab' indent+ goExpr EX_FORMATION{..} = EX_FORMATION lsb eol tab (goBinding binding) eol' tab' rsb+ goExpr EX_PHI_MEET{..} = EX_PHI_MEET prefix idx (goExpr expr)+ goExpr EX_PHI_AGAIN{..} = EX_PHI_AGAIN prefix idx (goExpr expr)+ goExpr EX_SINGLE{..} = EX_SINGLE (goPair pair) space (goExpr formation)+ goExpr expr = expr+ goArgument :: APP_ARGUMENT -> APP_ARGUMENT+ goArgument (AA_TAU (APP_BINDING pair)) = AA_TAU (APP_BINDING (goPair pair))+ goArgument (AA_TAUS binding) = AA_TAUS (goBinding binding)+ goArgument (AA_EXPRS arg) = AA_EXPRS (goAppArg arg)+ goAppArg :: APP_ARG -> APP_ARG+ goAppArg APP_ARG{..} = APP_ARG (goExpr expr) (goAppArgs args)+ goAppArgs :: APP_ARGS -> APP_ARGS+ goAppArgs AAS_EMPTY = AAS_EMPTY+ goAppArgs AAS_EXPR{..} = AAS_EXPR eol tab (goExpr expr) (goAppArgs args)+ goBinding :: BINDING -> BINDING+ goBinding BI_PAIR{..} = BI_PAIR (goPair pair) (goBindings bindings) tab+ goBinding binding = binding+ goBindings :: BINDINGS -> BINDINGS+ goBindings BDS_PAIR{..} = BDS_PAIR eol tab (goPair pair) (goBindings bindings)+ goBindings bindings = bindings+ goPair :: PAIR -> PAIR+ goPair PA_TAU{..} = PA_TAU attr arrow (goExpr expr)+ goPair PA_ALPHA{..} = PA_ALPHA alpha arrow (goExpr expr)+ goPair PA_FORMATION{..} = PA_FORMATION attr voids arrow (goExpr expr)+ goPair pair = pair class ToSalty a where toSalty :: a -> a
@@ -13,9 +13,11 @@ import AST import Control.Applicative (asum, (<|>))+import Control.Exception (throwIO) import Data.Aeson import qualified Data.Aeson.Key as Key import qualified Data.Aeson.KeyMap as KeyMap+import Data.Aeson.Types (formatRelativePath) import qualified Data.ByteString as BS import Data.FileEmbed (embedDir) import Data.Maybe (fromMaybe)@@ -24,6 +26,7 @@ import qualified Data.Text as T import Data.Yaml (Parser) import qualified Data.Yaml as Yaml+import Data.Yaml.Internal (Warning (DuplicateKey)) import GHC.Generics (Generic) import Metas import Parser@@ -489,7 +492,15 @@ normalizationRules = map decodeRule $(embedDir "resources/normalize") yamlRule :: FilePath -> IO Rule-yamlRule = Yaml.decodeFileThrow+yamlRule path = do+ decoded <- Yaml.decodeFileWithWarnings path+ case decoded of+ Left err -> throwIO err+ Right (warnings, rule) -> rule <$ mapM_ reportDuplicateKey warnings+ where+ reportDuplicateKey :: Warning -> IO ()+ reportDuplicateKey (DuplicateKey jsonPath) =+ fail (printf "The key '%s' is repeated in the rule file '%s', only the last value is kept" (formatRelativePath jsonPath) path) data Premise = Premise { result :: Text
@@ -0,0 +1,53 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The λ functions phino's own specs fire. phino implements none of them, so a+# spec that needs one to answer brings this file in with '--symbolic'. Every+# entry answers symbolically: the operands come down through 𝔻 or reach a+# normal form through 𝕄, and the term under '𝑛' carries a fresh symbol 𝜎+# standing for the value nobody worked out. Nothing here computes, which is+# what makes the morphing symbolic.+#+# 'L_number_nope' is missing on purpose: it is the λ function no entry answers,+# the one '--partial' parks on.++# Arithmetic over two numbers answers a number nobody has worked out.+- λ: L_number_(plus|times|div)+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )++# Comparing two numbers answers a bool nobody has decided, which is what the+# fork below then branches on.+- λ: L_number_gt+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.bool( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )++# Comparing two byte arrays answers a bool of the same kind.+- λ: L_bytes_eq+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.b+ 𝑛: Φ.bool( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )++# Inverting a byte array answers an array nobody has worked out.+- λ: L_bytes_not+ dataize:+ 𝛿1: $.ρ+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )++# A branch is where a 'morph' operand earns its place: the condition comes+# down through 𝔻, both branches reach a normal form through 𝕄, and the answer+# is one of them. This one answers the first, which is what an entry naming a+# meta it bound does; an entry whose answer is to stand for either branch joins+# the two of them in a 'join' block first and answers the meta that makes.+- λ: L_fork+ dataize:+ 𝛿1: $.ρ+ morph:+ 𝑛1: $.then+ 𝑛2: $.else+ 𝑛: 𝑛1
@@ -0,0 +1,11 @@+[[+ org -> [[+ eolang -> [[+ bytes -> [[+ data -> ?+ ]],+ L> Package+ ]],+ L> Package+ ]]+]]
@@ -0,0 +1,5 @@++ [[+ foo ↦ x+ ]]+
@@ -0,0 +1,1 @@+Q.org.eolang
@@ -0,0 +1,5 @@++ [[+ foo ↦ Q.org.eolang.x+ ]]+
@@ -0,0 +1,3 @@+ [[+ x -> [[ y -> [[ ^ -> ? ]] ]].y+ ]]
@@ -0,0 +1,11 @@+[[+ org -> [[+ eolang -> [[+ number -> [[+ @ -> ?+ ]],+ L> Package+ ]],+ L> Package+ ]]+]]
@@ -0,0 +1,11 @@+[[+ org -> [[+ eolang -> [[+ string -> [[+ @ -> ?+ ]],+ L> Package+ ]],+ L> Package+ ]]+]]
@@ -0,0 +1,18 @@+⟦+ j$kafka ↦ ⟦+ j$server ↦ ⟦+ j$KafkaRequestHandler ↦ ⟦+ φ ↦ Φ.jeo.class,+ j$$anonfun$run$1 ↦ ⟦+ φ ↦ Φ.jeo.method,+ params ↦ ⟦+ φ ↦ Φ.jeo.params,+ $this ↦ ⟦⟧+ ⟧+ ⟧+ ⟧,+ λ ⤍ Package+ ⟧,+ λ ⤍ Package+ ⟧+⟧
@@ -0,0 +1,14 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# This rule references the 'evaluate' function, which needs the evaluation+# context and is therefore only available to dataization/morphing rules.+# It is used to test that 'rewrite' rejects such rules at load time.+name: uses-evaluate+pattern: '!e2'+result: '!e1'+where:+ - meta: '!e1'+ function: evaluate+ args:+ - '!e2'
@@ -0,0 +1,22 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# This test rule is used with second.yaml test rule for testing that rewriting+# fails if rules lead to repeating expressions across several iterations.+# Here on the first cycle we rewrite formation with "0" to application with "1"+# In second.yaml this application is rewritten formation with "1"+# Then on the second cycle the formation with "1" is rewritten to application+# with "0", nhen in the second.yaml the application is rewritten to formation+# with "0". Here we get back to expression we started from and rewriting should+# fail on this step.+name: first+pattern: ⟦ x -> !e2 ⟧+result: Q.x(y -> !e1)+where:+ - meta: '!e1'+ function: sed+ args:+ - '!e2'+ - '"s/0/2/g"'+ - '"s/1/0/g"'+ - '"s/2/1/g"'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+name: infinite+pattern: ⟦ x -> !e2 ⟧+result: ⟦ x -> !e1 ⟧+where:+ - meta: '!e1'+ function: concat+ args: ['!e2', '"_hi"']
@@ -0,0 +1,14 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# This rule passes a non-binding argument to the 'join' where-function.+# It is used to test that the error message names the 'join' function+# correctly (it used to say "'go" instead of "join()").+name: uses-join-on-non-binding+pattern: '!e2'+result: '!e1'+where:+ - meta: '!e1'+ function: join+ args:+ - 'some-text'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+name: copy+label: \lambda+pattern: ⟦ 𝐵1, 𝜏1 ↦ ∅, 𝐵2 ⟧(𝜏1 ↦ 𝑘1)+result: ⟦ 𝐵1, 𝜏1 ↦ 𝑘1, 𝐵2 ⟧
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# This rule has a 'pattern' that is not a valid phi-expression. It is used+# to test that a broken --rule file is reported in plain text, with real+# characters and the path of the failing file, instead of an escaped+# AesonException dump.+name: malformed+pattern: '⟦ x ↦ ⟧'+result: 'ξ'
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# This rule turns a λ-marked formation into data. It is used to check that+# --rule is honoured together with --normalize, since none of the built-in+# normalization rules touches a λ binding.+name: marker+pattern: ⟦ λ ⤍ Marker ⟧+result: ⟦ Δ ⤍ FF- ⟧
@@ -0,0 +1,12 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# 'matches' dataizes its argument, and dataization of a formation (what+# '!e1' is bound to in the test input) raises inside the condition. The+# substitution must still be dropped (the policy #1079 questions), but the+# raise must be visible in the debug log (#1079).+name: raising-condition+pattern: '[[ x -> !e1 ]]'+result: '[[ x -> "hi" ]]'+when:+ matches: ['hello', '!e1']
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+name: second+pattern: Q.x(y -> !e1)+result: ⟦ x -> !e1 ⟧
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+name: foo+pattern: ⟦ x ↦ "foo", 𝐵1 ⟧+result: ⟦ x ↦ "bar", 𝐵1 ⟧
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+name: swap-a+pattern: ⟦ x -> !e1 ⟧+result: Q.a(!e1)
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+name: swap-b+pattern: ⟦ x -> !e1 ⟧+result: Q.b(!e1)
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ y -> ? ]](y -> Q.z) ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ absolute: '!e1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.foo.bar ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ absolute: '!e1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ y -> Q ]] ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ absolute: '!e1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ absolute: '!e1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ absolute: '!e1.q'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> T ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ absolute: '!e1'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ x -> $ ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ absolute: '!e1'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ x -> [[ y -> Q ]] ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ absolute: '!eX'
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ xxxx -> ? ]](~0 -> Q.y)'+pattern: '[[ !B1, !t1 -> ?, !B2 ]](α𝑖1 ↦ !e1)'+condition:+ eq:+ - 𝑖1+ - length: '!B1'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ x -> Q.y ]]'+pattern: '[[ !t1 -> Q.!t2, !B1 ]]'+condition:+ and:+ - eq: ['!t1', 'x']+ - eq: ['!t2', 'z']
@@ -0,0 +1,11 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.y, z -> Q.w ]]'+pattern: '[[ !t1 -> Q.!t2, !B1 ]]'+condition:+ and:+ - eq: ['!t1', 'x']+ - eq: ['!t2', 'y']+ - not:+ eq: ['!t1', '!t2']
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ a -> [[ ]], x -> [[ ]], b -> [[ ]] ]]'+pattern: '[[ !B1, x -> !e1, !B2 ]]'+condition:+ disjoint:+ - [Δ, λ]+ - [𝐵1, 𝐵2]
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ ]] ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ not:+ disjoint:+ - [Δ, λ]+ - ['𝐵unbound']
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> $, w -> $ ]](α0 -> Q)'+pattern: '[[ !B1 ]](α𝑖1 ↦ Q)'+condition:+ not:+ gt:+ - domain: '!Bx'+ - '𝑖1'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ a -> "a" ]] ]]'+pattern: '[[ x -> [[ !t1 -> !e1, !B1 ]] ]]'+condition:+ not:+ eq: ['!t1', '!tX']
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ ^ -> Q.x ]]'+pattern: '[[ !t1 -> !e1 ]]'+condition:+ not:+ eq:+ - '^'+ - '!tX'
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ ^ -> Q.x ]]'+pattern: '[[ !t1 -> !e1 ]]'+condition:+ eq:+ - '^'+ - '!t1'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ ^ -> Q.x ]]'+pattern: '[[ !t1 -> !e1 ]]'+condition:+ not:+ eq:+ - '!tX'+ - '^'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> "Hello", y -> "Hello" ]]'+pattern: '[[ x -> !e1, y -> !e2 ]]'+condition:+ not:+ eq: ['!e1', '!eX']
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> "Hello, world" ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ not:+ eq:+ - '"Hello, world"'+ - '!eX'
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> "Hello, world" ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ eq:+ - '"Hello, world"'+ - '!e1'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> "Hello, world" ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ not:+ eq:+ - '!eX'+ - '"Hello, world"'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> "Hello" ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ not:+ eq:+ - foo+ - '"Hello"'
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ ^ -> Q.x ]]'+pattern: '[[ !t1 -> !e1 ]]'+condition:+ eq:+ - '!t1'+ - '^'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Φ.hone.o-filter ]]'+pattern: '[[ x -> Q.hone.𝜏-filter ]]'+condition:+ or:+ - eq: [𝜏-filter, 'x-filter']+ - eq: [𝜏-filter, 'y-filter']+ - eq: [𝜏-filter, 'o-filter']
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> "Hello, world" ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ eq:+ - '!e1'+ - '"Hello, world"'
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ a -> "hey", b -> "jeff" ]] ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ eq:+ - '!e1'+ - '[[ a -> "hey", b -> "jeff" ]]'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ a -> "a" ]], y -> [[ a -> "b" ]] ]]'+pattern: '[[ x -> [[ !t1 -> !e1, !B1 ]], y -> [[ !t2 -> !e2, !B2 ]] ]]'+condition:+ eq: ['!t1', '!t2']
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> "Hello", y -> "Hello" ]]'+pattern: '[[ x -> !e1, y -> !e2 ]]'+condition:+ eq: ['!e1', '!e2']
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ y -> Q ]] ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ formation: '!e1'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ x -> [[ y -> Q ]] ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ formation: '!eX'
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> $, w -> $ ]](α0 -> Q)'+pattern: '[[ !B1 ]](α𝑖1 ↦ Q)'+condition:+ gt:+ - domain: '!B1'+ - '𝑖1'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.y, z -> Q.z ]]'+pattern: '[[ x -> !e1, z -> !e2 ]]'+condition:+ not:+ gt: ['!e1', '!e2']
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ L> Foo, x -> [[ ]], D> 00- ]]'+pattern: '[[ !B1, x -> !e1, !B2 ]]'+condition:+ in:+ - [Δ, λ]+ - [𝐵1, 𝐵2]
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ x -> Q.y, z -> Q.z ]].foo'+pattern: '[[ !B1 ]].!t1'+condition:+ in:+ - '!t1'+ - '!B1'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ L> Foo, x -> [[ ]] ]]'+pattern: '[[ !B1, x -> !e1, !B2 ]]'+condition:+ in:+ - [Δ, λ]+ - [𝐵1, 𝐵2]+failure: true
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.y, z -> Q.z ]].x'+pattern: '[[ !B1 ]].!t1'+condition:+ in:+ - '!t1'+ - '!B1'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.y, z -> Q.z ]].foo'+pattern: '[[ !B1 ]].!t1'+condition:+ not:+ in:+ - '!tUnbound'+ - '!B1'
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> ?, y -> Q.z ]].x'+pattern: '[[ !B1 ]].!t1'+condition:+ in:+ - '!t1'+ - '!B1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ y -> Q ]] ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ formation: '!e1'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.y, w -> $ ]](~0 -> Q)'+pattern: '[[ !B1 ]](α𝑖1 ↦ Q)'+condition:+ not:+ eq:+ - length: '!Bx'+ - 3
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.y, w -> $ ]](~0 -> Q)'+pattern: '[[ !B1 ]](α𝑖1 ↦ Q)'+condition:+ not:+ eq:+ - length: '^ -> ?'+ - 3
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.y, w -> $ ]](~0 -> Q)'+pattern: '[[ !B1 ]](α𝑖1 ↦ Q)'+condition:+ eq:+ - length: '!B1'+ - 2
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ k -> [[ x -> "D" ]] ]]'+pattern: '[[ !t1 -> !e1, !B1 ]]'+condition:+ matches: ['^ф$', '!e1']
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ k -> [[ x -> "ф" ]] ]]'+pattern: '[[ !t1 -> !e1, !B1 ]]'+condition:+ matches: ['^ф$', '!e1']
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> "Hello" ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ not:+ matches: ['Hello', '!eX']
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ k -> [[ x -> "()I" ]] ]]'+pattern: '[[ !t1 -> !e1, !B1 ]]'+condition:+ matches: ['\(\)[IBZF]$', '!e1']
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ k -> [[ x -> "Hello world ()" ]] ]]'+pattern: '[[ !t1 -> !e1, !B1 ]]'+condition:+ matches: ['Hello world \(\)', '!e1']
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ ^ -> Q.x ]]'+pattern: '[[ !t1 -> !e1 ]]'+condition:+ not:+ eq:+ - 𝑖1+ - 0
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ x -> [[ ]].b ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ nf: '[[ a -> !e1 ]]'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.foo ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ nf: '!e1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> $.foo ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ nf: '!e1'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '⟦ x ↦ [[ t -> ⊥.z ]].t ⟧.x'+pattern: '[[ x -> !e1 ]].x'+condition:+ not:+ nf: '!e1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ ]] ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ nf: '!e1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ D> 00-01-02 ]] ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ nf: '!e1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ y -> ? ]] ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ nf: '!e1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ nf: '!e1'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ x -> [[ ]].b ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ nf: '!e1.q'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '⟦ x ↦ ξ.t, t ↦ ∅ ⟧.x'+pattern: '[[ x -> !e1, !B1 ]].x'+condition:+ nf: '!e1'
@@ -0,0 +1,11 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# PHI left normalization for morphing (#973), so dispatching an absent+# attribute on a φ-decorated formation no longer reduces under 𝒩 — it is now a+# stuck normal form. (Before #973 the PHI rule could fire on '!e1', so it was+# not a normal form; this pack was 'not-nf-on-phi'.)+expression: '[[ x -> [[ @ -> [[ ]] ]].y ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ nf: '!e1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: 'Q.x'+pattern: '!e1.!t1'+condition:+ nf: '!e1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[x -> T]]'+pattern: '[[x -> !e1]]'+condition:+ nf: '!e1'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> $ ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ nf: '!e1'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ x -> Q ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ nf: '!eX'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ D> 00-01, x -> [[ ]], b -> [[ ]] ]]'+pattern: '[[ !B1, x -> !e1, !B2 ]]'+condition:+ disjoint:+ - [Δ, λ]+ - [𝐵1, 𝐵2]
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ a -> [[ ]], x -> [[ ]], L> Foo ]]'+pattern: '[[ !B1, x -> !e1, !B2 ]]'+condition:+ disjoint:+ - [Δ, λ]+ - [𝐵1, 𝐵2]
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: 'Q.bar'+pattern: 'Q.!t1'+condition:+ not:+ eq: ['!t1', 'foo']
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ x -> Q ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ formation: '!e1'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ x -> $, w -> $ ]](α3 -> Q)'+pattern: '[[ !B1 ]](α𝑖1 ↦ Q)'+condition:+ gt:+ - domain: '!B1'+ - '𝑖1'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ ]], D> 00- ]]'+pattern: '[[ !B1, x -> !e1, !B2 ]]'+condition:+ not:+ in:+ - [Δ, λ]+ - [𝐵1, 𝐵2]
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> T(y -> Q.z) ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ not:+ nf: '!e1'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> ⊥.𝜏1 ]]'+pattern: '[[ x -> !e1 ]]'+condition:+ not:+ nf: '!e1'
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.x ]]'+pattern: '[[ x -> Q.!t1 ]]'+condition:+ or:+ - eq: ['!t1', 'x']+ - eq: ['!t1', 'y']
@@ -0,0 +1,11 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ x -> Q.x ]]'+pattern: '[[ x -> Q.!t1 ]]'+condition:+ or:+ - eq: ['!t1', 'y']+ - eq: ['!t1', 'z']+ - eq: ['!t1', 'o']
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.y ]](~0 -> Q)'+pattern: '[[ !B1 ]](α𝑖1 ↦ !e1)'+condition:+ eq:+ - 𝑖1+ - 0
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+failure: true+expression: '[[ x -> Q.y, z -> Q.z ]]'+pattern: '[[ x -> !e1, !B1 ]]'+condition:+ part-of: ['!e1', '!B1']
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> [[ y -> Q.z ]], w -> Q.z ]]'+pattern: '[[ x -> [[ !B1 ]], !B2 ]]'+condition:+ part-of: ['Q.z', '!B1']
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.y, z -> Q.y ]]'+pattern: '[[ x -> !e1, !B1 ]]'+condition:+ part-of: ['!e1', '!B1']
@@ -0,0 +1,19 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ x -> Q.y ]].y'+pattern: '[[ !B1 ]].!t1'+condition:+ and:+ - not:+ in:+ - '!t1'+ - '𝐵1'+ - not:+ in:+ - 'φ'+ - '𝐵1'+ - not:+ in:+ - 'λ'+ - '𝐵1'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ Q+result: |-+ Φ
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ ⟦ x(y) ↦ ⟦ z ↦ ξ, w ↦ Φ ⟧.z:a, v(y) ↦ ⟦ z ↦ ∅, w ↦ Φ ⟧( z ↦ Φ ):b ⟧+result: |-+ ⟦ x(y) ↦ ⟦ z ↦ ξ, w ↦ Φ ⟧.z:a, v(y) ↦ ⟦ z ↦ ∅, w ↦ Φ ⟧( z ↦ Φ ):b ⟧
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ Q.org.bar.baz+result: |-+ Φ.org.bar.baz
@@ -0,0 +1,12 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ ⟦+ output(φ) ↦ ⟦+ write(buffer) ↦ ⟦ φ ↦ Φ.true ⟧+ ⟧:dead+ ⟧+result: |-+ ⟦ output(φ) ↦ ⟦ write(buffer) ↦ Φ.true:φ ⟧:dead ⟧
@@ -0,0 +1,36 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[+ x -> Q.x(Φ.jeo.opcode.lconst_0(+ 9+ ),+ Φ.jeo.opcode.lstore(+ 55,+ 1+ ),+ Φ.jeo.opcode.iconst_0(+ 3+ ),+ Φ.jeo.opcode.istore(+ 54,+ 3+ ),+ Φ.jeo.label(+ Φ.bytes(+ ⟦+ Δ ⤍ 4C-31-32-38-34-34-34-35-32-36-37+ ⟧+ )+ ))+ ]]+result: |-+ Φ.x(+ Φ.jeo.opcode.lconst_0( 9 ),+ Φ.jeo.opcode.lstore( 55, 1 ),+ Φ.jeo.opcode.iconst_0( 3 ),+ Φ.jeo.opcode.istore( 54, 3 ),+ Φ.jeo.label( Φ.bytes( 4C-31-32-38-34-34-34-35-32-36-37:Δ ) )+ ):x
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x(y) -> [[ L> Plus ]] ]]+result: |-+ ⟦ x(y) ↦ Plus:λ ⟧
@@ -0,0 +1,20 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[+ nan -> Q.number(Q.bytes([[ D> 7F-F8-00-00-00-00-00-00 ]])),+ pinf -> Q.number(Q.bytes([[ D> 7F-F0-00-00-00-00-00-00 ]])),+ ninf -> Q.number(Q.bytes([[ D> FF-F0-00-00-00-00-00-00 ]])),+ with-rho -> Q.number(~0 -> Q.bytes([[ D> 7F-F8-00-00-00-00-00-00 ]]), ^ -> Q.x.y.z),+ payload -> Q.number(Q.bytes([[ D> 7F-F8-00-00-00-00-00-01 ]]))+ ]]+result: |-+ ⟦+ nan ↦ Φ.nan,+ pinf ↦ Φ.pinf,+ ninf ↦ Φ.ninf,+ with-rho ↦ Φ.nan,+ payload ↦ Φ.number( Φ.bytes( 7F-F8-00-00-00-00-00-01:Δ ) )+ ⟧
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x -> Q.foo(~0 -> Q.bytes([[ D> 3F-F0-00-00-00-00-00-00 ]])) ]]+result: |-+ Φ.foo( Φ.bytes( 3F-F0-00-00-00-00-00-00:Δ ) ):x
@@ -0,0 +1,11 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[+ x -> Q.number(~0 -> Q.bytes([[ D> 3F-F0-00-00-00-00-00-00 ]]), ^ -> [[ t -> 42 ]], ^ -> Q.x.y.z),+ y -> Q.string(~0 -> Q.bytes([[ D> 68-65-79 ]]), ^ -> Q.x.y.z)+ ]]+result: |-+ ⟦ x ↦ 1, y ↦ "hey" ⟧
@@ -0,0 +1,13 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[+ foo -> [[+ @ -> $.^.z,+ bar -> Q.y(5, "foo")+ ]]+ ]]+result: |-+ ⟦ φ ↦ ρ.z, bar ↦ Φ.y( 5, "foo" ) ⟧:foo
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x(y) -> [[ a -> 42 ]] ]]+result: |-+ ⟦ x(y) ↦ 42:a ⟧
@@ -0,0 +1,14 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ ⟦+ x ↦ Φ.foo(+ x ↦ Φ.k+ ).bar(+ x ↦ Φ.k+ )+ ⟧+result: |-+ Φ.foo( x ↦ Φ.k ).bar( x ↦ Φ.k ):x
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x -> [[ D> 01-, a -> ?, ^ -> ?, b -> 2 ]] ]]+result: |-+ ⟦ x(a, ρ) ↦ ⟦ Δ ⤍ 01-, b ↦ 2 ⟧ ⟧
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ if -> [[ L> L_fork, left -> ?, right -> ? ]] ]]+result: |-+ ⟦ if(left, right) ↦ L_fork:λ ⟧
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x -> [[ ^ -> ?, x -> ?, y -> 5 ]], y -> [[ a -> ?, b -> 3, m -> ?, ^ -> ? ]] ]]+result: |-+ ⟦ x(ρ, x) ↦ 5:y, y(a) ↦ ⟦ b ↦ 3, m ↦ ∅, ρ ↦ ∅ ⟧ ⟧
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x -> y ]]+result: |-+ y:x
@@ -0,0 +1,5 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '⟦ Δ ⤍ 𝛿1 ⟧'+result: '!d1:D'
@@ -0,0 +1,30 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ ⟦+ number ↦ ⟦+ a ↦ ∅,+ b ↦ Φ.org.ρ.φ,+ c ↦ ξ.xyz(+ q ↦ Φ.y,+ α0 ↦ ξ.a.b+ ),+ z ↦ ⟦+ λ ⤍ Func,+ Δ ⤍ 00-,+ def ↦ Φ.txt.sprintf+ ⟧,+ error ↦ ⊥+ ⟧+ ⟧+result: |-+ [[+ number(a) -> [[+ b -> Q.org.^.@,+ c -> xyz( q -> Q.y, ~0 -> a.b ),+ z -> [[ L> Func, D> 00-, def -> Q.txt.sprintf ]],+ error -> T+ ]]+ ]]
@@ -0,0 +1,26 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x -> Q.y(1, 2) ]]+result: |-+ ⟦+ x ↦ Φ.y(+ α0 ↦ Φ.number(+ φ ↦ Φ.bytes(+ φ ↦ ⟦+ Δ ⤍ 3F-F0-00-00-00-00-00-00+ ⟧+ )+ )+ )(+ α1 ↦ Φ.number(+ φ ↦ Φ.bytes(+ φ ↦ ⟦+ Δ ⤍ 40-00-00-00-00-00-00-00+ ⟧+ )+ )+ )+ ⟧
@@ -0,0 +1,26 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x -> Q.y(z -> "hey", b -> 1) ]]+result: |-+ ⟦+ x ↦ Φ.y(+ z ↦ Φ.string(+ φ ↦ Φ.bytes(+ φ ↦ ⟦+ Δ ⤍ 68-65-79+ ⟧+ )+ )+ )(+ b ↦ Φ.number(+ φ ↦ Φ.bytes(+ φ ↦ ⟦+ Δ ⤍ 3F-F0-00-00-00-00-00-00+ ⟧+ )+ )+ )+ ⟧
@@ -0,0 +1,22 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ ⟦+ output(φ) ↦ ⟦+ write(buffer) ↦ ⟦ φ ↦ Φ.true ⟧+ ⟧:dead+ ⟧+result: |-+ ⟦+ output ↦ ⟦+ φ ↦ ∅,+ dead ↦ ⟦+ write ↦ ⟦+ buffer ↦ ∅,+ φ ↦ Φ.true+ ⟧+ ⟧+ ⟧+ ⟧
@@ -0,0 +1,36 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[+ nan -> Q.nan,+ pinf -> Q.pinf,+ ninf -> Q.number(~0 -> Q.bytes([[D> FF-F0-00-00-00-00-00-00]]), ^ -> Q.x)+ ]]+result: |-+ ⟦+ nan ↦ Φ.number(+ φ ↦ Φ.bytes(+ φ ↦ ⟦+ Δ ⤍ 7F-F8-00-00-00-00-00-00+ ⟧+ )+ ),+ pinf ↦ Φ.number(+ φ ↦ Φ.bytes(+ φ ↦ ⟦+ Δ ⤍ 7F-F0-00-00-00-00-00-00+ ⟧+ )+ ),+ ninf ↦ Φ.number(+ φ ↦ Φ.bytes(+ φ ↦ ⟦+ Δ ⤍ FF-F0-00-00-00-00-00-00+ ⟧+ )+ )(+ ρ ↦ Φ.x+ )+ ⟧
@@ -0,0 +1,36 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[+ x -> Q.number(+ ~0 -> Q.bytes([[D> 3F-F0-00-00-00-00-00-00]]), ^ -> Q.x, ^ -> [[ ]]+ ),+ y -> Q.string(+ ~0 -> Q.bytes([[D> 48-65-79]]), ^ -> $.x+ )+ ]]+result: |-+ ⟦+ x ↦ Φ.number(+ φ ↦ Φ.bytes(+ φ ↦ ⟦+ Δ ⤍ 3F-F0-00-00-00-00-00-00+ ⟧+ )+ )(+ ρ ↦ Φ.x+ )(+ ρ ↦ ⟦⟧+ ),+ y ↦ Φ.string(+ φ ↦ Φ.bytes(+ φ ↦ ⟦+ Δ ⤍ 48-65-79+ ⟧+ )+ )(+ ρ ↦ ξ.x+ )+ ⟧
@@ -0,0 +1,14 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x(x, y) -> [[ z -> Q.x ]] ]]+result: |-+ ⟦+ x ↦ ⟦+ x ↦ ∅,+ y ↦ ∅,+ z ↦ Φ.x+ ⟧+ ⟧
@@ -0,0 +1,17 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x -> 1, z -> [[ ]] ]]+result: |-+ ⟦+ x ↦ Φ.number(+ φ ↦ Φ.bytes(+ φ ↦ ⟦+ Δ ⤍ 3F-F0-00-00-00-00-00-00+ ⟧+ )+ ),+ z ↦ ⟦⟧+ ⟧
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x -> y ]]+result: |-+ ⟦+ x ↦ ξ.y+ ⟧
@@ -0,0 +1,17 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[+ x -> Q.y(+ z -> "hey",+ b -> 1+ ).z(+ a -> [[+ q -> [[ ^ -> Q.a ]]+ ]]+ )+ ]]+result: |-+ Φ.y( z ↦ "hey", b ↦ 1 ).z( a ↦ Φ.a:ρ:q ):x
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[+ x -> [[]]+ ]]+result: |-+ ⟦⟧:x
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[+ x -> [[ y -> ?, a -> 1, ^ -> ?, q -> ? ]]+ ]]+result: |-+ ⟦ x(y) ↦ ⟦ a ↦ 1, ρ ↦ ∅, q ↦ ∅ ⟧ ⟧
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The second addition is handed the symbol the first one answered with, brings+# it down to the manufactured datum and answers a symbol of its own, so a chain+# of firings ends where a single one does.+model: true+symbolic: true+input: '5.plus( 6 ).plus( 7 )'+result: '40-45-00-00-00-00-00-00'
@@ -0,0 +1,16 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The run enters the program where the locator points, follows the reference+# it finds there and dataizes what it lands on.+location: 'Q.foo.bar'+input: |+ [[+ foo -> [[+ bar -> [[+ @ -> Q.x+ ]]+ ]],+ x -> [[ D> 42- ]]+ ]]+result: '42-'
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The addition answers a number nobody worked out, so what 𝔻 reaches is the+# datum every symbol is manufactured the same one of, and not the sum at all.+model: true+symbolic: true+input: '5.plus( 6 )'+result: '40-45-00-00-00-00-00-00'
@@ -0,0 +1,11 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# Dispatching an absent attribute on a φ-decorated formation resolves the+# inherited attribute through morphing 'mphi' (#973): PHI used to be a+# normalization rule, but following the decoration is a semantic 𝕄 step, so it+# moved into 'resources/morphing'. Here '.t' is missing from the outer+# formation, so 𝕄 walks the '@' decoration to the parent that defines 't' and+# dataizes its datum.+input: '[[ @ -> [[ t -> [[ D> 2A- ]] ]] ]].t'+result: '2A-'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# Nobody decided the comparison, so the fork cannot know which branch the+# program takes; it answers the first one, whose value is a number the program+# wrote and not a symbol at all.+model: true+symbolic: true+input: '5.gt( 6 ).if( 1, 2 )'+result: '3F-F0-00-00-00-00-00-00'
@@ -0,0 +1,13 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A number is sugar for an application of 'Q.number', so the object model has+# to declare 'number' and 'bytes' before 5 means anything.+location: 'Q.x'+input: |+ [[+ number ↦ ⟦ φ ↦ ∅ ⟧,+ bytes ↦ ⟦ φ ↦ ∅ ⟧,+ x -> 5+ ]]+result: '40-14-00-00-00-00-00-00'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The 'none' rule dataizes ⊥ (𝔻(⟦⟧) → 𝔻(⊥)), which matches no clause now that+# there is no 'end' rule, so an empty formation reduces through one labelled+# 'dataize' step and then fails: it has nothing to dataize (#955).+input: '[[ ]]'+fails: 'terminator'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+model: true+symbolic: true+input: '5.nope'+fails: "No entry of --symbolic answers the λ function 'L_number_nope'"
@@ -0,0 +1,44 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# One firing, and nothing is computed: the operands come down to the numbers+# they are, and what the entry answers with is a number standing for a sum+# nobody has worked out.+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.@'+deep: true+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ number(φ) ↦ ⟦ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ @ ↦ 5.plus( 6 ) ⟧+result: '⟦ φ ↦ 𝜎1:λ, plus(x) ↦ L_number_plus:λ ⟧'+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := 5+ 𝑛·0·2 := 𝑛·0·1.plus( x ↦ 6 )+ 𝕄(Φ.φ.x):+ 𝑛·0·3 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝑛·0·4 := Φ.number( φ ↦ 𝑛·0·3 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := 5+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := Φ.number( φ ↦ 𝑛·0·3 )+ 𝑛·1·4 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 40-18-00-00-00-00-00-00 # 6.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.number( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.number( φ ↦ 𝜎1:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)
@@ -0,0 +1,62 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The key of an entry is a regular expression over λ names, so one entry+# stands for the whole family of them a box numbers its functions with.+symbolic: |+ - λ: L_number_(plus|times)+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.@'+deep: true+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ number(φ) ↦ ⟦+ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧,+ times(ρ, x) ↦ ⟦ λ ⤍ L_number_times ⟧ ⟧,+ @ ↦ 5.plus( 6 ).times( 7 ) ⟧+result: |-+ ⟦ φ ↦ 𝜎2:λ, plus(x) ↦ L_number_plus:λ, times(x) ↦ L_number_times:λ ⟧+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := 5+ 𝑛·0·2 := 𝑛·0·1.plus( x ↦ 6 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := 5+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := 6+ 𝑛·1·4 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 40-18-00-00-00-00-00-00 # 6.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.number( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.number( φ ↦ 𝜎1:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝑛·0·3 := 𝑛·1·6.times( x ↦ 7 )+ 𝕄(Φ.φ.x):+ 𝑛·0·4 := Φ.bytes( φ ↦ 40-1C-00-00-00-00-00-00:Δ )+ 𝑛·0·5 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝔼(L_number_times):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.number( φ ↦ 𝜎1:λ )+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵3):+ 𝕄(Φ.a🌵3):+ 𝑛·2·2 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝑛·2·3 := Φ.bytes( φ ↦ 40-1C-00-00-00-00-00-00:Δ )+ 𝛿·2·1 := 40-1C-00-00-00-00-00-00 # 7.0+ 𝛿2·2 := 𝛿·2·1 # 𝔻(ξ.x)+ 𝑛·2·4 := Φ.number( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·2·4):+ 𝑛·2·5 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·2·6 := 𝑛·2·5 # 𝕄(𝑛·2·4)
@@ -0,0 +1,46 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A program that does not loop answers the same with '_acyclic' as without it.+# The guard remembers the terms the frames above have open, so only a genuine+# return to one of them trips it; a term merely reduced twice in two places+# does not.+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.@'+deep: true+acyclic: proven+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ number(φ) ↦ ⟦ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ @ ↦ 5.plus( 6 ) ⟧+result: '⟦ φ ↦ 𝜎1:λ, plus(x) ↦ L_number_plus:λ ⟧'+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := 5+ 𝑛·0·2 := 𝑛·0·1.plus( x ↦ 6 )+ 𝕄(Φ.φ.x):+ 𝑛·0·3 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝑛·0·4 := Φ.number( φ ↦ 𝑛·0·3 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := 5+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := Φ.number( φ ↦ 𝑛·0·3 )+ 𝑛·1·4 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 40-18-00-00-00-00-00-00 # 6.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.number( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.number( φ ↦ 𝜎1:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)
@@ -0,0 +1,27 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A firing whose 'dataize' operand was parked gets stuck on the λ function+# that parked it and never on its own: an entry answers 'L_entry', so blaming+# it would name a λ function the file carries where the one nothing answers,+# 'L_none', stands one reduction deeper. The spine parks that name, so the+# deep walk over the residue writes no second 'unanswered(L_none)' for the one+# site (#1288, #1300).+symbolic: |+ - λ: L_entry+ dataize:+ 𝛿1: $.v+ 𝑛: ⟦ ⟧+location: 'Q.x'+deep: true+partial: true+input: '⟦ x ↦ ⟦ v ↦ ⟦ λ ⤍ L_none ⟧.foo, λ ⤍ L_entry, ρ ↦ ∅ ⟧.z ⟧'+protocol: |+ 𝕄(Φ.x):+ 𝔼(L_entry):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ unanswered(L_none) # 𝕄(L_none:λ)+ stuck(L_none)+ 𝔼(L_entry):+ stuck(L_none)
@@ -0,0 +1,184 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A loop walking an index from zero up to a size that is a symbol, under+# '--acyclic=plausible'. The first round holds the number '0', the second holds+# the symbol 'plus' answered in its place, and a symbol stands for a term that+# holds no symbol of its own, so the fork of the second round is cut against+# the fork of the first one rather than a round later (#1491). The cut fork is+# the φ of a copy of 'rec', so the cut answers that copy with a fresh symbol,+# which the 'join' of the first fork pairs with the other branch (#1735).+symbolic: |+ - λ: L_id+ morph:+ 𝑛1: $.x.φ+ 𝑛: 𝑛1+ - λ: L_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.b+ 𝑛: Φ.num( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_eq+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.b+ 𝑛: ⟦ φ ↦ Φ.bool( if ↦ ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ ⟦ λ ⤍ 𝜎 ⟧ ⟧ ) ⟧+ - λ: L_fork+ dataize:+ 𝛿1: $.φ+ morph:+ 𝑛1: $.left+ 𝑛2: $.right+ symbolize:+ 𝑛3: 𝑛1+ 𝑛4: 𝑛2+ join:+ 𝑛5: [𝑛3, 𝑛4]+ 𝑛: 𝑛5+location: 'Q.a'+deep: true+acyclic: plausible+partial: true+steps: 32+input: >+ ⟦ num ↦ ⟦ φ ↦ ∅, plus ↦ ⟦ ρ ↦ ∅, b ↦ ∅, λ ⤍ L_plus ⟧, eq ↦ ⟦ ρ ↦ ∅, b ↦ ∅, λ ⤍ L_eq ⟧ ⟧,+ bool ↦ ⟦ φ ↦ ∅, if ↦ ∅ ⟧,+ count ↦ ⟦ size ↦ ∅, φ ↦ ξ.rec( index ↦ Φ.num( φ ↦ ⟦ Δ ⤍ 00- ⟧ ), accum ↦ Φ.num( φ ↦ ⟦ Δ ⤍ 00- ⟧ ) ), rec ↦ ⟦ ρ ↦ ∅, index ↦ ∅, accum ↦ ∅, φ ↦ ξ.index.eq( ξ.ρ.size ).if( ξ.accum, ξ.ρ.rec( index ↦ ξ.index.plus( Φ.num( φ ↦ ⟦ Δ ⤍ 01- ⟧ ) ), accum ↦ ξ.accum.plus( Φ.num( φ ↦ ⟦ Δ ⤍ 01- ⟧ ) ) ) ) ⟧ ⟧,+ a ↦ ⟦ λ ⤍ L_id, x ↦ Φ.count( size ↦ Φ.num( φ ↦ ⟦ λ ⤍ 𝜎1 ⟧ ) ) ⟧ ⟧+protocol: |+ 𝕄(Φ.a):+ 𝕄(Φ.a.x):+ 𝑛·0·1 := Φ.num( φ ↦ 𝜎1:λ )+ 𝑛·0·2 := Φ.count( size ↦ 𝑛·0·1 )+ 𝔼(L_id):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.count( size ↦ 𝑛·0·1 )+ 𝑛·1·2 := ⟦ index ↦ ∅, accum ↦ ∅, φ ↦ index.eq( ρ.size ).if( accum, ρ.rec( index ↦ index.plus( Φ.num( φ ↦ 01-:Δ ) ), accum ↦ accum.plus( Φ.num( φ ↦ 01-:Δ ) ) ) ) ⟧( index ↦ Φ.num( φ ↦ 00-:Δ ) )+ 𝑛·1·3 := 𝑛·1·2( accum ↦ Φ.num( φ ↦ 00-:Δ ) )+ 𝕄(Φ.a🌵0.index):+ 𝑛·1·4 := Φ.num( φ ↦ 00-:Δ )+ 𝕄(Φ.a🌵0.accum):+ 𝑛·1·5 := Φ.num( φ ↦ 00-:Δ )+ 𝕄(Φ.a🌵0.φ):+ 𝑛·1·6 := Φ.num( φ ↦ 00-:Δ )+ 𝑛·1·7 := Φ.num( φ ↦ 00-:Δ )+ 𝑛·1·8 := Φ.num( φ ↦ 𝜎1:λ )+ 𝑛·1·9 := Φ.num( φ ↦ 00-:Δ )+ 𝑛·1·10 := 𝑛·1·9.eq( b ↦ 𝑛·1·8 )+ 𝔼(L_eq):+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·2·1 := Φ.num( φ ↦ 00-:Δ )+ 𝛿·2·1 := 00-+ 𝛿1·2 := 𝛿·2·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·2 := Φ.num( φ ↦ 𝜎1:λ )+ 𝛿2·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.b)+ 𝑛·2·3 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ ⟧ ):φ # 𝑛+ 𝑛·2·4 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ ⟧ ):φ # 𝕄(𝑛·2·3)+ 𝑛·1·11 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ ⟧ )+ 𝑛·1·12 := Φ.num( φ ↦ 00-:Δ )+ 𝑛·1·13 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ ⟧ )+ 𝑛·1·14 := ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ 𝜎2:λ ⟧( left ↦ 𝑛·1·12 )+ 𝑛·1·15 := Φ.num( φ ↦ 00-:Δ )+ 𝑛·1·16 := Φ.num( φ ↦ 00-:Δ )+ 𝑛·1·17 := Φ.num( φ ↦ 01-:Δ )+ 𝑛·1·18 := Φ.num( φ ↦ 00-:Δ )+ 𝑛·1·19 := 𝑛·1·18.plus( b ↦ 𝑛·1·17 )+ 𝔼(L_plus):+ 𝔻(Φ.a🌵3):+ 𝕄(Φ.a🌵3):+ 𝑛·3·1 := Φ.num( φ ↦ 00-:Δ )+ 𝛿·3·1 := 00-+ 𝛿1·3 := 𝛿·3·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵4):+ 𝕄(Φ.a🌵4):+ 𝑛·3·2 := Φ.num( φ ↦ 01-:Δ )+ 𝛿·3·2 := 01-+ 𝛿2·3 := 𝛿·3·2 # 𝔻(ξ.b)+ 𝑛·3·3 := Φ.num( φ ↦ 𝜎3:λ ) # 𝑛+ 𝕄(𝑛·3·3):+ 𝑛·3·4 := Φ.num( φ ↦ 𝜎3:λ )+ 𝑛·3·5 := 𝑛·3·4 # 𝕄(𝑛·3·3)+ 𝑛·1·20 := ⟦ index ↦ ∅, accum ↦ ∅, φ ↦ index.eq( ρ.size ).if( accum, ρ.rec( index ↦ index.plus( 𝑛·3·2 ), accum ↦ accum.plus( 𝑛·3·2 ) ) ) ⟧( index ↦ 𝑛·3·4 )+ 𝑛·1·21 := Φ.num( φ ↦ 00-:Δ )+ 𝑛·1·22 := Φ.num( φ ↦ 00-:Δ )+ 𝑛·1·23 := Φ.num( φ ↦ 01-:Δ )+ 𝑛·1·24 := Φ.num( φ ↦ 00-:Δ )+ 𝑛·1·25 := 𝑛·1·24.plus( b ↦ 𝑛·1·23 )+ 𝔼(L_plus):+ 𝑛·4·1 := 𝑛·3·4 # 𝑛+ 𝑛·4·2 := 𝑛·3·5 # 𝕄(𝑛·4·1)+ 𝑛·1·26 := ⟦ index ↦ ∅, accum ↦ ∅, φ ↦ index.eq( ρ.size ).if( accum, ρ.rec( index ↦ index.plus( 𝑛·1·23 ), accum ↦ accum.plus( 𝑛·1·23 ) ) ) ⟧( index ↦ 𝑛·3·4 )+ 𝑛·1·27 := 𝑛·1·26( accum ↦ 𝑛·3·4 )+ 𝑛·1·28 := ⟦ index ↦ ∅, accum ↦ ∅, φ ↦ index.eq( ρ.size ).if( accum, ρ.rec( index ↦ index.plus( 𝑛·1·23 ), accum ↦ accum.plus( 𝑛·1·23 ) ) ) ⟧( index ↦ 𝑛·3·4 )+ 𝑛·1·29 := 𝑛·1·28( accum ↦ 𝑛·3·4 )+ 𝑛·1·30 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ ⟧ )+ 𝑛·1·31 := ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ 𝜎2:λ ⟧( left ↦ 𝑛·1·24 )+ 𝑛·1·32 := 𝑛·1·31( right ↦ 𝑛·1·29 )+ 𝔼(L_fork):+ 𝛿1·5 := 𝔻(𝜎2:λ) # 𝔻(ξ.φ)+ 𝕄(Φ.a🌵6):+ 𝑛·5·1 := Φ.num( φ ↦ 00-:Δ )+ 𝑛1·5 := 𝑛·5·1 # 𝕄(ξ.left)+ 𝕄(Φ.a🌵7):+ 𝕄(Φ.a🌵7.φ):+ 𝑛·5·2 := Φ.num( φ ↦ 𝜎1:λ )+ 𝑛·5·3 := 𝑛·3·4.eq( b ↦ 𝑛·5·2 )+ 𝔼(L_eq):+ 𝔻(Φ.a🌵8):+ 𝕄(Φ.a🌵8):+ 𝑛·6·1 := Φ.num( φ ↦ 𝜎3:λ )+ 𝛿1·6 := 𝔻(𝜎3:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵9):+ 𝕄(Φ.a🌵9):+ 𝑛·6·2 := Φ.num( φ ↦ 𝜎1:λ )+ 𝛿2·6 := 𝔻(𝜎1:λ) # 𝔻(ξ.b)+ 𝑛·6·3 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎4:λ ⟧ ):φ # 𝑛+ 𝑛·6·4 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎4:λ ⟧ ):φ # 𝕄(𝑛·6·3)+ 𝑛·5·4 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎4:λ ⟧ )+ 𝑛·5·5 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎4:λ ⟧ )+ 𝑛·5·6 := ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ 𝜎4:λ ⟧( left ↦ 𝑛·6·1 )+ 𝑛·5·7 := Φ.num( φ ↦ 01-:Δ )+ 𝑛·5·8 := 𝑛·6·1.plus( b ↦ 𝑛·5·7 )+ 𝔼(L_plus):+ 𝔻(Φ.a🌵10):+ 𝕄(Φ.a🌵10):+ 𝑛·7·1 := Φ.num( φ ↦ 𝜎3:λ )+ 𝛿1·7 := 𝔻(𝜎3:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵11):+ 𝕄(Φ.a🌵11):+ 𝑛·7·2 := Φ.num( φ ↦ 01-:Δ )+ 𝛿·7·1 := 01-+ 𝛿2·7 := 𝛿·7·1 # 𝔻(ξ.b)+ 𝑛·7·3 := Φ.num( φ ↦ 𝜎5:λ ) # 𝑛+ 𝕄(𝑛·7·3):+ 𝑛·7·4 := Φ.num( φ ↦ 𝜎5:λ )+ 𝑛·7·5 := 𝑛·7·4 # 𝕄(𝑛·7·3)+ 𝑛·5·9 := ⟦ index ↦ ∅, accum ↦ ∅, φ ↦ index.eq( ρ.size ).if( accum, ρ.rec( index ↦ index.plus( 𝑛·7·2 ), accum ↦ accum.plus( 𝑛·7·2 ) ) ) ⟧( index ↦ 𝑛·7·4 )+ 𝑛·5·10 := Φ.num( φ ↦ 01-:Δ )+ 𝑛·5·11 := 𝑛·7·1.plus( b ↦ 𝑛·5·10 )+ 𝔼(L_plus):+ 𝑛·8·1 := 𝑛·7·4 # 𝑛+ 𝑛·8·2 := 𝑛·7·5 # 𝕄(𝑛·8·1)+ 𝑛·5·12 := ⟦ index ↦ ∅, accum ↦ ∅, φ ↦ index.eq( ρ.size ).if( accum, ρ.rec( index ↦ index.plus( 𝑛·5·10 ), accum ↦ accum.plus( 𝑛·5·10 ) ) ) ⟧( index ↦ 𝑛·7·4 )+ 𝑛·5·13 := 𝑛·5·12( accum ↦ 𝑛·7·4 )+ 𝑛·5·14 := ⟦ index ↦ ∅, accum ↦ ∅, φ ↦ index.eq( ρ.size ).if( accum, ρ.rec( index ↦ index.plus( 𝑛·5·10 ), accum ↦ accum.plus( 𝑛·5·10 ) ) ) ⟧( index ↦ 𝑛·7·4 )+ 𝑛·5·15 := 𝑛·5·14( accum ↦ 𝑛·7·4 )+ 𝑛·5·16 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎4:λ ⟧ )+ 𝑛·5·17 := ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ 𝜎4:λ ⟧( left ↦ 𝑛·7·1 )+ 𝑛·5·18 := 𝑛·5·17( right ↦ 𝑛·5·15 )+ looped(𝑛·1·32) := 𝜎6 # plausible+ 𝑛2·5 := 𝜎6:λ # 𝕄(ξ.right)+ 𝔻(𝜎7:λ) == 00-+ 𝑛3·5 := ⟦ φ ↦ 𝜎7:λ, plus(b) ↦ L_plus:λ, eq(b) ↦ L_eq:λ ⟧ # 𝑛1+ 𝑛4·5 := 𝑛2·5 # 𝑛2+ 𝔻(𝜎8:λ) ∈ { 𝔻(𝜎7:λ), 𝔻(𝜎6:λ) }+ 𝑛5·5 := 𝜎8:λ # [𝑛3, 𝑛4]+ 𝑛·5·19 := 𝑛5·5 # 𝑛+ 𝑛·5·20 := 𝑛5·5 # 𝕄(𝑛·5·19)+ 𝑛1·1 := 𝑛·1·3 # 𝕄(ξ.x.φ)+ 𝑛·1·33 := 𝑛1·1 # 𝑛+ 𝑛·1·34 := 𝑛1·1 # 𝕄(𝑛·1·33)
@@ -0,0 +1,171 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A factorial over a symbolic argument, under '--acyclic=proven'. Every round+# of the recursion mints fresh symbols, so the deep walk fires 'mul' with+# a ↦ 𝜎1 and b ↦ Φ.fact( n ↦ 𝜎3 ) on the first round and with a ↦ 𝜎3 and+# b ↦ Φ.fact( n ↦ 𝜎5 ) on the second, and no two rounds are ever the same term.+# They are the same formation up to a renaming of symbols, which is what the+# guard compares by (#1420), and the walk enters the formation it fires (#1451),+# so the second firing is cut before it opens and writes a 'looped' line where+# its block would have stood, carrying the term of the round that was kept+# (#1434). The budget is generous here, so what ends the run is the cut and not+# the limit. The argument 'n' and every symbol 'dec' answers stand in a+# carrier '⟦ φ ↦ 𝜎 ⟧', since the walk defers a copy one of whose arguments is+# a bare symbol instead of entering it (#1729). The first 'L_if' gets stuck,+# yet the symbols it minted stay taken, so the second one mints from 𝜎7 (#1738).+symbolic: |+ - λ: L_zero+ dataize:+ 𝛿1: $.x+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+ - λ: L_dec+ dataize:+ 𝛿1: $.x+ 𝑛: ⟦ φ ↦ ⟦ λ ⤍ 𝜎 ⟧ ⟧+ - λ: L_mul+ dataize:+ 𝛿1: $.a+ 𝛿2: $.b+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+ - λ: L_if+ dataize:+ 𝛿1: $.c+ morph:+ 𝑛1: $.left+ 𝑛2: $.right+ symbolize:+ 𝑛3: 𝑛1+ 𝑛4: 𝑛2+ join:+ 𝑛5: [𝑛3, 𝑛4]+ 𝑛: 𝑛5+location: 'Q.x'+deep: true+acyclic: proven+partial: true+steps: 250+input: >+ ⟦ if ↦ ⟦ c ↦ ∅, left ↦ ∅, right ↦ ∅, λ ⤍ L_if ⟧,+ zero ↦ ⟦ x ↦ ∅, λ ⤍ L_zero ⟧,+ dec ↦ ⟦ x ↦ ∅, λ ⤍ L_dec ⟧,+ mul ↦ ⟦ a ↦ ∅, b ↦ ∅, λ ⤍ L_mul ⟧,+ fact ↦ ⟦ n ↦ ∅, φ ↦ Φ.if( c ↦ Φ.zero( x ↦ ξ.n ), left ↦ ⟦ Δ ⤍ 01- ⟧, right ↦ Φ.mul( a ↦ ξ.n, b ↦ Φ.fact( n ↦ Φ.dec( x ↦ ξ.n ) ) ) ) ⟧,+ x ↦ Φ.fact( n ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎1 ⟧ ⟧ ) ⟧+result: |-+ ⟦+ n ↦ 𝜎1:λ:φ,+ φ ↦ Φ.if(+ c ↦ 𝜎2:λ,+ left ↦ 01-:Δ,+ right ↦ Φ.mul( a ↦ n, b ↦ Φ.fact( n ↦ 𝜎3:λ:φ ) )+ )+ ⟧+protocol: |+ 𝕄(Φ.x):+ 𝑛·0·1 := Φ.fact( n ↦ 𝜎1:λ:φ )+ 𝕄(Φ.x.φ):+ 𝑛·0·2 := Φ.zero( x ↦ 𝜎1:λ:φ )+ 𝔼(L_zero):+ 𝛿1·1 := 𝔻(𝜎1:λ) # 𝔻(ξ.x)+ 𝑛·1·1 := 𝜎2:λ # 𝑛+ 𝑛·1·2 := 𝜎2:λ # 𝕄(𝑛·1·1)+ 𝑛·0·3 := Φ.if( c ↦ 𝜎2:λ )+ 𝑛·0·4 := Φ.if( c ↦ 𝜎2:λ )+ 𝑛·0·5 := 𝑛·0·4( left ↦ 01-:Δ )+ 𝑛·0·6 := Φ.mul( a ↦ 𝜎1:λ:φ )+ 𝑛·0·7 := Φ.dec( x ↦ 𝜎1:λ:φ )+ 𝔼(L_dec):+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.x)+ 𝑛·2·1 := 𝜎3:λ:φ # 𝑛+ 𝑛·2·2 := 𝜎3:λ:φ # 𝕄(𝑛·2·1)+ 𝑛·0·8 := Φ.fact( n ↦ 𝜎3:λ:φ )+ 𝑛·0·9 := Φ.mul( a ↦ 𝜎1:λ:φ )+ 𝑛·0·10 := 𝑛·0·9( b ↦ 𝑛·0·8 )+ 𝔼(L_mul):+ 𝛿1·3 := 𝔻(𝜎1:λ) # 𝔻(ξ.a)+ 𝔻(Φ.a🌵3):+ 𝕄(Φ.a🌵3):+ 𝑛·3·1 := Φ.fact( n ↦ 𝜎3:λ:φ )+ 𝑛·3·2 := Φ.if( c ↦ Φ.zero( x ↦ 𝜎3:λ:φ ) )+ 𝑛·3·3 := 𝑛·3·2( left ↦ 01-:Δ )+ 𝑛·3·4 := 𝑛·3·3( right ↦ Φ.mul( a ↦ 𝜎3:λ:φ, b ↦ Φ.fact( n ↦ Φ.dec( x ↦ 𝜎3:λ:φ ) ) ) )+ 𝔼(L_if):+ 𝔻(Φ.a🌵4):+ 𝕄(Φ.a🌵4):+ 𝑛·4·1 := Φ.zero( x ↦ 𝜎3:λ:φ )+ 𝔼(L_zero):+ 𝛿1·5 := 𝔻(𝜎3:λ) # 𝔻(ξ.x)+ 𝑛·5·1 := 𝜎4:λ # 𝑛+ 𝑛·5·2 := 𝜎4:λ # 𝕄(𝑛·5·1)+ 𝛿1·4 := 𝔻(𝜎4:λ) # 𝔻(ξ.c)+ 𝑛1·4 := 01-:Δ # 𝕄(ξ.left)+ 𝕄(Φ.a🌵7):+ 𝑛·4·2 := Φ.mul( a ↦ 𝜎3:λ:φ )+ 𝑛·4·3 := 𝑛·4·2( b ↦ Φ.fact( n ↦ Φ.dec( x ↦ 𝜎3:λ:φ ) ) )+ 𝕄(Φ.a🌵7.b):+ 𝑛·4·4 := Φ.dec( x ↦ 𝜎3:λ:φ )+ 𝔼(L_dec):+ 𝛿1·6 := 𝔻(𝜎3:λ) # 𝔻(ξ.x)+ 𝑛·6·1 := 𝜎5:λ:φ # 𝑛+ 𝑛·6·2 := 𝜎5:λ:φ # 𝕄(𝑛·6·1)+ 𝑛·4·5 := Φ.fact( n ↦ 𝜎5:λ:φ )+ looped(𝑛·0·10) # proven+ 𝑛2·4 := 𝑛·4·3 # 𝕄(ξ.right)+ 𝔻(𝜎6:λ) == 01-+ 𝑛3·4 := 𝜎6:λ # 𝑛1+ 𝑛4·4 := 𝑛·4·3 # 𝑛2+ stuck(L_if)+ stuck(L_if)+ 𝑛·0·11 := Φ.if( c ↦ 𝜎2:λ )+ 𝑛·0·12 := 𝑛·0·11( left ↦ 01-:Δ )+ 𝑛·0·13 := 𝑛·0·12( right ↦ 𝑛·0·10 )+ 𝔼(L_if):+ 𝛿1·7 := 𝔻(𝜎2:λ) # 𝔻(ξ.c)+ 𝑛1·7 := 01-:Δ # 𝕄(ξ.left)+ 𝕄(Φ.a🌵11):+ 𝑛·7·1 := Φ.mul( a ↦ 𝜎1:λ:φ )+ 𝑛·7·2 := 𝑛·7·1( b ↦ 𝑛·3·1 )+ 𝕄(Φ.a🌵11.b):+ 𝑛·7·3 := Φ.fact( n ↦ 𝜎3:λ:φ )+ 𝔼(L_mul):+ 𝛿1·8 := 𝔻(𝜎1:λ) # 𝔻(ξ.a)+ 𝔻(Φ.a🌵13):+ 𝕄(Φ.a🌵13):+ 𝑛·8·1 := Φ.fact( n ↦ 𝜎3:λ:φ )+ 𝑛·8·2 := Φ.if( c ↦ 𝑛·4·1 )+ 𝑛·8·3 := 𝑛·8·2( left ↦ 01-:Δ )+ 𝑛·8·4 := 𝑛·8·3( right ↦ 𝑛·4·3 )+ 𝔼(L_if):+ 𝔻(Φ.a🌵14):+ 𝕄(Φ.a🌵14):+ 𝑛·9·1 := Φ.zero( x ↦ 𝜎3:λ:φ )+ 𝔼(L_zero):+ 𝛿1·10 := 𝔻(𝜎3:λ) # 𝔻(ξ.x)+ 𝑛·10·1 := 𝜎7:λ # 𝑛+ 𝑛·10·2 := 𝜎7:λ # 𝕄(𝑛·10·1)+ 𝛿1·9 := 𝔻(𝜎7:λ) # 𝔻(ξ.c)+ 𝑛1·9 := 01-:Δ # 𝕄(ξ.left)+ 𝕄(Φ.a🌵17):+ 𝑛·9·2 := Φ.mul( a ↦ 𝜎3:λ:φ )+ 𝑛·9·3 := 𝑛·9·2( b ↦ Φ.fact( n ↦ 𝑛·4·4 ) )+ 𝕄(Φ.a🌵17.b):+ 𝑛·9·4 := Φ.dec( x ↦ 𝜎3:λ:φ )+ 𝔼(L_dec):+ 𝛿1·11 := 𝔻(𝜎3:λ) # 𝔻(ξ.x)+ 𝑛·11·1 := 𝜎8:λ:φ # 𝑛+ 𝑛·11·2 := 𝜎8:λ:φ # 𝕄(𝑛·11·1)+ 𝑛·9·5 := Φ.fact( n ↦ 𝜎8:λ:φ )+ looped(𝑛·7·2) # proven+ 𝑛2·9 := 𝑛·9·3 # 𝕄(ξ.right)+ 𝔻(𝜎9:λ) == 01-+ 𝑛3·9 := 𝜎9:λ # 𝑛1+ 𝑛4·9 := 𝑛·9·3 # 𝑛2+ stuck(L_if)+ stuck(L_if)+ 𝑛2·7 := 𝑛·7·2 # 𝕄(ξ.right)+ 𝔻(𝜎10:λ) == 01-+ 𝑛3·7 := 𝜎10:λ # 𝑛1+ 𝑛4·7 := 𝑛·7·2 # 𝑛2+ stuck(L_if)
@@ -0,0 +1,167 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The loop of #1729: 'joined' folds a tuple whose tail is the bare symbol '𝜎3',+# an object nobody knows. The right branch of the first fork is the copy+# 'step( acc ↦ …, tup ↦ 𝜎3 )', and nothing inside its body can succeed, since+# every round asks '𝜎3' for its 'length'. Before #1729 the walk entered that+# body, got stuck six times, and left it as written, so the join had a symbol+# on the left and a body on the right, and 'e' came to nothing. Now the walk+# does not enter a copy one of whose arguments reads to a bare symbol: it+# answers the copy with a fresh symbol and writes a 'deferred' line naming the+# copy it stands for, the join pairs that symbol with the one the left branch+# ends in, and 'e' comes to a symbol. Since #1732 that line spells the copy as+# a call of 'Φ.joined.step', the object of the world it was made of, rather+# than of 'Φ.e.step', the copy of 'joined' the walk wrote into 'e', since only+# the first one has voids the copy fills. Reading 'items.length' through the+# tuple, itself a copy over bare symbols, still reaches '𝜎1', since a copy with+# no φ has no body to defer.+symbolic: |+ - λ: L_bytes_eq+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.b+ 𝑛: Φ.bool( if ↦ ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ ⟦ λ ⤍ 𝜎 ⟧ ⟧ )+ - λ: L_bytes_concat+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.b+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_dataized+ dataize:+ 𝛿1: $.target+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_fork+ dataize:+ 𝛿1: $.φ+ morph:+ 𝑛1: $.left+ 𝑛2: $.right+ symbolize:+ 𝑛3: 𝑛1+ 𝑛4: 𝑛2+ join:+ 𝑛5: [𝑛3, 𝑛4]+ 𝑛: 𝑛5+location: 'Q.e'+deep: true+partial: true+acyclic: plausible+result: '⟦ items ↦ Φ.tuple( length ↦ Φ.bytes( φ ↦ 𝜎1:λ ), head ↦ 𝜎2:λ, tail ↦ 𝜎3:λ ), φ ↦ 𝜎9:λ, step(acc, tup) ↦ Φ.dataized( target ↦ tup.length ).eq( b ↦ Φ.bytes( φ ↦ 00-:Δ ) ).if( acc, ρ.step( acc ↦ acc.concat( b ↦ Φ.dataized( target ↦ tup.head ) ), tup ↦ tup.tail ) ):φ ⟧'+input: |+ ⟦+ bool(if) ↦ ⟦ φ ↦ if( Φ.bytes( φ ↦ FF-:Δ ), Φ.bytes( φ ↦ 00-:Δ ) ) ⟧,+ bytes(φ) ↦ ⟦ eq(ρ, b) ↦ L_bytes_eq:λ, concat(ρ, b) ↦ L_bytes_concat:λ ⟧,+ dataized(target) ↦ L_dataized:λ,+ tuple(length, head, tail) ↦ ⟦⟧,+ joined(items) ↦ ⟦+ φ ↦ Φ.dataized( target ↦ items.length ).eq( b ↦ Φ.bytes( φ ↦ 00-:Δ ) ).if(+ Φ.bytes( φ ↦ --:Δ ),+ step( acc ↦ Φ.dataized( target ↦ items.head ), tup ↦ items.tail )+ ),+ step(ρ, acc, tup) ↦ Φ.dataized( target ↦ tup.length ).eq( b ↦ Φ.bytes( φ ↦ 00-:Δ ) ).if(+ acc,+ ρ.step( acc ↦ acc.concat( b ↦ Φ.dataized( target ↦ tup.head ) ), tup ↦ tup.tail )+ ):φ+ ⟧,+ e ↦ Φ.joined(+ items ↦ Φ.tuple( length ↦ Φ.bytes( φ ↦ 𝜎1:λ ), head ↦ 𝜎2:λ, tail ↦ 𝜎3:λ )+ )+ ⟧+protocol: |+ 𝕄(Φ.e):+ 𝑛·0·1 := Φ.joined( items ↦ Φ.tuple( length ↦ Φ.bytes( φ ↦ 𝜎1:λ ), head ↦ 𝜎2:λ, tail ↦ 𝜎3:λ ) )+ 𝕄(Φ.e.items):+ 𝑛·0·2 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·3 := Φ.tuple( length ↦ 𝑛·0·2 )+ 𝑛·0·4 := Φ.tuple( length ↦ 𝑛·0·2 )+ 𝑛·0·5 := 𝑛·0·4( head ↦ 𝜎2:λ )+ 𝑛·0·6 := Φ.tuple( length ↦ 𝑛·0·2 )+ 𝑛·0·7 := 𝑛·0·6( head ↦ 𝜎2:λ )+ 𝑛·0·8 := 𝑛·0·7( tail ↦ 𝜎3:λ )+ 𝕄(Φ.e.φ):+ 𝑛·0·9 := Φ.tuple( length ↦ 𝑛·0·2 )+ 𝑛·0·10 := 𝑛·0·9( head ↦ 𝜎2:λ )+ 𝑛·0·11 := 𝑛·0·10( tail ↦ 𝜎3:λ )+ 𝑛·0·12 := Φ.tuple( length ↦ 𝑛·0·2 )+ 𝑛·0·13 := 𝑛·0·12( head ↦ 𝜎2:λ )+ 𝑛·0·14 := 𝑛·0·13( tail ↦ 𝜎3:λ )+ 𝑛·0·15 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·16 := Φ.dataized( target ↦ 𝑛·0·14.length )+ 𝔼(L_dataized):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.tuple( length ↦ 𝑛·0·15 )+ 𝑛·1·2 := 𝑛·1·1( head ↦ 𝜎2:λ )+ 𝑛·1·3 := 𝑛·1·2( tail ↦ 𝜎3:λ )+ 𝑛·1·4 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝛿1·1 := 𝔻(𝜎1:λ) # 𝔻(ξ.target)+ 𝑛·1·5 := Φ.bytes( φ ↦ 𝜎4:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.bytes( φ ↦ 𝜎4:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝑛·0·17 := Φ.bytes( φ ↦ 00-:Δ )+ 𝑛·0·18 := 𝑛·1·6.eq( b ↦ 𝑛·0·17 )+ 𝔼(L_bytes_eq):+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·2·1 := Φ.bytes( φ ↦ 𝜎4:λ )+ 𝛿1·2 := 𝔻(𝜎4:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·2 := Φ.bytes( φ ↦ 00-:Δ )+ 𝛿·2·1 := 00-+ 𝛿2·2 := 𝛿·2·1 # 𝔻(ξ.b)+ 𝑛·2·3 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎5:λ ⟧ ) # 𝑛+ 𝕄(𝑛·2·3):+ 𝑛·2·4 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎5:λ ⟧ )+ 𝑛·2·5 := 𝑛·2·4 # 𝕄(𝑛·2·3)+ 𝑛·0·19 := Φ.bytes( φ ↦ --:Δ )+ 𝑛·0·20 := ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ 𝜎5:λ ⟧( left ↦ 𝑛·0·19 )+ 𝑛·0·21 := Φ.tuple( length ↦ 𝑛·1·4 )+ 𝑛·0·22 := 𝑛·0·21( head ↦ 𝜎2:λ )+ 𝑛·0·23 := 𝑛·0·22( tail ↦ 𝜎3:λ )+ 𝑛·0·24 := Φ.tuple( length ↦ 𝑛·1·4 )+ 𝑛·0·25 := 𝑛·0·24( head ↦ 𝜎2:λ )+ 𝑛·0·26 := 𝑛·0·25( tail ↦ 𝜎3:λ )+ 𝑛·0·27 := Φ.dataized( target ↦ 𝑛·0·26.head )+ 𝔼(L_dataized):+ 𝔻(Φ.a🌵3):+ 𝕄(Φ.a🌵3):+ 𝑛·3·1 := Φ.tuple( length ↦ 𝑛·1·4 )+ 𝑛·3·2 := 𝑛·3·1( head ↦ 𝜎2:λ )+ 𝑛·3·3 := 𝑛·3·2( tail ↦ 𝜎3:λ )+ 𝛿1·3 := 𝔻(𝜎2:λ) # 𝔻(ξ.target)+ 𝑛·3·4 := Φ.bytes( φ ↦ 𝜎6:λ ) # 𝑛+ 𝕄(𝑛·3·4):+ 𝑛·3·5 := Φ.bytes( φ ↦ 𝜎6:λ )+ 𝑛·3·6 := 𝑛·3·5 # 𝕄(𝑛·3·4)+ 𝑛·0·28 := ⟦ acc ↦ ∅, tup ↦ ∅, φ ↦ Φ.dataized( target ↦ tup.length ).eq( b ↦ 𝑛·2·2 ).if( acc, ρ.step( acc ↦ acc.concat( b ↦ Φ.dataized( target ↦ tup.head ) ), tup ↦ tup.tail ) ) ⟧( acc ↦ 𝑛·3·5 )+ 𝑛·0·29 := Φ.tuple( length ↦ 𝑛·1·4 )+ 𝑛·0·30 := 𝑛·0·29( head ↦ 𝜎2:λ )+ 𝑛·0·31 := 𝑛·0·30( tail ↦ 𝜎3:λ )+ 𝑛·0·32 := Φ.tuple( length ↦ 𝑛·1·4 )+ 𝑛·0·33 := 𝑛·0·32( head ↦ 𝜎2:λ )+ 𝑛·0·34 := 𝑛·0·33( tail ↦ 𝜎3:λ )+ 𝑛·0·35 := ⟦ acc ↦ ∅, tup ↦ ∅, φ ↦ Φ.dataized( target ↦ tup.length ).eq( b ↦ 𝑛·2·2 ).if( acc, ρ.step( acc ↦ acc.concat( b ↦ Φ.dataized( target ↦ tup.head ) ), tup ↦ tup.tail ) ) ⟧( acc ↦ 𝑛·3·5 )+ 𝑛·0·36 := 𝑛·0·35( tup ↦ 𝑛·0·34.tail )+ 𝑛·0·37 := ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ 𝜎5:λ ⟧( left ↦ 𝑛·0·19 )+ 𝑛·0·38 := ⟦ acc ↦ ∅, tup ↦ ∅, φ ↦ Φ.dataized( target ↦ tup.length ).eq( b ↦ 𝑛·2·2 ).if( acc, ρ.step( acc ↦ acc.concat( b ↦ Φ.dataized( target ↦ tup.head ) ), tup ↦ tup.tail ) ) ⟧( acc ↦ 𝑛·3·5 )+ 𝑛·0·39 := 𝑛·0·38( tup ↦ 𝑛·0·34.tail )+ 𝑛·0·40 := 𝑛·0·37( right ↦ 𝑛·0·39 )+ 𝔼(L_fork):+ 𝛿1·4 := 𝔻(𝜎5:λ) # 𝔻(ξ.φ)+ 𝕄(Φ.a🌵5):+ 𝑛·4·1 := Φ.bytes( φ ↦ --:Δ )+ 𝑛1·4 := 𝑛·4·1 # 𝕄(ξ.left)+ 𝕄(Φ.a🌵6):+ deferred(𝜎7) := Φ.joined.step( acc ↦ 𝑛·3·5, tup ↦ 𝜎3:λ )+ 𝑛2·4 := 𝜎7:λ # 𝕄(ξ.right)+ 𝔻(𝜎8:λ) == --+ 𝑛3·4 := ⟦ φ ↦ 𝜎8:λ, eq(b) ↦ L_bytes_eq:λ, concat(b) ↦ L_bytes_concat:λ ⟧ # 𝑛1+ 𝑛4·4 := 𝑛2·4 # 𝑛2+ 𝔻(𝜎9:λ) ∈ { 𝔻(𝜎8:λ), 𝔻(𝜎7:λ) }+ 𝑛5·4 := 𝜎9:λ # [𝑛3, 𝑛4]+ 𝑛·4·2 := 𝑛5·4 # 𝑛+ 𝑛·4·3 := 𝑛5·4 # 𝕄(𝑛·4·2)
@@ -0,0 +1,43 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The fork of 'bool.and' from #1817 under an entry that does not say+# 'lenient: true'. A strict join pairs a bare symbol only with the symbol a φ+# chain ends in, and the chain of the second branch stops at the call of+# 'Φ.bool', so there is no symbol to pair it with and the firing gets stuck.+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ join:+ 𝑛3: [𝑛1, 𝑛2]+ 𝑛: 𝑛3+location: 'Q.y'+deep: true+input: |+ ⟦+ bool(if) ↦ ⟦ φ ↦ ξ.if( α0 ↦ ⟦ Δ ⤍ FF- ⟧, α1 ↦ ⟦ Δ ⤍ 00- ⟧ ) ⟧,+ y ↦ ⟦+ r ↦ ⟦+ a ↦ ⟦ λ ⤍ 𝜎1 ⟧,+ b ↦ ⟦ φ ↦ Φ.bool( if ↦ ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ ⟦ λ ⤍ 𝜎2 ⟧ ⟧ ) ⟧,+ λ ⤍ L_fork+ ⟧+ ⟧+ ⟧+fails: "No entry of --symbolic answers the λ function 'L_fork'"+protocol: |+ 𝕄(Φ.y):+ 𝕄(Φ.y.r):+ 𝕄(Φ.y.r.b):+ 𝕄(Φ.y.r.b.φ):+ 𝑛·0·1 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ ⟧ )+ 𝔼(L_fork):+ 𝑛1·1 := 𝜎1:λ # 𝕄(ξ.a)+ 𝕄(Φ.a🌵1):+ 𝕄(Φ.a🌵1.φ):+ 𝑛·1·1 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ ⟧ )+ 𝑛2·1 := 𝑛·1·1:φ # 𝕄(ξ.b)+ stuck(L_fork)
@@ -0,0 +1,44 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A lenient join answers a copy of the branch a bare symbol stands against only+# when that branch holds exactly one symbol (#1817), since only then is it+# clear which symbol the bare one pairs with. Here the call of 'Φ.bool' holds+# two, '𝜎2' and '𝜎3', so the join is refused and the firing gets stuck.+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ join:+ 𝑛3: [𝑛1, 𝑛2]+ lenient: true+ 𝑛: 𝑛3+location: 'Q.y'+deep: true+input: |+ ⟦+ bool(if) ↦ ⟦ φ ↦ ξ.if( α0 ↦ ⟦ Δ ⤍ FF- ⟧, α1 ↦ ⟦ Δ ⤍ 00- ⟧ ) ⟧,+ y ↦ ⟦+ r ↦ ⟦+ a ↦ ⟦ λ ⤍ 𝜎1 ⟧,+ b ↦ ⟦ φ ↦ Φ.bool( if ↦ ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ ⟦ λ ⤍ 𝜎2 ⟧, was ↦ ⟦ λ ⤍ 𝜎3 ⟧ ⟧ ) ⟧,+ λ ⤍ L_fork+ ⟧+ ⟧+ ⟧+fails: "No entry of --symbolic answers the λ function 'L_fork'"+protocol: |+ 𝕄(Φ.y):+ 𝕄(Φ.y.r):+ 𝕄(Φ.y.r.b):+ 𝕄(Φ.y.r.b.φ):+ 𝑛·0·1 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ, was ↦ 𝜎3:λ ⟧ )+ 𝔼(L_fork):+ 𝑛1·1 := 𝜎1:λ # 𝕄(ξ.a)+ 𝕄(Φ.a🌵1):+ 𝕄(Φ.a🌵1.φ):+ 𝑛·1·1 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ, was ↦ 𝜎3:λ ⟧ )+ 𝑛2·1 := 𝑛·1·1:φ # 𝕄(ξ.b)+ stuck(L_fork)
@@ -0,0 +1,25 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The fork the lenient join of #1815 brings together, under an entry that+# does not say 'lenient: true'. A copy and a decorator of it differ in shape,+# so the strict join refuses them and the firing gets stuck, as an entry is+# strict unless it says otherwise.+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ join:+ 𝑛3: [𝑛1, 𝑛2]+ 𝑛: 𝑛3+location: 'Q.y'+input: '⟦ y ↦ ⟦ a ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎1 ⟧, neg ↦ ⟦⟧ ⟧, b ↦ ⟦ φ ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎2 ⟧, neg ↦ ⟦⟧ ⟧ ⟧, λ ⤍ L_fork ⟧.φ ⟧'+fails: "No entry of --symbolic answers the λ function 'L_fork'"+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_fork):+ 𝑛1·1 := ⟦ φ ↦ 𝜎1:λ, neg ↦ ⟦⟧ ⟧ # 𝕄(ξ.a)+ 𝑛2·1 := ⟦ φ ↦ 𝜎2:λ, neg ↦ ⟦⟧ ⟧:φ # 𝕄(ξ.b)+ stuck(L_fork)
@@ -0,0 +1,26 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The very fork '--partial' parks, without the option: a firing with nothing to+# answer fails the run, exactly as a λ function no entry of the '--symbolic'+# file answers does. The protocol keeps what the firing had reached before it+# got stuck, since it records what 𝔼 was asked for and not only what it could+# answer.+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ join:+ 𝑛3: [𝑛1, 𝑛2]+ 𝑛: 𝑛3+location: 'Q.y'+input: '⟦ y ↦ ⟦ a ↦ ⟦ l ↦ ⟦ λ ⤍ 𝜎1 ⟧ ⟧, b ↦ ⟦ l ↦ ⟦ λ ⤍ 𝜎2 ⟧, x ↦ ⟦⟧ ⟧, λ ⤍ L_fork ⟧.l ⟧'+fails: "No entry of --symbolic answers the λ function 'L_fork'"+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_fork):+ 𝑛1·1 := 𝜎1:λ:l # 𝕄(ξ.a)+ 𝑛2·1 := ⟦ l ↦ 𝜎2:λ, x ↦ ⟦⟧ ⟧ # 𝕄(ξ.b)+ stuck(L_fork)
@@ -0,0 +1,17 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A λ name no key of the file matches has nothing to answer it, so the run+# fails and the protocol holds nothing but the run itself.+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.x'+input: '⟦ x ↦ ⟦ λ ⤍ L_none ⟧.foo ⟧'+fails: "No entry of --symbolic answers the λ function 'L_none'"+protocol: |+ 𝕄(Φ.x):+ unanswered(L_none) # 𝕄(L_none:λ)
@@ -0,0 +1,61 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The very operand '--partial' parks, without the option: an operand of a+# firing that reaches the terminator ⊥ still fails the run, as it did before+# #1401, and the protocol keeps what the run had reached when it did.+symbolic: |+ - λ: L_dataized+ dataize:+ 𝛿1: $.target+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_entry+ dataize:+ 𝛿1: $.n+ morph:+ 𝑛1: $.v.φ+ 𝑛: Φ.l🌵.root( 𝑛1 )+ - λ: L_root+ dataize:+ 𝛿1: $.v+ 𝑛: ⟦ ⟧+location: 'Q.l🌵'+deep: true+acyclic: proven+steps: 32+input: >+ ⟦+ number ↦ ⟦ φ ↦ ∅ ⟧,+ bytes ↦ ⟦ φ ↦ ∅, size ↦ ⟦ λ ⤍ L_bytes_size ⟧ ⟧,+ dataized ↦ ⟦ target ↦ ∅, λ ⤍ L_dataized ⟧,+ block ↦ ⟦ data ↦ ∅, buffer ↦ ∅, read ↦ ⟦ φ ↦ Φ.dataized( target ↦ ξ.ρ.data.size ).as-bytes ⟧ ⟧,+ l🌵 ↦ ⟦+ mark ↦ ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧,+ root ↦ ⟦ v ↦ ∅, λ ⤍ L_root ⟧,+ e1 ↦ Φ.l🌵.mark( n ↦ Φ.number( φ ↦ Φ.bytes( φ ↦ ⟦ Δ ⤍ 3F-F0-00-00-00-00-00-00 ⟧ ) ) )( v ↦ Φ.block( buffer ↦ Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎1 ⟧ ) ).read )+ ⟧+ ⟧+fails: 'terminator ⊥'+protocol: |+ 𝕄(Φ.l🌵):+ 𝕄(Φ.l🌵.e1):+ 𝑛·0·1 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝑛·0·2 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·0·3 := ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧( n ↦ 𝑛·0·2 )+ 𝑛·0·4 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·5 := Φ.block( buffer ↦ 𝑛·0·4 )+ 𝑛·0·6 := Φ.block( buffer ↦ 𝑛·0·4 )+ 𝑛·0·7 := ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧( n ↦ 𝑛·0·2 )+ 𝑛·0·8 := 𝑛·0·7( v ↦ 𝑛·0·6.read )+ 𝔼(L_entry):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·1·2 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 3F-F0-00-00-00-00-00-00 # 1.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.n)+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := Φ.block( buffer ↦ 𝑛·0·4 )+ 𝑛·1·4 := Φ.dataized( target ↦ ⊥ )+ 𝔼(L_dataized):
@@ -0,0 +1,52 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The memo of '--acyclic=plausible' keeps no stall the step budget made. The+# formation 'f' is first fired deep inside the operand of 'L_wrap', where the+# budget runs out before 'arg' comes down, so the firing gets stuck. Before+# #1514 the stall was kept, and the firings of the same formation under+# 'Φ.q.φ' and 'Φ.f', where the budget is enough, were told it bare, with+# nothing answered in between. Now the firing under 'Φ.q.φ' brings 'arg'+# down and answers, and the walk leaves that answer in 'f', so it fires+# nothing more when it reaches 'Φ.f' (#1720).+symbolic: |+ - λ: L_outer+ dataize:+ 𝛿1: ξ.arg+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+ - λ: L_wrap+ dataize:+ 𝛿1: ξ.w+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+deep: true+partial: true+acyclic: plausible+steps: 10+input: >+ ⟦ x ↦ ⟦ w ↦ Φ.p, λ ⤍ L_wrap ⟧,+ p ↦ ⟦ φ ↦ Φ.q ⟧,+ q ↦ ⟦ φ ↦ Φ.f ⟧,+ f ↦ ⟦ arg ↦ Φ.c, λ ⤍ L_outer ⟧,+ c ↦ ⟦ φ ↦ Φ.d ⟧,+ d ↦ ⟦ φ ↦ Φ.e ⟧,+ e ↦ ⟦ Δ ⤍ 01- ⟧ ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.x):+ 𝔼(L_wrap):+ 𝔻(Φ.a🌵0):+ 𝔼(L_outer):+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ starved(10)+ stuck(L_outer)+ stuck(L_outer)+ 𝕄(Φ.q):+ 𝕄(Φ.q.φ):+ 𝔼(L_outer):+ 𝔻(Φ.a🌵2):+ 𝛿·3·1 := 01-+ 𝛿1·3 := 𝛿·3·1 # 𝔻(ξ.arg)+ 𝑛·3·1 := 𝜎1:λ # 𝑛+ 𝑛·3·2 := 𝜎1:λ # 𝕄(𝑛·3·1)
@@ -0,0 +1,96 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The memo of '--acyclic=plausible': 𝔼 is a function of the formation it+# fires, so two bindings spelling one term are two firings of one formation,+# and a run firing each of them afresh mints two symbols for one value and+# fires everything under the second once more (#1476). Under the mode the+# second takes what the first answered: the inner sum of 'b' is the inner sum+# of 'a' fired again, and so is the outer one once the inner answers the+# same, so the walk over 'b' reduces nothing, mints nothing and lands 'b' on+# the very symbol 'a' came to. The protocol still writes the two firings+# under 'b', at their own site, each with the answer the firing under 'a'+# made, named after the line that made it, and with no operand line under+# it, since none was reduced.+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+deep: true+acyclic: plausible+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ number(φ) ↦ ⟦ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ a ↦ 7.plus( 5.plus( 6 ) ),+ b ↦ 7.plus( 5.plus( 6 ) ) ⟧+result: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ number(φ) ↦ ⟦ plus(x) ↦ L_number_plus:λ ⟧,+ a ↦ ⟦ φ ↦ 𝜎2:λ, plus(x) ↦ L_number_plus:λ ⟧,+ b ↦ ⟦ φ ↦ 𝜎2:λ, plus(x) ↦ L_number_plus:λ ⟧ ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.a):+ 𝑛·0·1 := Φ.bytes( φ ↦ 40-1C-00-00-00-00-00-00:Δ )+ 𝑛·0·2 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·0·3 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·0·4 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝑛·0·5 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝑛·0·6 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝑛·0·7 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝑛·0·8 := Φ.number( φ ↦ 𝑛·0·7 )+ 𝑛·0·9 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝑛·0·10 := 𝑛·0·9.plus( x ↦ 𝑛·0·8 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := Φ.number( φ ↦ 𝑛·0·7 )+ 𝑛·1·4 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 40-18-00-00-00-00-00-00 # 6.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.number( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.number( φ ↦ 𝜎1:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝑛·0·11 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·0·12 := 𝑛·0·11.plus( x ↦ 𝑛·1·6 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·2·2 := Φ.bytes( φ ↦ 40-1C-00-00-00-00-00-00:Δ )+ 𝛿·2·1 := 40-1C-00-00-00-00-00-00 # 7.0+ 𝛿1·2 := 𝛿·2·1 # 𝔻(ξ.ρ)+ 𝛿2·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.x)+ 𝑛·2·3 := Φ.number( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·2·3):+ 𝑛·2·4 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·2·5 := 𝑛·2·4 # 𝕄(𝑛·2·3)+ 𝕄(Φ.b):+ 𝑛·0·13 := Φ.bytes( φ ↦ 40-1C-00-00-00-00-00-00:Δ )+ 𝑛·0·14 := Φ.number( φ ↦ 𝑛·0·13 )+ 𝑛·0·15 := Φ.number( φ ↦ 𝑛·0·13 )+ 𝑛·0·16 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝑛·0·17 := Φ.number( φ ↦ 𝑛·0·16 )+ 𝑛·0·18 := Φ.number( φ ↦ 𝑛·0·16 )+ 𝑛·0·19 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝑛·0·20 := Φ.number( φ ↦ 𝑛·0·19 )+ 𝑛·0·21 := Φ.number( φ ↦ 𝑛·0·16 )+ 𝑛·0·22 := 𝑛·0·21.plus( x ↦ 𝑛·0·20 )+ 𝔼(L_number_plus):+ 𝑛·3·1 := 𝑛·1·6 # 𝑛+ 𝑛·3·2 := 𝑛·1·7 # 𝕄(𝑛·3·1)+ 𝑛·0·23 := Φ.number( φ ↦ 𝑛·0·13 )+ 𝑛·0·24 := 𝑛·0·23.plus( x ↦ 𝑛·1·6 )+ 𝔼(L_number_plus):+ 𝑛·4·1 := 𝑛·2·4 # 𝑛+ 𝑛·4·2 := 𝑛·2·5 # 𝕄(𝑛·4·1)
@@ -0,0 +1,25 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The deep walk writes what it morphed back into the world (#1720). Before,+# the world stayed as written, so 'b' read 'Φ.a' as 'Φ.foo.x' and fired 'Fn'+# twice more, and the walk fired it once again when it reached 'foo'. Now the+# read of 'Φ.foo' under 'a' leaves the answer in 'foo', the walk leaves what+# it made of 'a' in 'a', and 'Fn' fires once, as it does in EO.+symbolic: |+ - λ: Fn+ 𝑛: ⟦ x ↦ ⟦ y ↦ ⟦ λ ⤍ 𝜎 ⟧ ⟧ ⟧+deep: true+partial: true+acyclic: plausible+input: >+ ⟦ a ↦ Φ.foo.x, b ↦ Φ.a.y, foo ↦ ⟦ λ ⤍ Fn ⟧ ⟧+result: >+ ⟦ a ↦ ⟦ x ↦ ⟦ y ↦ 𝜎1:λ ⟧ ⟧.x, b ↦ Φ.a.y, foo ↦ ⟦ x ↦ ⟦ y ↦ 𝜎1:λ ⟧ ⟧ ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.a):+ 𝔼(Fn):+ 𝑛·1·1 := 𝜎1:λ:y:x # 𝑛+ 𝑛·1·2 := 𝜎1:λ:y:x # 𝕄(𝑛·1·1)
@@ -0,0 +1,62 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The deep walk writes what it morphed back into the copy it stands in, not+# only into the world as written (#1720). Here 'm' lives in the copy+# 'Φ.same( left ↦ … )', and 'φ' reads it twice before the walk reaches 'm'.+# Before, every read fired 'L_bytes_eq' again, and so did the walk at 'm'. Now+# the first read leaves the answer in 'm', so the second read and the walk at+# 'm' fire nothing, and 'L_bytes_eq' fires twice: once for 'm' and once for+# 'm.eq( b ↦ m )'.+symbolic: |+ - λ: L_bytes_eq+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.b+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.e'+deep: true+partial: true+acyclic: plausible+input: >+ ⟦ bytes(φ) ↦ ⟦ eq(ρ, b) ↦ L_bytes_eq:λ ⟧,+ same(left) ↦ ⟦ φ ↦ m.eq( b ↦ m ), m ↦ left.eq( b ↦ Φ.bytes( φ ↦ 00-:Δ ) ) ⟧,+ e ↦ Φ.same( left ↦ Φ.bytes( φ ↦ 𝜎1:λ ) ) ⟧+result: >+ ⟦ left ↦ Φ.bytes( φ ↦ 𝜎1:λ ),+ φ ↦ ⟦ φ ↦ 𝜎3:λ, eq(b) ↦ L_bytes_eq:λ ⟧,+ m ↦ ⟦ φ ↦ 𝜎2:λ, eq(b) ↦ L_bytes_eq:λ ⟧ ⟧+protocol: |+ 𝕄(Φ.e):+ 𝑛·0·1 := Φ.same( left ↦ Φ.bytes( φ ↦ 𝜎1:λ ) )+ 𝕄(Φ.e.left):+ 𝑛·0·2 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝕄(Φ.e.φ):+ 𝑛·0·3 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·4 := 𝑛·0·3.eq( b ↦ Φ.bytes( φ ↦ 00-:Δ ) )+ 𝔼(L_bytes_eq):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝛿1·1 := 𝔻(𝜎1:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·2 := Φ.bytes( φ ↦ 00-:Δ )+ 𝛿·1·1 := 00-+ 𝛿2·1 := 𝛿·1·1 # 𝔻(ξ.b)+ 𝑛·1·3 := Φ.bytes( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·1·3):+ 𝑛·1·4 := Φ.bytes( φ ↦ 𝜎2:λ )+ 𝑛·1·5 := 𝑛·1·4 # 𝕄(𝑛·1·3)+ 𝑛·0·5 := 𝑛·1·4.eq( b ↦ 𝑛·1·4 )+ 𝔼(L_bytes_eq):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.bytes( φ ↦ 𝜎2:λ )+ 𝛿1·2 := 𝔻(𝜎2:λ) # 𝔻(ξ.ρ)+ 𝛿2·2 := 𝔻(𝜎2:λ) # 𝔻(ξ.b)+ 𝑛·2·2 := Φ.bytes( φ ↦ 𝜎3:λ ) # 𝑛+ 𝕄(𝑛·2·2):+ 𝑛·2·3 := Φ.bytes( φ ↦ 𝜎3:λ )+ 𝑛·2·4 := 𝑛·2·3 # 𝕄(𝑛·2·2)
@@ -0,0 +1,38 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The head pass of 𝕄 takes four steps through the four φ layers of 'Φ.e'+# before it reads 'eq' of the inner formation, whose 'φ' reads its sibling+# 'm'. Under '--deep' the head pass fires 'm' first and writes its answer back+# (#1727). Before #1731 it fired 'm' at the depth of its fourth step, so the+# firing ran out of ten steps, and 'L_dataized' fired three times without+# reaching the answer. Now the head pass fires 'm' at the depth it began at,+# the way the deep walk at the end of 𝕄 fires it, and 'm' fires once.+symbolic: |+ - λ: L_dataized+ dataize:+ 𝛿1: $.target+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.e'+deep: true+partial: true+acyclic: plausible+steps: 10+input: >+ ⟦ bytes(φ) ↦ ⟦ eq(ρ, b) ↦ L_bytes_eq:λ ⟧,+ dataized(target) ↦ L_dataized:λ,+ e ↦ ⟦ φ ↦ ⟦ φ ↦ ⟦ φ ↦ ⟦ φ ↦ m, m ↦ Φ.dataized( target ↦ Φ.bytes( φ ↦ 𝜎1:λ ) ) ⟧ ⟧ ⟧ ⟧.eq ⟧+result: '⟦ b ↦ ∅, λ ⤍ L_bytes_eq ⟧'+protocol: |+ 𝕄(Φ.e):+ 𝑛·0·1 := Φ.dataized( target ↦ Φ.bytes( φ ↦ 𝜎1:λ ) )+ 𝔼(L_dataized):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝛿1·1 := 𝔻(𝜎1:λ) # 𝔻(ξ.target)+ 𝑛·1·2 := Φ.bytes( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·1·2):+ 𝑛·1·3 := Φ.bytes( φ ↦ 𝜎2:λ )+ 𝑛·1·4 := 𝑛·1·3 # 𝕄(𝑛·1·2)
@@ -0,0 +1,56 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The term at 'Φ.e' reads 'φ' of the object 'Φ.same' makes, and that 'φ'+# reads its sibling 'm' twice. Before #1727 the head pass of 𝕄 copied 'm'+# into both reads before anything fired, so the deep walk later fired+# 'L_dataized' again for each copy, four firings in all. Now, under '--deep',+# the head pass first fires the reads of siblings in the binding it+# dispatches into, the way the deep walk fires them, and writes their answers+# back, so 'm' fires once and both reads take its answer: two firings, as+# many as the same object costs without the '.φ'.+symbolic: |+ - λ: L_bytes_eq+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.b+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_dataized+ dataize:+ 𝛿1: $.target+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.e'+deep: true+partial: true+acyclic: plausible+input: >+ ⟦ bytes(φ) ↦ ⟦ eq(ρ, b) ↦ L_bytes_eq:λ ⟧,+ dataized(target) ↦ L_dataized:λ,+ same(left) ↦ ⟦ φ ↦ m.eq( b ↦ m ), m ↦ Φ.dataized( target ↦ left ) ⟧,+ e ↦ Φ.same( left ↦ Φ.bytes( φ ↦ 𝜎1:λ ) ).φ ⟧+result: '⟦ φ ↦ 𝜎3:λ, eq(b) ↦ L_bytes_eq:λ ⟧'+protocol: |+ 𝕄(Φ.e):+ 𝑛·0·1 := Φ.same( left ↦ Φ.bytes( φ ↦ 𝜎1:λ ) )+ 𝑛·0·2 := Φ.dataized( target ↦ Φ.bytes( φ ↦ 𝜎1:λ ) )+ 𝔼(L_dataized):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝛿1·1 := 𝔻(𝜎1:λ) # 𝔻(ξ.target)+ 𝑛·1·2 := Φ.bytes( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·1·2):+ 𝑛·1·3 := Φ.bytes( φ ↦ 𝜎2:λ )+ 𝑛·1·4 := 𝑛·1·3 # 𝕄(𝑛·1·2)+ 𝑛·0·3 := 𝑛·1·3.eq( b ↦ 𝑛·1·3 )+ 𝔼(L_bytes_eq):+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·2·1 := Φ.bytes( φ ↦ 𝜎2:λ )+ 𝛿1·2 := 𝔻(𝜎2:λ) # 𝔻(ξ.ρ)+ 𝛿2·2 := 𝔻(𝜎2:λ) # 𝔻(ξ.b)+ 𝑛·2·2 := Φ.bytes( φ ↦ 𝜎3:λ ) # 𝑛+ 𝕄(𝑛·2·2):+ 𝑛·2·3 := Φ.bytes( φ ↦ 𝜎3:λ )+ 𝑛·2·4 := 𝑛·2·3 # 𝕄(𝑛·2·2)
@@ -0,0 +1,58 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The memo of '--acyclic=plausible' stamps a stall with the count of answers+# the memo held when the firing began, not when it failed. The firing under+# 'x' brings 'first' down through 'L_inner', which answers, and then gets+# stuck on 'L_none'. Before #1507 the stall was stamped after that answer, so+# the firing under 'y', the very same formation, was told the stall bare, as+# if nothing was answered since. Now the answer made inside the first firing+# counts as one made after it began, so the firing under 'y' reduces its+# operands again.+symbolic: |+ - λ: L_outer+ dataize:+ 𝛿1: ξ.first+ 𝛿2: ξ.second+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+ - λ: L_inner+ 𝑛: ⟦ Δ ⤍ 01- ⟧+deep: true+partial: true+acyclic: plausible+steps: 64+input: >+ ⟦ x ↦ ⟦ first ↦ Φ.s, second ↦ ⟦ λ ⤍ L_none ⟧, λ ⤍ L_outer ⟧,+ y ↦ ⟦ first ↦ Φ.s, second ↦ ⟦ λ ⤍ L_none ⟧, λ ⤍ L_outer ⟧,+ s ↦ ⟦ φ ↦ Φ.g ⟧,+ g ↦ ⟦ λ ⤍ L_inner ⟧ ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.x):+ 𝔼(L_outer):+ 𝔻(Φ.a🌵0):+ 𝔼(L_inner):+ 𝑛·2·1 := 01-:Δ # 𝑛+ 𝑛·2·2 := 01-:Δ # 𝕄(𝑛·2·1)+ 𝛿·1·1 := 01-+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.first)+ 𝔻(Φ.a🌵1):+ unanswered(L_none) # 𝔻(L_none:λ)+ stuck(L_none)+ 𝕄(Φ.y):+ 𝔼(L_outer):+ 𝔻(Φ.a🌵2):+ 𝔼(L_inner):+ 𝑛·4·1 := 01-:Δ # 𝑛+ 𝑛·4·2 := 01-:Δ # 𝕄(𝑛·4·1)+ 𝛿·3·1 := 01-+ 𝛿1·3 := 𝛿·3·1 # 𝔻(ξ.first)+ 𝔻(Φ.a🌵3):+ unanswered(L_none) # 𝔻(L_none:λ)+ stuck(L_none)+ 𝕄(Φ.s):+ 𝕄(Φ.s.φ):+ 𝔼(L_inner):+ 𝑛·5·1 := 01-:Δ # 𝑛+ 𝑛·5·2 := 01-:Δ # 𝕄(𝑛·5·1)
@@ -0,0 +1,54 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The memo of '--acyclic=plausible' keeps a stall only while nothing new was+# answered. The firing of 'f' under 'x' brings 'big' down inside the box of+# 's', and 's' is within 'big', so the mode cuts the operand and the firing+# gets stuck. Then 'g' answers, and 'f' is fired again at its own site, where+# nothing cuts it. Before #1495 that firing took the stall the first one met+# and reduced nothing; now it brings 'big' down and answers.+symbolic: |+ - λ: L_f+ dataize:+ 𝛿1: $.arg+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+ - λ: L_g+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+deep: true+partial: true+acyclic: plausible+steps: 32+input: >+ ⟦ x ↦ ⟦ λ ⤍ L_f, arg ↦ Φ.s ⟧,+ g ↦ ⟦ λ ⤍ L_g ⟧,+ f ↦ ⟦ λ ⤍ L_f, arg ↦ Φ.big ⟧,+ s ↦ ⟦ φ ↦ Φ.f ⟧,+ big ↦ ⟦ φ ↦ Φ.k( x ↦ Φ.f ) ⟧,+ k ↦ ⟦ x ↦ ∅, φ ↦ ⟦ Δ ⤍ 01- ⟧ ⟧ ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.x):+ 𝔼(L_f):+ 𝔻(Φ.a🌵0):+ 𝔼(L_f):+ 𝔻(Φ.a🌵1):+ looped(Φ.f:φ) # plausible+ stuck(L_f)+ stuck(L_f)+ 𝕄(Φ.g):+ 𝔼(L_g):+ 𝑛·3·1 := 𝜎1:λ # 𝑛+ 𝑛·3·2 := 𝜎1:λ # 𝕄(𝑛·3·1)+ 𝕄(Φ.f):+ 𝔼(L_f):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·4·1 := Φ.k( x ↦ Φ.f )+ 𝛿·4·1 := 01-+ 𝛿1·4 := 𝛿·4·1 # 𝔻(ξ.arg)+ 𝑛·4·2 := 𝜎2:λ # 𝑛+ 𝑛·4·3 := 𝜎2:λ # 𝕄(𝑛·4·2)+ 𝕄(Φ.big):+ 𝕄(Φ.big.φ):+ 𝑛·0·1 := Φ.k( x ↦ Φ.f )
@@ -0,0 +1,65 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# Under '--deep' the head pass of 𝕄 fires the reads of siblings in the+# binding it dispatches into before it reads that binding (#1727), and only+# them. Here every sibling 'φ' reads is 'a', which is no λ, so nothing fires+# before the head pass reads 'φ', and each of the two 'L_plus' fires once.+# Walking the whole binding instead would settle 'a.twice.plus' on the way,+# which fires the inner 'L_plus', and keep nothing of it, since what it+# settles to is a 'plus' still waiting for 'x' and no answer of a λ. The head+# pass would then fire the inner 'L_plus' again, three firings in all.+symbolic: |+ - λ: L_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.e'+deep: true+partial: true+input: >+ ⟦ bytes(φ) ↦ ⟦ plus(ρ, x) ↦ L_plus:λ, twice(ρ) ↦ ⟦ φ ↦ ξ.ρ.plus( x ↦ ξ.ρ ) ⟧ ⟧,+ pair(a) ↦ ⟦ φ ↦ a.twice.plus( x ↦ a ) ⟧,+ e ↦ Φ.pair( Φ.bytes( φ ↦ 𝜎1:λ ) ).φ ⟧+result: '⟦ φ ↦ 𝜎3:λ, plus(x) ↦ L_plus:λ, twice ↦ ρ.plus( x ↦ ρ ):φ ⟧'+protocol: |+ 𝕄(Φ.e):+ 𝑛·0·1 := Φ.pair( a ↦ Φ.bytes( φ ↦ 𝜎1:λ ) )+ 𝑛·0·2 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·3 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·4 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·5 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·6 := 𝑛·0·5.plus( x ↦ 𝑛·0·5 )+ 𝔼(L_plus):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝛿1·1 := 𝔻(𝜎1:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·2 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝛿2·1 := 𝔻(𝜎1:λ) # 𝔻(ξ.x)+ 𝑛·1·3 := Φ.bytes( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·1·3):+ 𝑛·1·4 := Φ.bytes( φ ↦ 𝜎2:λ )+ 𝑛·1·5 := 𝑛·1·4 # 𝕄(𝑛·1·3)+ 𝑛·0·7 := 𝑛·1·4.plus( x ↦ 𝑛·1·2 )+ 𝕄(Φ.e.x):+ 𝑛·0·8 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·9 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·10 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝔼(L_plus):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.bytes( φ ↦ 𝜎2:λ )+ 𝛿1·2 := 𝔻(𝜎2:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵3):+ 𝕄(Φ.a🌵3):+ 𝑛·2·2 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝛿2·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.x)+ 𝑛·2·3 := Φ.bytes( φ ↦ 𝜎3:λ ) # 𝑛+ 𝕄(𝑛·2·3):+ 𝑛·2·4 := Φ.bytes( φ ↦ 𝜎3:λ )+ 𝑛·2·5 := 𝑛·2·4 # 𝕄(𝑛·2·3)
@@ -0,0 +1,48 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The fork of 'bool.and' from #1817: one branch is a bare symbol, the other a+# call of 'Φ.bool', whose φ is code and not a formation, so its φ chain ends in+# no symbol. The call holds one symbol, '𝜎2', so a lenient join answers a copy+# of the call with '𝜎2' replaced by a fresh '𝜎3', which stands for either+# '𝜎1' or '𝜎2'. The join reads nothing outside the two branches.+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ join:+ 𝑛3: [𝑛1, 𝑛2]+ lenient: true+ 𝑛: 𝑛3+location: 'Q.y'+deep: true+input: |+ ⟦+ bool(if) ↦ ⟦ φ ↦ ξ.if( α0 ↦ ⟦ Δ ⤍ FF- ⟧, α1 ↦ ⟦ Δ ⤍ 00- ⟧ ) ⟧,+ y ↦ ⟦+ r ↦ ⟦+ a ↦ ⟦ λ ⤍ 𝜎1 ⟧,+ b ↦ ⟦ φ ↦ Φ.bool( if ↦ ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ ⟦ λ ⤍ 𝜎2 ⟧ ⟧ ) ⟧,+ λ ⤍ L_fork+ ⟧+ ⟧+ ⟧+result: 'Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎3:λ ⟧ ):φ:r'+protocol: |+ 𝕄(Φ.y):+ 𝕄(Φ.y.r):+ 𝕄(Φ.y.r.b):+ 𝕄(Φ.y.r.b.φ):+ 𝑛·0·1 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ ⟧ )+ 𝔼(L_fork):+ 𝑛1·1 := 𝜎1:λ # 𝕄(ξ.a)+ 𝕄(Φ.a🌵1):+ 𝕄(Φ.a🌵1.φ):+ 𝑛·1·1 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ ⟧ )+ 𝑛2·1 := 𝑛·1·1:φ # 𝕄(ξ.b)+ 𝔻(𝜎3:λ) ∈ { 𝔻(𝜎1:λ), 𝔻(𝜎2:λ) }+ 𝑛3·1 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎3:λ ⟧ ):φ # [𝑛1, 𝑛2]+ 𝑛·1·2 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎3:λ ⟧ ):φ # 𝑛+ 𝑛·1·3 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎3:λ ⟧ ):φ # 𝕄(𝑛·1·2)
@@ -0,0 +1,38 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A datum is never joined with anything, which is why a branch carrying one+# goes through 'symbolize' first: a value somebody worked out and a value+# nobody did are a difference in kind and not in value, and after that stage+# both branches carry ⟦ λ ⤍ 𝜎 ⟧ where they differ. The symbol the literal+# stood into is a symbol like any other here, so what the fork answers is the+# join of the two and what is known about the literal stays on the line the+# 'symbolize' stage wrote it on. Both stages walk the φ chain and nothing+# else, that being where the value of a branch is reached (#1293).+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ symbolize:+ 𝑛3: 𝑛1+ 𝑛4: 𝑛2+ join:+ 𝑛5: [𝑛3, 𝑛4]+ 𝑛: 𝑛5+location: 'Q.y'+input: '⟦ y ↦ ⟦ a ↦ ⟦ φ ↦ ⟦ Δ ⤍ 01- ⟧ ⟧, b ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎7 ⟧ ⟧, λ ⤍ L_fork ⟧.φ ⟧'+result: '𝜎9:λ'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_fork):+ 𝑛1·1 := 01-:Δ:φ # 𝕄(ξ.a)+ 𝑛2·1 := 𝜎7:λ:φ # 𝕄(ξ.b)+ 𝔻(𝜎8:λ) == 01-+ 𝑛3·1 := 𝜎8:λ:φ # 𝑛1+ 𝑛4·1 := 𝑛2·1 # 𝑛2+ 𝔻(𝜎9:λ) ∈ { 𝔻(𝜎8:λ), 𝔻(𝜎7:λ) }+ 𝑛5·1 := 𝜎9:λ:φ # [𝑛3, 𝑛4]+ 𝑛·1·1 := 𝑛5·1 # 𝑛+ 𝑛·1·2 := 𝑛5·1 # 𝕄(𝑛·1·1)
@@ -0,0 +1,30 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A fork whose one branch calls a method often meets a decorator: one branch+# comes to a copy, the other to a formation whose φ is that copy. The two+# differ in shape, so a strict join refuses them. An entry that says+# 'lenient: true' joins them into the decorator, with a fresh symbol minted+# inside it the usual way (#1815).+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ join:+ 𝑛3: [𝑛1, 𝑛2]+ lenient: true+ 𝑛: 𝑛3+location: 'Q.y'+input: '⟦ y ↦ ⟦ a ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎1 ⟧, neg ↦ ⟦⟧ ⟧, b ↦ ⟦ φ ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎2 ⟧, neg ↦ ⟦⟧ ⟧ ⟧, λ ⤍ L_fork ⟧.φ ⟧'+result: '⟦ φ ↦ 𝜎3:λ, neg ↦ ⟦⟧ ⟧'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_fork):+ 𝑛1·1 := ⟦ φ ↦ 𝜎1:λ, neg ↦ ⟦⟧ ⟧ # 𝕄(ξ.a)+ 𝑛2·1 := ⟦ φ ↦ 𝜎2:λ, neg ↦ ⟦⟧ ⟧:φ # 𝕄(ξ.b)+ 𝔻(𝜎3:λ) ∈ { 𝔻(𝜎1:λ), 𝔻(𝜎2:λ) }+ 𝑛3·1 := ⟦ φ ↦ 𝜎3:λ, neg ↦ ⟦⟧ ⟧:φ # [𝑛1, 𝑛2]+ 𝑛·1·1 := 𝑛3·1 # 𝑛+ 𝑛·1·2 := 𝑛3·1 # 𝕄(𝑛·1·1)
@@ -0,0 +1,29 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The lenient join of #1815 does not care which branch is the decorator: with+# the decorator on the left and the copy it decorates on the right, it answers+# the same decorator. A copy is a decorator of its own symbol too, so the join+# takes the branch with the longer φ chain for the decorator.+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ join:+ 𝑛3: [𝑛1, 𝑛2]+ lenient: true+ 𝑛: 𝑛3+location: 'Q.y'+input: '⟦ y ↦ ⟦ a ↦ ⟦ φ ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎1 ⟧, neg ↦ ⟦⟧ ⟧ ⟧, b ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎2 ⟧, neg ↦ ⟦⟧ ⟧, λ ⤍ L_fork ⟧.φ ⟧'+result: '⟦ φ ↦ 𝜎3:λ, neg ↦ ⟦⟧ ⟧'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_fork):+ 𝑛1·1 := ⟦ φ ↦ 𝜎1:λ, neg ↦ ⟦⟧ ⟧:φ # 𝕄(ξ.a)+ 𝑛2·1 := ⟦ φ ↦ 𝜎2:λ, neg ↦ ⟦⟧ ⟧ # 𝕄(ξ.b)+ 𝔻(𝜎3:λ) ∈ { 𝔻(𝜎1:λ), 𝔻(𝜎2:λ) }+ 𝑛3·1 := ⟦ φ ↦ 𝜎3:λ, neg ↦ ⟦⟧ ⟧:φ # [𝑛1, 𝑛2]+ 𝑛·1·1 := 𝑛3·1 # 𝑛+ 𝑛·1·2 := 𝑛3·1 # 𝕄(𝑛·1·1)
@@ -0,0 +1,121 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A fork one branch of which is a literal ⊥ is how a program spells "raise+# unless the condition holds", and the other branch is a perfectly good value.+# The deep walk fires it, since that ⊥ is an argument the program wrote and no+# ξ.ρ the walk reduced to nothing, and the join says on which side of the+# condition the program raises and answers the other side (#1405).+symbolic: |+ - λ: L_number_gt+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.bool( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_fork+ dataize:+ 𝛿1: $.ρ+ morph:+ 𝑛1: $.then+ 𝑛2: $.else+ symbolize:+ 𝑛3: 𝑛1+ 𝑛4: 𝑛2+ join:+ 𝑛5: [𝑛3, 𝑛4]+ 𝑛: 𝑛5+location: 'Q.@'+deep: true+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ bool(φ) ↦ ⟦ if ↦ ⟦ ρ ↦ ∅, then ↦ ∅, else ↦ ∅, λ ⤍ L_fork ⟧ ⟧,+ number(φ) ↦ ⟦+ gt(ρ, x) ↦ ⟦ λ ⤍ L_number_gt ⟧,+ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ @ ↦ 5.gt( 0 ).if( then ↦ 1.plus( 2 ), else ↦ ⊥ ).plus( 6 ) ⟧+result: |-+ ⟦ φ ↦ 𝜎3:λ, gt(x) ↦ L_number_gt:λ, plus(x) ↦ L_number_plus:λ ⟧+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := 5+ 𝑛·0·2 := 𝑛·0·1.gt( x ↦ 0 )+ 𝔼(L_number_gt):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := 5+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := 0+ 𝑛·1·4 := Φ.bytes( φ ↦ 00-00-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 00-00-00-00-00-00-00-00 # 0.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.bool( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.bool( φ ↦ 𝜎1:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝑛·0·3 := 𝑛·1·6.if( then ↦ 1.plus( 2 ) )+ 𝑛·0·4 := 𝑛·0·3( else ↦ ⊥ )+ 𝔼(L_fork):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.bool( φ ↦ 𝜎1:λ )+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.ρ)+ 𝕄(Φ.a🌵3):+ 𝑛·2·2 := 1+ 𝑛·2·3 := 𝑛·2·2.plus( x ↦ 2 )+ 𝕄(Φ.a🌵3.x):+ 𝑛·2·4 := Φ.bytes( φ ↦ 40-00-00-00-00-00-00-00:Δ )+ 𝑛·2·5 := Φ.number( φ ↦ 𝑛·2·4 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵4):+ 𝕄(Φ.a🌵4):+ 𝑛·3·1 := 1+ 𝑛·3·2 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝛿·3·1 := 3F-F0-00-00-00-00-00-00 # 1.0+ 𝛿1·3 := 𝛿·3·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵5):+ 𝕄(Φ.a🌵5):+ 𝑛·3·3 := Φ.number( φ ↦ 𝑛·2·4 )+ 𝑛·3·4 := Φ.bytes( φ ↦ 40-00-00-00-00-00-00-00:Δ )+ 𝛿·3·2 := 40-00-00-00-00-00-00-00 # 2.0+ 𝛿2·3 := 𝛿·3·2 # 𝔻(ξ.x)+ 𝑛·3·5 := Φ.number( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·3·5):+ 𝑛·3·6 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·3·7 := 𝑛·3·6 # 𝕄(𝑛·3·5)+ 𝑛1·2 := 𝑛·3·7 # 𝕄(ξ.then)+ 𝑛2·2 := ⊥ # 𝕄(ξ.else)+ 𝑛3·2 := 𝑛1·2 # 𝑛1+ 𝑛4·2 := ⊥ # 𝑛2+ terminate(𝔻(𝜎1:λ), right) # 𝑛4+ 𝑛5·2 := 𝑛3·2 # [𝑛3, 𝑛4]+ 𝑛·2·6 := 𝑛5·2 # 𝑛+ 𝑛·2·7 := 𝑛5·2 # 𝕄(𝑛·2·6)+ 𝑛·0·5 := 𝑛·3·6.plus( x ↦ 6 )+ 𝕄(Φ.φ.x):+ 𝑛·0·6 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝑛·0·7 := Φ.number( φ ↦ 𝑛·0·6 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵7):+ 𝕄(Φ.a🌵7):+ 𝑛·4·1 := Φ.number( φ ↦ 𝜎2:λ )+ 𝛿1·4 := 𝔻(𝜎2:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵8):+ 𝕄(Φ.a🌵8):+ 𝑛·4·2 := Φ.number( φ ↦ 𝑛·0·6 )+ 𝑛·4·3 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝛿·4·1 := 40-18-00-00-00-00-00-00 # 6.0+ 𝛿2·4 := 𝛿·4·1 # 𝔻(ξ.x)+ 𝑛·4·4 := Φ.number( φ ↦ 𝜎3:λ ) # 𝑛+ 𝕄(𝑛·4·4):+ 𝑛·4·5 := Φ.number( φ ↦ 𝜎3:λ )+ 𝑛·4·6 := 𝑛·4·5 # 𝕄(𝑛·4·4)
@@ -0,0 +1,126 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# EO raises with a copy of an object whose λ function the file leaves out on+# purpose, here 'L_throw', rather than with ⊥. The entry of the fork names it+# among its terminators, so the join takes the branch that comes to such a+# copy for one that raises, the way it takes ⊥, and answers the other branch.+# The morph of that branch stops at the copy and never walks into its message,+# which here would fire 'L_number_plus' for nothing (#1865).+symbolic: |+ - λ: L_number_gt+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.bool( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_fork+ dataize:+ 𝛿1: $.ρ+ morph:+ 𝑛1: $.then+ 𝑛2: $.else+ symbolize:+ 𝑛3: 𝑛1+ 𝑛4: 𝑛2+ join:+ 𝑛5: [𝑛3, 𝑛4]+ terminators: [L_throw]+ 𝑛: 𝑛5+location: 'Q.@'+deep: true+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ error(message) ↦ ⟦ λ ⤍ L_throw ⟧,+ bool(φ) ↦ ⟦ if ↦ ⟦ ρ ↦ ∅, then ↦ ∅, else ↦ ∅, λ ⤍ L_fork ⟧ ⟧,+ number(φ) ↦ ⟦+ gt(ρ, x) ↦ ⟦ λ ⤍ L_number_gt ⟧,+ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ @ ↦ 5.gt( 0 ).if( then ↦ 1.plus( 2 ), else ↦ Φ.error( message ↦ 7.plus( 8 ) ) ).plus( 6 ) ⟧+result: |-+ ⟦ φ ↦ 𝜎3:λ, gt(x) ↦ L_number_gt:λ, plus(x) ↦ L_number_plus:λ ⟧+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := 5+ 𝑛·0·2 := 𝑛·0·1.gt( x ↦ 0 )+ 𝔼(L_number_gt):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := 5+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := 0+ 𝑛·1·4 := Φ.bytes( φ ↦ 00-00-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 00-00-00-00-00-00-00-00 # 0.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.bool( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.bool( φ ↦ 𝜎1:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝑛·0·3 := 𝑛·1·6.if( then ↦ 1.plus( 2 ) )+ 𝑛·0·4 := 𝑛·0·3( else ↦ Φ.error( message ↦ 7.plus( 8 ) ) )+ 𝔼(L_fork):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.bool( φ ↦ 𝜎1:λ )+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.ρ)+ 𝕄(Φ.a🌵3):+ 𝑛·2·2 := 1+ 𝑛·2·3 := 𝑛·2·2.plus( x ↦ 2 )+ 𝕄(Φ.a🌵3.x):+ 𝑛·2·4 := Φ.bytes( φ ↦ 40-00-00-00-00-00-00-00:Δ )+ 𝑛·2·5 := Φ.number( φ ↦ 𝑛·2·4 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵4):+ 𝕄(Φ.a🌵4):+ 𝑛·3·1 := 1+ 𝑛·3·2 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝛿·3·1 := 3F-F0-00-00-00-00-00-00 # 1.0+ 𝛿1·3 := 𝛿·3·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵5):+ 𝕄(Φ.a🌵5):+ 𝑛·3·3 := Φ.number( φ ↦ 𝑛·2·4 )+ 𝑛·3·4 := Φ.bytes( φ ↦ 40-00-00-00-00-00-00-00:Δ )+ 𝛿·3·2 := 40-00-00-00-00-00-00-00 # 2.0+ 𝛿2·3 := 𝛿·3·2 # 𝔻(ξ.x)+ 𝑛·3·5 := Φ.number( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·3·5):+ 𝑛·3·6 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·3·7 := 𝑛·3·6 # 𝕄(𝑛·3·5)+ 𝑛1·2 := 𝑛·3·7 # 𝕄(ξ.then)+ 𝕄(Φ.a🌵6):+ 𝑛·2·6 := Φ.error( message ↦ 7.plus( 8 ) )+ 𝑛2·2 := 𝑛·2·6 # 𝕄(ξ.else)+ 𝑛3·2 := 𝑛1·2 # 𝑛1+ 𝑛4·2 := 𝑛·2·6 # 𝑛2+ terminate(𝔻(𝜎1:λ), right) # 𝑛4+ 𝑛5·2 := 𝑛3·2 # [𝑛3, 𝑛4]+ 𝑛·2·7 := 𝑛5·2 # 𝑛+ 𝑛·2·8 := 𝑛5·2 # 𝕄(𝑛·2·7)+ 𝑛·0·5 := 𝑛·3·6.plus( x ↦ 6 )+ 𝕄(Φ.φ.x):+ 𝑛·0·6 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝑛·0·7 := Φ.number( φ ↦ 𝑛·0·6 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵7):+ 𝕄(Φ.a🌵7):+ 𝑛·4·1 := Φ.number( φ ↦ 𝜎2:λ )+ 𝛿1·4 := 𝔻(𝜎2:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵8):+ 𝕄(Φ.a🌵8):+ 𝑛·4·2 := Φ.number( φ ↦ 𝑛·0·6 )+ 𝑛·4·3 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝛿·4·1 := 40-18-00-00-00-00-00-00 # 6.0+ 𝛿2·4 := 𝛿·4·1 # 𝔻(ξ.x)+ 𝑛·4·4 := Φ.number( φ ↦ 𝜎3:λ ) # 𝑛+ 𝕄(𝑛·4·4):+ 𝑛·4·5 := Φ.number( φ ↦ 𝜎3:λ )+ 𝑛·4·6 := 𝑛·4·5 # 𝕄(𝑛·4·4)
@@ -0,0 +1,120 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The same fork with its branches given by position and the ⊥ on the other+# side: a positional ⊥ is as much an argument the program wrote as a named one,+# so the walk fires the fork all the same, and the join says the program raises+# on the left and answers the right (#1405).+symbolic: |+ - λ: L_number_gt+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.bool( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_fork+ dataize:+ 𝛿1: $.ρ+ morph:+ 𝑛1: $.then+ 𝑛2: $.else+ symbolize:+ 𝑛3: 𝑛1+ 𝑛4: 𝑛2+ join:+ 𝑛5: [𝑛3, 𝑛4]+ 𝑛: 𝑛5+location: 'Q.@'+deep: true+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ bool(φ) ↦ ⟦ if ↦ ⟦ ρ ↦ ∅, then ↦ ∅, else ↦ ∅, λ ⤍ L_fork ⟧ ⟧,+ number(φ) ↦ ⟦+ gt(ρ, x) ↦ ⟦ λ ⤍ L_number_gt ⟧,+ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ @ ↦ 5.gt( 0 ).if( ⊥, 1.plus( 2 ) ).plus( 6 ) ⟧+result: |-+ ⟦ φ ↦ 𝜎3:λ, gt(x) ↦ L_number_gt:λ, plus(x) ↦ L_number_plus:λ ⟧+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := 5+ 𝑛·0·2 := 𝑛·0·1.gt( x ↦ 0 )+ 𝔼(L_number_gt):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := 5+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := 0+ 𝑛·1·4 := Φ.bytes( φ ↦ 00-00-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 00-00-00-00-00-00-00-00 # 0.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.bool( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.bool( φ ↦ 𝜎1:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝑛·0·3 := 𝑛·1·6.if( then ↦ ⊥ )+ 𝑛·0·4 := 𝑛·0·3( else ↦ 1.plus( 2 ) )+ 𝔼(L_fork):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.bool( φ ↦ 𝜎1:λ )+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.ρ)+ 𝑛1·2 := ⊥ # 𝕄(ξ.then)+ 𝕄(Φ.a🌵4):+ 𝑛·2·2 := 1+ 𝑛·2·3 := 𝑛·2·2.plus( x ↦ 2 )+ 𝕄(Φ.a🌵4.x):+ 𝑛·2·4 := Φ.bytes( φ ↦ 40-00-00-00-00-00-00-00:Δ )+ 𝑛·2·5 := Φ.number( φ ↦ 𝑛·2·4 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵5):+ 𝕄(Φ.a🌵5):+ 𝑛·3·1 := 1+ 𝑛·3·2 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝛿·3·1 := 3F-F0-00-00-00-00-00-00 # 1.0+ 𝛿1·3 := 𝛿·3·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵6):+ 𝕄(Φ.a🌵6):+ 𝑛·3·3 := Φ.number( φ ↦ 𝑛·2·4 )+ 𝑛·3·4 := Φ.bytes( φ ↦ 40-00-00-00-00-00-00-00:Δ )+ 𝛿·3·2 := 40-00-00-00-00-00-00-00 # 2.0+ 𝛿2·3 := 𝛿·3·2 # 𝔻(ξ.x)+ 𝑛·3·5 := Φ.number( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·3·5):+ 𝑛·3·6 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·3·7 := 𝑛·3·6 # 𝕄(𝑛·3·5)+ 𝑛2·2 := 𝑛·3·7 # 𝕄(ξ.else)+ 𝑛3·2 := ⊥ # 𝑛1+ 𝑛4·2 := 𝑛2·2 # 𝑛2+ terminate(𝔻(𝜎1:λ), left) # 𝑛3+ 𝑛5·2 := 𝑛4·2 # [𝑛3, 𝑛4]+ 𝑛·2·6 := 𝑛5·2 # 𝑛+ 𝑛·2·7 := 𝑛5·2 # 𝕄(𝑛·2·6)+ 𝑛·0·5 := 𝑛·3·6.plus( x ↦ 6 )+ 𝕄(Φ.φ.x):+ 𝑛·0·6 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝑛·0·7 := Φ.number( φ ↦ 𝑛·0·6 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵7):+ 𝕄(Φ.a🌵7):+ 𝑛·4·1 := Φ.number( φ ↦ 𝜎2:λ )+ 𝛿1·4 := 𝔻(𝜎2:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵8):+ 𝕄(Φ.a🌵8):+ 𝑛·4·2 := Φ.number( φ ↦ 𝑛·0·6 )+ 𝑛·4·3 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝛿·4·1 := 40-18-00-00-00-00-00-00 # 6.0+ 𝛿2·4 := 𝛿·4·1 # 𝔻(ξ.x)+ 𝑛·4·4 := Φ.number( φ ↦ 𝜎3:λ ) # 𝑛+ 𝕄(𝑛·4·4):+ 𝑛·4·5 := Φ.number( φ ↦ 𝜎3:λ )+ 𝑛·4·6 := 𝑛·4·5 # 𝕄(𝑛·4·4)
@@ -0,0 +1,42 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The very fork that does not join, with a 'rewrite' block in front of the+# join: the second branch carries an 'x' the first does not, and a rule of the+# entry drops it, so the two have one shape once they are compared and the+# fork answers their join. Each 'rewrite' line binds a meta of its own, which+# the protocol writes like a 'symbolize' one, commented with the meta it was+# rewritten from; a branch no rule matches is bound as it was (#1409).+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ rewrite:+ 𝑛3:+ of: 𝑛1+ rules: &shape+ - name: no-x+ pattern: ⟦ !B1, x ↦ ⟦⟧, !B2 ⟧+ result: ⟦ !B1, !B2 ⟧+ 𝑛4:+ of: 𝑛2+ rules: *shape+ join:+ 𝑛5: [𝑛3, 𝑛4]+ 𝑛: 𝑛5+location: 'Q.y'+input: '⟦ y ↦ ⟦ a ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎1 ⟧ ⟧, b ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎2 ⟧, x ↦ ⟦⟧ ⟧, λ ⤍ L_fork ⟧.φ ⟧'+result: '𝜎3:λ'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_fork):+ 𝑛1·1 := 𝜎1:λ:φ # 𝕄(ξ.a)+ 𝑛2·1 := ⟦ φ ↦ 𝜎2:λ, x ↦ ⟦⟧ ⟧ # 𝕄(ξ.b)+ 𝑛3·1 := 𝑛1·1 # 𝑛1+ 𝑛4·1 := 𝜎2:λ:φ # 𝑛2+ 𝔻(𝜎3:λ) ∈ { 𝔻(𝜎1:λ), 𝔻(𝜎2:λ) }+ 𝑛5·1 := 𝜎3:λ:φ # [𝑛3, 𝑛4]+ 𝑛·1·1 := 𝑛5·1 # 𝑛+ 𝑛·1·2 := 𝑛5·1 # 𝕄(𝑛·1·1)
@@ -0,0 +1,163 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The program '!(x > 0)' of eo-runtime: 'not' is 'if. false true', so one+# branch of the fork is the literal 'false' and the other the literal 'true',+# while what the fork answers is a bool carrying a symbol. The two spellings+# are one value, and the 'rewrite' block of the fork says so, turning either+# literal into the shape an answer has with the datum it stands for, which+# 'symbolize' then stands into a known symbol, so the join pairs them and the+# root dataizes the fork of 'not' over the fork of '>' (#1409).+symbolic: |+ - λ: L_number_gt+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.b+ 𝑛: ⟦ φ ↦ Φ.bool( if ↦ ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ ⟦ λ ⤍ 𝜎 ⟧ ⟧ ) ⟧+ - λ: L_entry+ dataize:+ 𝛿1: $.n+ morph:+ 𝑛1: $.v.φ+ 𝑛: Φ.l🌵.root( 𝑛1 )+ - λ: L_root+ dataize:+ 𝛿1: $.v+ 𝑛: ⟦ ⟧+ - λ: L_fork+ dataize:+ 𝛿1: $.φ+ morph:+ 𝑛1: $.left+ 𝑛2: $.right+ rewrite:+ 𝑛3:+ of: 𝑛1+ rules: &bool+ - name: false-literal+ pattern: ⟦ !B1, φ ↦ Φ.bool( if ↦ ⟦ ρ ↦ ∅, left ↦ ∅, right ↦ ∅, φ ↦ ξ.right ⟧ ), !B2 ⟧+ result: ⟦ φ ↦ Φ.bool( if ↦ ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ ⟦ Δ ⤍ 00- ⟧ ⟧ ) ⟧+ - name: true-literal+ pattern: ⟦ !B1, φ ↦ Φ.bool( if ↦ ⟦ ρ ↦ ∅, left ↦ ∅, right ↦ ∅, φ ↦ ξ.left ⟧ ), !B2 ⟧+ result: ⟦ φ ↦ Φ.bool( if ↦ ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ ⟦ Δ ⤍ FF- ⟧ ⟧ ) ⟧+ - name: bool-without-rho+ pattern: ⟦ !B1, φ ↦ Φ.bool( if ↦ ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ 𝑒1 ⟧ ), !B2 ⟧+ result: ⟦ φ ↦ Φ.bool( if ↦ ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ 𝑒1 ⟧ ) ⟧+ 𝑛4:+ of: 𝑛2+ rules: *bool+ symbolize:+ 𝑛5: 𝑛3+ 𝑛6: 𝑛4+ join:+ 𝑛7: [𝑛5, 𝑛6]+ 𝑛: 𝑛7+location: 'Q.l🌵'+deep: true+partial: true+acyclic: proven+steps: 32+input: |+ ⟦+ number ↦ ⟦ φ ↦ ∅, gt ↦ ⟦ b ↦ ∅, λ ⤍ L_number_gt, ρ ↦ ∅ ⟧ ⟧,+ bytes ↦ ⟦ φ ↦ ∅ ⟧,+ bool ↦ ⟦ if ↦ ∅, φ ↦ ξ.if( left ↦ Φ.bytes( φ ↦ ⟦ Δ ⤍ FF- ⟧ ), right ↦ Φ.bytes( φ ↦ ⟦ Δ ⤍ 00- ⟧ ) ), not ↦ ξ.if( left ↦ Φ.false, right ↦ Φ.true ) ⟧,+ true ↦ ⟦ φ ↦ Φ.bool( if ↦ ⟦ ρ ↦ ∅, left ↦ ∅, right ↦ ∅, φ ↦ ξ.left ⟧ ) ⟧,+ false ↦ ⟦ φ ↦ Φ.bool( if ↦ ⟦ ρ ↦ ∅, left ↦ ∅, right ↦ ∅, φ ↦ ξ.right ⟧ ) ⟧,+ guard ↦ ⟦ x ↦ ∅, φ ↦ ξ.x.gt( b ↦ Φ.number( φ ↦ Φ.bytes( φ ↦ ⟦ Δ ⤍ 00-00-00-00-00-00-00-00 ⟧ ) ) ).not ⟧,+ l🌵 ↦ ⟦ mark ↦ ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧, root ↦ ⟦ v ↦ ∅, λ ⤍ L_root ⟧,+ e1 ↦ Φ.l🌵.mark( n ↦ Φ.number( φ ↦ Φ.bytes( φ ↦ ⟦ Δ ⤍ 3F-F0-00-00-00-00-00-00 ⟧ ) ) )( v ↦ Φ.guard( x ↦ Φ.number( φ ↦ Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎1 ⟧ ) ) ) ) ⟧+ ⟧+protocol: |+ 𝕄(Φ.l🌵):+ 𝕄(Φ.l🌵.e1):+ 𝑛·0·1 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝑛·0·2 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·0·3 := ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧( n ↦ 𝑛·0·2 )+ 𝑛·0·4 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·5 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝑛·0·6 := Φ.guard( x ↦ 𝑛·0·5 )+ 𝑛·0·7 := ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧( n ↦ 𝑛·0·2 )+ 𝑛·0·8 := 𝑛·0·7( v ↦ 𝑛·0·6 )+ 𝔼(L_entry):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·1·2 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 3F-F0-00-00-00-00-00-00 # 1.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.n)+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := Φ.guard( x ↦ 𝑛·0·5 )+ 𝑛·1·4 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝑛·1·5 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝑛·1·6 := 𝑛·1·5.gt( b ↦ 0 )+ 𝔼(L_number_gt):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝑛·2·2 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵3):+ 𝕄(Φ.a🌵3):+ 𝑛·2·3 := 0+ 𝑛·2·4 := Φ.bytes( φ ↦ 00-00-00-00-00-00-00-00:Δ )+ 𝛿·2·1 := 00-00-00-00-00-00-00-00 # 0.0+ 𝛿2·2 := 𝛿·2·1 # 𝔻(ξ.b)+ 𝑛·2·5 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ ⟧ ):φ # 𝑛+ 𝑛·2·6 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ ⟧ ):φ # 𝕄(𝑛·2·5)+ 𝑛·1·7 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎2:λ ⟧ )+ 𝑛·1·8 := ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ 𝜎2:λ ⟧( left ↦ Φ.false )+ 𝑛·1·9 := 𝑛·1·8( right ↦ Φ.true )+ 𝔼(L_fork):+ 𝛿1·3 := 𝔻(𝜎2:λ) # 𝔻(ξ.φ)+ 𝕄(Φ.a🌵5):+ 𝕄(Φ.a🌵5.φ):+ 𝑛·3·1 := Φ.bool( if(left, right) ↦ right:φ )+ 𝑛1·3 := 𝑛·3·1:φ # 𝕄(ξ.left)+ 𝕄(Φ.a🌵6):+ 𝕄(Φ.a🌵6.φ):+ 𝑛·3·2 := Φ.bool( if(left, right) ↦ left:φ )+ 𝑛2·3 := 𝑛·3·2:φ # 𝕄(ξ.right)+ 𝑛3·3 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 00-:Δ ⟧ ):φ # 𝑛1+ 𝑛4·3 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ FF-:Δ ⟧ ):φ # 𝑛2+ 𝔻(𝜎3:λ) == 00-+ 𝑛5·3 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎3:λ ⟧ ):φ # 𝑛3+ 𝔻(𝜎4:λ) == FF-+ 𝑛6·3 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎4:λ ⟧ ):φ # 𝑛4+ 𝔻(𝜎5:λ) ∈ { 𝔻(𝜎3:λ), 𝔻(𝜎4:λ) }+ 𝑛7·3 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎5:λ ⟧ ):φ # [𝑛5, 𝑛6]+ 𝑛·3·3 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎5:λ ⟧ ):φ # 𝑛+ 𝑛·3·4 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎5:λ ⟧ ):φ # 𝕄(𝑛·3·3)+ 𝑛1·1 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎5:λ ⟧ ):φ # 𝕄(ξ.v.φ)+ 𝑛·1·10 := Φ.l🌵.root( Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎5:λ ⟧ ):φ ) # 𝑛+ 𝕄(𝑛·1·10):+ 𝑛·1·11 := ⟦ v ↦ ∅, λ ⤍ L_root ⟧( v ↦ Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎5:λ ⟧ ):φ )+ 𝑛·1·12 := 𝑛·1·11 # 𝕄(𝑛·1·10)+ 𝔼(L_root):+ 𝔻(Φ.a🌵7):+ 𝕄(Φ.a🌵7):+ 𝑛·4·1 := Φ.bool( if(left, right) ↦ ⟦ λ ⤍ L_fork, φ ↦ 𝜎5:λ ⟧ )+ 𝑛·4·2 := ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ 𝜎5:λ ⟧( left ↦ Φ.bytes( φ ↦ FF-:Δ ) )+ 𝑛·4·3 := 𝑛·4·2( right ↦ Φ.bytes( φ ↦ 00-:Δ ) )+ 𝔼(L_fork):+ 𝛿1·5 := 𝔻(𝜎5:λ) # 𝔻(ξ.φ)+ 𝕄(Φ.a🌵9):+ 𝑛·5·1 := Φ.bytes( φ ↦ FF-:Δ )+ 𝑛1·5 := 𝑛·5·1 # 𝕄(ξ.left)+ 𝕄(Φ.a🌵10):+ 𝑛·5·2 := Φ.bytes( φ ↦ 00-:Δ )+ 𝑛2·5 := 𝑛·5·2 # 𝕄(ξ.right)+ 𝑛3·5 := 𝑛·5·1 # 𝑛1+ 𝑛4·5 := 𝑛·5·2 # 𝑛2+ 𝔻(𝜎6:λ) == FF-+ 𝑛5·5 := 𝜎6:λ:φ # 𝑛3+ 𝔻(𝜎7:λ) == 00-+ 𝑛6·5 := 𝜎7:λ:φ # 𝑛4+ 𝔻(𝜎8:λ) ∈ { 𝔻(𝜎6:λ), 𝔻(𝜎7:λ) }+ 𝑛7·5 := 𝜎8:λ:φ # [𝑛5, 𝑛6]+ 𝑛·5·3 := 𝑛7·5 # 𝑛+ 𝑛·5·4 := 𝑛7·5 # 𝕄(𝑛·5·3)+ 𝛿1·4 := 𝔻(𝜎8:λ) # 𝔻(ξ.v)+ 𝑛·4·4 := ⟦⟧ # 𝑛+ 𝑛·4·5 := ⟦⟧ # 𝕄(𝑛·4·4)
@@ -0,0 +1,146 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The same fork as the pack beside this one, answering the join of its two+# branches instead of the first of them, with one more firing standing after+# it: the branch point stays in the program, since the 'plus( 6 )' below the+# fork reads the symbol the two branches were joined into and not the value of+# either. The line saying what that symbol stands for is what ties it to the+# two, and the firing of a branch stands one level deeper, under the fork that+# asked for it.+symbolic: |+ - λ: L_number_gt+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.bool( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_fork+ dataize:+ 𝛿1: $.ρ+ morph:+ 𝑛1: $.then+ 𝑛2: $.else+ symbolize:+ 𝑛3: 𝑛1+ 𝑛4: 𝑛2+ join:+ 𝑛5: [𝑛3, 𝑛4]+ 𝑛: 𝑛5+location: 'Q.@'+deep: true+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ bool(φ) ↦ ⟦ if ↦ ⟦ ρ ↦ ∅, then ↦ ∅, else ↦ ∅, λ ⤍ L_fork ⟧ ⟧,+ number(φ) ↦ ⟦+ gt(ρ, x) ↦ ⟦ λ ⤍ L_number_gt ⟧,+ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ @ ↦ 5.gt( 0 ).if( 1.plus( 2 ), 3.plus( 4 ) ).plus( 6 ) ⟧+result: |-+ ⟦ φ ↦ 𝜎5:λ, gt(x) ↦ L_number_gt:λ, plus(x) ↦ L_number_plus:λ ⟧+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := 5+ 𝑛·0·2 := 𝑛·0·1.gt( x ↦ 0 )+ 𝔼(L_number_gt):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := 5+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := 0+ 𝑛·1·4 := Φ.bytes( φ ↦ 00-00-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 00-00-00-00-00-00-00-00 # 0.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.bool( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.bool( φ ↦ 𝜎1:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝑛·0·3 := 𝑛·1·6.if( then ↦ 1.plus( 2 ) )+ 𝑛·0·4 := 𝑛·0·3( else ↦ 3.plus( 4 ) )+ 𝔼(L_fork):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.bool( φ ↦ 𝜎1:λ )+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.ρ)+ 𝕄(Φ.a🌵3):+ 𝑛·2·2 := 1+ 𝑛·2·3 := 𝑛·2·2.plus( x ↦ 2 )+ 𝕄(Φ.a🌵3.x):+ 𝑛·2·4 := Φ.bytes( φ ↦ 40-00-00-00-00-00-00-00:Δ )+ 𝑛·2·5 := Φ.number( φ ↦ 𝑛·2·4 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵4):+ 𝕄(Φ.a🌵4):+ 𝑛·3·1 := 1+ 𝑛·3·2 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝛿·3·1 := 3F-F0-00-00-00-00-00-00 # 1.0+ 𝛿1·3 := 𝛿·3·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵5):+ 𝕄(Φ.a🌵5):+ 𝑛·3·3 := Φ.number( φ ↦ 𝑛·2·4 )+ 𝑛·3·4 := Φ.bytes( φ ↦ 40-00-00-00-00-00-00-00:Δ )+ 𝛿·3·2 := 40-00-00-00-00-00-00-00 # 2.0+ 𝛿2·3 := 𝛿·3·2 # 𝔻(ξ.x)+ 𝑛·3·5 := Φ.number( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·3·5):+ 𝑛·3·6 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·3·7 := 𝑛·3·6 # 𝕄(𝑛·3·5)+ 𝑛1·2 := 𝑛·3·7 # 𝕄(ξ.then)+ 𝕄(Φ.a🌵6):+ 𝑛·2·6 := 3+ 𝑛·2·7 := 𝑛·2·6.plus( x ↦ 4 )+ 𝕄(Φ.a🌵6.x):+ 𝑛·2·8 := Φ.bytes( φ ↦ 40-10-00-00-00-00-00-00:Δ )+ 𝑛·2·9 := Φ.number( φ ↦ 𝑛·2·8 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵7):+ 𝕄(Φ.a🌵7):+ 𝑛·4·1 := 3+ 𝑛·4·2 := Φ.bytes( φ ↦ 40-08-00-00-00-00-00-00:Δ )+ 𝛿·4·1 := 40-08-00-00-00-00-00-00 # 3.0+ 𝛿1·4 := 𝛿·4·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵8):+ 𝕄(Φ.a🌵8):+ 𝑛·4·3 := Φ.number( φ ↦ 𝑛·2·8 )+ 𝑛·4·4 := Φ.bytes( φ ↦ 40-10-00-00-00-00-00-00:Δ )+ 𝛿·4·2 := 40-10-00-00-00-00-00-00 # 4.0+ 𝛿2·4 := 𝛿·4·2 # 𝔻(ξ.x)+ 𝑛·4·5 := Φ.number( φ ↦ 𝜎3:λ ) # 𝑛+ 𝕄(𝑛·4·5):+ 𝑛·4·6 := Φ.number( φ ↦ 𝜎3:λ )+ 𝑛·4·7 := 𝑛·4·6 # 𝕄(𝑛·4·5)+ 𝑛2·2 := 𝑛·4·7 # 𝕄(ξ.else)+ 𝑛3·2 := 𝑛1·2 # 𝑛1+ 𝑛4·2 := 𝑛2·2 # 𝑛2+ 𝔻(𝜎4:λ) ∈ { 𝔻(𝜎2:λ), 𝔻(𝜎3:λ) }+ 𝑛5·2 := ⟦ φ ↦ 𝜎4:λ, gt(x) ↦ L_number_gt:λ, plus(x) ↦ L_number_plus:λ ⟧ # [𝑛3, 𝑛4]+ 𝑛·2·10 := 𝑛5·2 # 𝑛+ 𝑛·2·11 := 𝑛5·2 # 𝕄(𝑛·2·10)+ 𝑛·0·5 := Φ.number( φ ↦ 𝜎4:λ ).plus( x ↦ 6 )+ 𝕄(Φ.φ.x):+ 𝑛·0·6 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝑛·0·7 := Φ.number( φ ↦ 𝑛·0·6 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵9):+ 𝕄(Φ.a🌵9):+ 𝑛·5·1 := Φ.number( φ ↦ 𝜎4:λ )+ 𝛿1·5 := 𝔻(𝜎4:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵10):+ 𝕄(Φ.a🌵10):+ 𝑛·5·2 := Φ.number( φ ↦ 𝑛·0·6 )+ 𝑛·5·3 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝛿·5·1 := 40-18-00-00-00-00-00-00 # 6.0+ 𝛿2·5 := 𝛿·5·1 # 𝔻(ξ.x)+ 𝑛·5·4 := Φ.number( φ ↦ 𝜎5:λ ) # 𝑛+ 𝕄(𝑛·5·4):+ 𝑛·5·5 := Φ.number( φ ↦ 𝜎5:λ )+ 𝑛·5·6 := 𝑛·5·5 # 𝕄(𝑛·5·4)
@@ -0,0 +1,32 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A fork answers neither of its branches: nobody has picked between the two, so+# handing one of them through would say that the branch point is not there at+# all. What it answers with is the join of the two — the shape both of them+# have, with a fresh symbol wherever they carry two different unknowns — and+# what that fresh symbol stands for stands on a line of its own, since a 𝜎 is+# the name of a λ function and nothing is assigned to it. The branches differ+# under φ, that being where the value of a branch is reached and so the only+# place the join looks at all (#1293).+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ join:+ 𝑛3: [𝑛1, 𝑛2]+ 𝑛: 𝑛3+location: 'Q.y'+input: '⟦ y ↦ ⟦ a ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎1 ⟧ ⟧, b ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎2 ⟧ ⟧, λ ⤍ L_fork ⟧.φ ⟧'+result: '𝜎3:λ'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_fork):+ 𝑛1·1 := 𝜎1:λ:φ # 𝕄(ξ.a)+ 𝑛2·1 := 𝜎2:λ:φ # 𝕄(ξ.b)+ 𝔻(𝜎3:λ) ∈ { 𝔻(𝜎1:λ), 𝔻(𝜎2:λ) }+ 𝑛3·1 := 𝜎3:λ:φ # [𝑛1, 𝑛2]+ 𝑛·1·1 := 𝑛3·1 # 𝑛+ 𝑛·1·2 := 𝑛3·1 # 𝕄(𝑛·1·1)
@@ -0,0 +1,27 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# Two branches nothing tells apart are the answer themselves: there is nothing+# to pick between them, so the join mints no symbol at all and the firing+# answers the very term both of them are. A fork is a branch point in the+# program and not necessarily one in the value it stands for.+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ join:+ 𝑛3: [𝑛1, 𝑛2]+ 𝑛: 𝑛3+location: 'Q.y'+input: '⟦ y ↦ ⟦ a ↦ ⟦ l ↦ ⟦ λ ⤍ 𝜎1 ⟧ ⟧, b ↦ ⟦ l ↦ ⟦ λ ⤍ 𝜎1 ⟧ ⟧, λ ⤍ L_fork ⟧.l ⟧'+result: '𝜎1:λ'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_fork):+ 𝑛1·1 := 𝜎1:λ:l # 𝕄(ξ.a)+ 𝑛2·1 := 𝜎1:λ:l # 𝕄(ξ.b)+ 𝑛3·1 := 𝜎1:λ:l # [𝑛1, 𝑛2]+ 𝑛·1·1 := 𝜎1:λ:l # 𝑛+ 𝑛·1·2 := 𝜎1:λ:l # 𝕄(𝑛·1·1)
@@ -0,0 +1,37 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The memo of '--acyclic=plausible' keeps a cut the way it keeps an answer.+# The firing under 'x' brings its operand down through 𝔻, which goes round+# 'cyc' until the mode cuts it, so the firing never answers; 'y' spells the+# very same formation, and before #1480 its firing walked all the way down to+# the same cut again, since only an answer was kept. Now the second firing+# takes the cut the first one met: it is written at its own site with the+# formation the cut carried, and nothing under it is reduced.+symbolic: |+ - λ: L_outer+ dataize:+ 𝛿1: ξ.arg+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+deep: true+acyclic: plausible+steps: 64+input: >+ ⟦ cyc ↦ ⟦ x ↦ ∅, φ ↦ Φ.cyc( ξ.x ) ⟧,+ x ↦ ⟦ arg ↦ Φ.cyc( ⟦⟧ ), λ ⤍ L_outer ⟧,+ y ↦ ⟦ arg ↦ Φ.cyc( ⟦⟧ ), λ ⤍ L_outer ⟧ ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.x):+ 𝕄(Φ.x.arg):+ 𝑛·0·1 := Φ.cyc( x ↦ ⟦⟧ )+ 𝔼(L_outer):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.cyc( x ↦ ⟦⟧ )+ 𝑛·1·2 := Φ.cyc( x ↦ ⟦⟧ )+ looped(𝑛·1·2) # plausible+ 𝕄(Φ.y):+ 𝔼(L_outer):+ looped(𝑛·1·2) # 𝕄(Φ.y), plausible
@@ -0,0 +1,33 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The memo of '--acyclic=plausible' keeps a stuck firing the way it keeps a+# cut. The firing under 'x' brings its operand down through 𝔻, which gets+# stuck on 'L_none', so the firing never answers; 'y' spells the very same+# formation, and before #1493 its firing reduced its operand and got stuck on+# 'L_none' again, since a stuck firing kept nothing. Now the second firing+# takes the failure the first one met: it is written at its own site and+# nothing under it is reduced.+symbolic: |+ - λ: L_outer+ dataize:+ 𝛿1: ξ.arg+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+deep: true+partial: true+acyclic: plausible+steps: 64+input: >+ ⟦ x ↦ ⟦ arg ↦ ⟦ λ ⤍ L_none ⟧, λ ⤍ L_outer ⟧,+ y ↦ ⟦ arg ↦ ⟦ λ ⤍ L_none ⟧, λ ⤍ L_outer ⟧ ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.x):+ 𝔼(L_outer):+ 𝔻(Φ.a🌵0):+ unanswered(L_none) # 𝔻(L_none:λ)+ stuck(L_none)+ 𝕄(Φ.y):+ 𝔼(L_outer):+ stall(L_none)
@@ -0,0 +1,19 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# An entry answering a λ function no other entry answers: the firing happens,+# and the run then parks on the answer instead of failing on it. What fired+# before the run got stuck stays in the protocol.+symbolic: |+ - λ: L_answers+ 𝑛: ⟦ λ ⤍ L_none ⟧+location: 'Q.x'+partial: true+input: '⟦ x ↦ ⟦ λ ⤍ L_answers ⟧.foo ⟧'+result: 'L_none:λ.foo'+protocol: |+ 𝕄(Φ.x):+ 𝔼(L_answers):+ 𝑛·1·1 := L_none:λ # 𝑛+ 𝑛·1·2 := L_none:λ # 𝕄(𝑛·1·1)+ unanswered(L_none) # 𝕄(L_none:λ)
@@ -0,0 +1,64 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The '--deep' walk stands its answers in the place of what it computed, inside+# the bindings of the object it walks, and makes no new object by doing so+# (#1757). The operand of 'L_entry' is the object 'Φ.dbl' made, named 𝑛·1·1 by+# its 'applied' line, and the walk computes its 'φ' and its 'v' before 𝕄 hands+# it back. It is still 𝑛·1·1 then: in the line binding the operand, in the term+# the entry wrote, in the argument 'root' was applied to, and in the formation+# 𝔻 gets into when 'L_root' brings that argument down.+symbolic: |+ - λ: L_entry+ morph:+ 𝑛1: $.x+ 𝑛: Φ.root( v ↦ 𝑛1 )+ - λ: L_root+ dataize:+ 𝛿1: $.v+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+ - λ: L_twice+ dataize:+ 𝛿1: $.ρ+ 𝑛: Φ.num( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.y'+deep: true+input: >+ ⟦ num ↦ ⟦ φ ↦ ∅, twice ↦ ⟦ ρ ↦ ∅, λ ⤍ L_twice ⟧ ⟧,+ dbl ↦ ⟦ v ↦ ∅, φ ↦ ξ.v.twice ⟧,+ root(v) ↦ ⟦ λ ⤍ L_root ⟧,+ y ↦ ⟦ λ ⤍ L_entry, x ↦ Φ.dbl( v ↦ Φ.num( φ ↦ ⟦ Δ ⤍ 2A- ⟧ ) ) ⟧ ⟧+result: '𝜎2:λ'+protocol: |+ 𝕄(Φ.y):+ 𝕄(Φ.y.x):+ 𝑛·0·1 := Φ.num( φ ↦ 2A-:Δ )+ 𝑛·0·2 := Φ.dbl( v ↦ 𝑛·0·1 )+ 𝔼(L_entry):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.dbl( v ↦ 𝑛·0·1 )+ 𝕄(Φ.a🌵0.v):+ 𝑛·1·2 := Φ.num( φ ↦ 2A-:Δ )+ 𝕄(Φ.a🌵0.φ):+ 𝑛·1·3 := Φ.num( φ ↦ 2A-:Δ )+ 𝑛·1·4 := Φ.num( φ ↦ 2A-:Δ )+ 𝔼(L_twice):+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·2·1 := Φ.num( φ ↦ 2A-:Δ )+ 𝛿·2·1 := 2A-+ 𝛿1·2 := 𝛿·2·1 # 𝔻(ξ.ρ)+ 𝑛·2·2 := Φ.num( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·2·2):+ 𝑛·2·3 := Φ.num( φ ↦ 𝜎1:λ )+ 𝑛·2·4 := 𝑛·2·3 # 𝕄(𝑛·2·2)+ 𝑛1·1 := 𝑛·1·1 # 𝕄(ξ.x)+ 𝑛·1·5 := Φ.root( v ↦ 𝑛·1·1 ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.root( v ↦ 𝑛·1·1 )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝔼(L_root):+ 𝛿1·3 := 𝔻(𝜎1:λ) # 𝔻(ξ.v)+ 𝑛·3·1 := 𝜎2:λ # 𝑛+ 𝑛·3·2 := 𝜎2:λ # 𝕄(𝑛·3·1)
@@ -0,0 +1,23 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# Every pack spells its terms the way '--hide-rho' spells them, since the ρ+# chain is the universe an entry was fired inside and not the answer it gave.+# A pack saying 'hide-rho: false' asks for the other spelling, and then the+# result and every term of the protocol carry the ρ the calculus put there —+# here the parent of the operand 𝕄 was asked to reduce.+symbolic: |+ - λ: L_keep+ morph:+ 𝑛1: $.x+ 𝑛: ⟦ z ↦ 𝑛1 ⟧+location: 'Q.y'+hide-rho: false+input: '⟦ y ↦ ⟦ x ↦ ⟦ λ ⤍ 𝜎1, ρ ↦ ∅ ⟧, λ ⤍ L_keep ⟧.z ⟧'+result: '⟦ λ ⤍ 𝜎1, ρ ↦ ⟦ x(ρ) ↦ 𝜎1:λ ⟧ ⟧'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_keep):+ 𝑛1·1 := ⟦ λ ⤍ 𝜎1, ρ ↦ ⟦ x(ρ) ↦ 𝜎1:λ ⟧ ⟧ # 𝕄(ξ.x)+ 𝑛·1·1 := ⟦ λ ⤍ 𝜎1, ρ ↦ ⟦ x(ρ) ↦ 𝜎1:λ ⟧ ⟧:z # 𝑛+ 𝑛·1·2 := ⟦ λ ⤍ 𝜎1, ρ ↦ ⟦ x(ρ) ↦ 𝜎1:λ ⟧ ⟧:z # 𝕄(𝑛·1·1)
@@ -0,0 +1,78 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The same method nobody dispatched, in a copy of an object that declares no+# ρ, the way eo-runtime spells 'text': 'skip' drops the ρ the dispatch hands+# the copy, so the copy has no ρ of its own, yet 'length' still declares one+# and still waits for its receiver. The deep walk hands it back as it was+# written instead of firing 'L_dataized' on a ⊥ it stands on (#1414).+symbolic: |+ - λ: L_dataized+ dataize:+ 𝛿1: $.target+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_entry+ dataize:+ 𝛿1: $.n+ morph:+ 𝑛1: $.v.φ+ 𝑛: Φ.l🌵.root( 𝑛1 )+ - λ: L_root+ dataize:+ 𝛿1: $.v+ 𝑛: ⟦ ⟧+location: 'Q.l🌵'+deep: true+partial: true+acyclic: proven+steps: 32+input: |+ ⟦+ number ↦ ⟦ φ ↦ ∅ ⟧,+ bytes ↦ ⟦ φ ↦ ∅, as-bytes ↦ ⟦ φ ↦ ξ.ρ, ρ ↦ ∅ ⟧ ⟧,+ dataized ↦ ⟦ target ↦ ∅, λ ⤍ L_dataized ⟧,+ text ↦ ⟦ φ ↦ ∅, length ↦ ⟦ φ ↦ Φ.dataized( target ↦ ξ.ρ.φ ).as-bytes, ρ ↦ ∅ ⟧ ⟧,+ holder ↦ ⟦ buf ↦ ∅, φ ↦ ξ.buf ⟧,+ l🌵 ↦ ⟦+ mark ↦ ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧,+ root ↦ ⟦ v ↦ ∅, λ ⤍ L_root ⟧,+ e1 ↦ Φ.l🌵.mark( n ↦ Φ.number( φ ↦ Φ.bytes( φ ↦ ⟦ Δ ⤍ 3F-F0-00-00-00-00-00-00 ⟧ ) ) )( v ↦ Φ.holder( buf ↦ Φ.text( φ ↦ Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎1 ⟧ ) ) ) )+ ⟧+ ⟧+protocol: |+ 𝕄(Φ.l🌵):+ 𝕄(Φ.l🌵.e1):+ 𝑛·0·1 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝑛·0·2 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·0·3 := ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧( n ↦ 𝑛·0·2 )+ 𝑛·0·4 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·5 := Φ.text( φ ↦ 𝑛·0·4 )+ 𝑛·0·6 := Φ.holder( buf ↦ 𝑛·0·5 )+ 𝑛·0·7 := ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧( n ↦ 𝑛·0·2 )+ 𝑛·0·8 := 𝑛·0·7( v ↦ 𝑛·0·6 )+ 𝔼(L_entry):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·1·2 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 3F-F0-00-00-00-00-00-00 # 1.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.n)+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := Φ.holder( buf ↦ 𝑛·0·5 )+ 𝑛·1·4 := Φ.text( φ ↦ 𝑛·0·4 )+ 𝑛·1·5 := Φ.text( φ ↦ 𝑛·0·4 )+ 𝕄(Φ.a🌵1.φ):+ 𝑛·1·6 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛1·1 := 𝑛·1·5 # 𝕄(ξ.v.φ)+ 𝑛·1·7 := Φ.l🌵.root( 𝑛·1·5 ) # 𝑛+ 𝕄(𝑛·1·7):+ 𝑛·1·8 := ⟦ v ↦ ∅, λ ⤍ L_root ⟧( v ↦ 𝑛·1·5 )+ 𝑛·1·9 := 𝑛·1·8 # 𝕄(𝑛·1·7)+ 𝔼(L_root):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.v)+ 𝑛·2·2 := ⟦⟧ # 𝑛+ 𝑛·2·3 := ⟦⟧ # 𝕄(𝑛·2·2)
@@ -0,0 +1,78 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A method nobody dispatched is a formation whose ρ is still void: 'length' of+# the copy of 'text' the entry of 'L_entry' morphs waits for a dispatch to bind+# its ρ. The deep walk hands it back as it was written instead of entering it,+# since the entry of 'L_dataized' inside it would dataize 'ξ.ρ.φ', which stands+# for ⊥, and that ⊥ would end the whole run even under '--partial' (#1397).+symbolic: |+ - λ: L_dataized+ dataize:+ 𝛿1: $.target+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_entry+ dataize:+ 𝛿1: $.n+ morph:+ 𝑛1: $.v.φ+ 𝑛: Φ.l🌵.root( 𝑛1 )+ - λ: L_root+ dataize:+ 𝛿1: $.v+ 𝑛: ⟦ ⟧+location: 'Q.l🌵'+deep: true+partial: true+acyclic: proven+steps: 32+input: |+ ⟦+ number ↦ ⟦ φ ↦ ∅ ⟧,+ bytes ↦ ⟦ φ ↦ ∅, as-bytes ↦ ⟦ φ ↦ ξ.ρ, ρ ↦ ∅ ⟧ ⟧,+ dataized ↦ ⟦ target ↦ ∅, λ ⤍ L_dataized ⟧,+ text ↦ ⟦ φ ↦ ∅, length ↦ ⟦ φ ↦ Φ.dataized( target ↦ ξ.ρ.φ ).as-bytes, ρ ↦ ∅ ⟧, ρ ↦ ∅ ⟧,+ holder ↦ ⟦ buf ↦ ∅, φ ↦ ξ.buf ⟧,+ l🌵 ↦ ⟦+ mark ↦ ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧,+ root ↦ ⟦ v ↦ ∅, λ ⤍ L_root ⟧,+ e1 ↦ Φ.l🌵.mark( n ↦ Φ.number( φ ↦ Φ.bytes( φ ↦ ⟦ Δ ⤍ 3F-F0-00-00-00-00-00-00 ⟧ ) ) )( v ↦ Φ.holder( buf ↦ Φ.text( φ ↦ Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎1 ⟧ ) ) ) )+ ⟧+ ⟧+protocol: |+ 𝕄(Φ.l🌵):+ 𝕄(Φ.l🌵.e1):+ 𝑛·0·1 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝑛·0·2 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·0·3 := ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧( n ↦ 𝑛·0·2 )+ 𝑛·0·4 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·5 := Φ.text( φ ↦ 𝑛·0·4 )+ 𝑛·0·6 := Φ.holder( buf ↦ 𝑛·0·5 )+ 𝑛·0·7 := ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧( n ↦ 𝑛·0·2 )+ 𝑛·0·8 := 𝑛·0·7( v ↦ 𝑛·0·6 )+ 𝔼(L_entry):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·1·2 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 3F-F0-00-00-00-00-00-00 # 1.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.n)+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := Φ.holder( buf ↦ 𝑛·0·5 )+ 𝑛·1·4 := Φ.text( φ ↦ 𝑛·0·4 )+ 𝑛·1·5 := Φ.text( φ ↦ 𝑛·0·4 )+ 𝕄(Φ.a🌵1.φ):+ 𝑛·1·6 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛1·1 := 𝑛·1·5 # 𝕄(ξ.v.φ)+ 𝑛·1·7 := Φ.l🌵.root( 𝑛·1·5 ) # 𝑛+ 𝕄(𝑛·1·7):+ 𝑛·1·8 := ⟦ v ↦ ∅, λ ⤍ L_root ⟧( v ↦ 𝑛·1·5 )+ 𝑛·1·9 := 𝑛·1·8 # 𝕄(𝑛·1·7)+ 𝔼(L_root):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.v)+ 𝑛·2·2 := ⟦⟧ # 𝑛+ 𝑛·2·3 := ⟦⟧ # 𝕄(𝑛·2·2)
@@ -0,0 +1,93 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A method nobody applied is an abstract formation, one holding a void of its+# own: 'at' of the copy of 'text' the entry of 'L_entry' morphs waits for 'i'.+# The deep walk hands it back as it was written instead of entering it, since+# its body is parametric: the entry of 'L_dataized' inside it would dataize+# 'ξ.i', which stands for nothing, and the ⊥ it reaches would end the whole run+# even under '--partial' (#1393).+symbolic: |+ - λ: L_number_gt+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.b+ 𝑛: Φ.bool( if ↦ ⟦ λ ⤍ L_fork, left ↦ ∅, right ↦ ∅, φ ↦ ⟦ λ ⤍ 𝜎 ⟧ ⟧ )+ - λ: L_dataized+ dataize:+ 𝛿1: $.target+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_entry+ dataize:+ 𝛿1: $.n+ morph:+ 𝑛1: $.v.φ+ 𝑛: Φ.l🌵.root( 𝑛1 )+ - λ: L_root+ dataize:+ 𝛿1: $.v+ 𝑛: ⟦ ⟧+location: 'Q.l🌵'+deep: true+partial: true+acyclic: proven+steps: 32+input: |+ ⟦+ number ↦ ⟦ φ ↦ ∅, gt ↦ ⟦ ρ ↦ ∅, b ↦ ∅, λ ⤍ L_number_gt ⟧ ⟧,+ bytes ↦ ⟦ φ ↦ ∅ ⟧,+ bool ↦ ⟦ if ↦ ∅ ⟧,+ dataized ↦ ⟦ target ↦ ∅, λ ⤍ L_dataized ⟧,+ text ↦ ⟦+ φ ↦ ∅,+ at ↦ ⟦+ i ↦ ∅,+ φ ↦ Φ.number( φ ↦ Φ.bytes( φ ↦ ⟦ Δ ⤍ 00-00-00-00-00-00-00-00 ⟧ ) ).gt( b ↦ Φ.dataized( target ↦ ξ.i ) )+ ⟧+ ⟧,+ holder ↦ ⟦ buf ↦ ∅, φ ↦ ξ.buf ⟧,+ l🌵 ↦ ⟦+ mark ↦ ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧,+ root ↦ ⟦ v ↦ ∅, λ ⤍ L_root ⟧,+ e1 ↦ Φ.l🌵.mark(+ n ↦ Φ.number( φ ↦ Φ.bytes( φ ↦ ⟦ Δ ⤍ 3F-F0-00-00-00-00-00-00 ⟧ ) )+ )( v ↦ Φ.holder( buf ↦ Φ.text( φ ↦ Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎1 ⟧ ) ) ) )+ ⟧+ ⟧+protocol: |+ 𝕄(Φ.l🌵):+ 𝕄(Φ.l🌵.e1):+ 𝑛·0·1 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝑛·0·2 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·0·3 := ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧( n ↦ 𝑛·0·2 )+ 𝑛·0·4 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·5 := Φ.text( φ ↦ 𝑛·0·4 )+ 𝑛·0·6 := Φ.holder( buf ↦ 𝑛·0·5 )+ 𝑛·0·7 := ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧( n ↦ 𝑛·0·2 )+ 𝑛·0·8 := 𝑛·0·7( v ↦ 𝑛·0·6 )+ 𝔼(L_entry):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·1·2 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 3F-F0-00-00-00-00-00-00 # 1.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.n)+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := Φ.holder( buf ↦ 𝑛·0·5 )+ 𝑛·1·4 := Φ.text( φ ↦ 𝑛·0·4 )+ 𝑛·1·5 := Φ.text( φ ↦ 𝑛·0·4 )+ 𝕄(Φ.a🌵1.φ):+ 𝑛·1·6 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛1·1 := 𝑛·1·5 # 𝕄(ξ.v.φ)+ 𝑛·1·7 := Φ.l🌵.root( 𝑛·1·5 ) # 𝑛+ 𝕄(𝑛·1·7):+ 𝑛·1·8 := ⟦ v ↦ ∅, λ ⤍ L_root ⟧( v ↦ 𝑛·1·5 )+ 𝑛·1·9 := 𝑛·1·8 # 𝕄(𝑛·1·7)+ 𝔼(L_root):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.v)+ 𝑛·2·2 := ⟦⟧ # 𝑛+ 𝑛·2·3 := ⟦⟧ # 𝕄(𝑛·2·2)
@@ -0,0 +1,45 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# Each branch of a fork reaches the join as the whole formation of its carrier,+# methods included, and a carrier of any size declares methods full of+# literals. Neither stage has any business with them: a term carries the value+# it stands for where its φ chain ends, so the '-1' of a 'neg' nobody has+# called is code and not data, and standing it into an unknown would mint a+# symbol nobody ever reads — dozens of them per fork over a real object model,+# each one a line of the protocol and a fact a reader has to know to skip+# (#1293).+#+# Here both branches carry a literal under φ, which is the value of the branch+# and is stood, and another inside 'neg', which is not and is left alone. The+# two branches differ inside 'neg' as well, and that difference is no fork:+# the join takes the method of the first branch verbatim, mints one symbol for+# the one pair of values that differ, and the answer keeps its methods so the+# program can go on dispatching on it.+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ symbolize:+ 𝑛3: 𝑛1+ 𝑛4: 𝑛2+ join:+ 𝑛5: [𝑛3, 𝑛4]+ 𝑛: 𝑛5+location: 'Q.y'+input: '⟦ y ↦ ⟦ a ↦ ⟦ φ ↦ ⟦ Δ ⤍ 01- ⟧, neg ↦ ⟦ φ ↦ ⟦ Δ ⤍ 0A- ⟧ ⟧ ⟧, b ↦ ⟦ φ ↦ ⟦ Δ ⤍ 02- ⟧, neg ↦ ⟦ φ ↦ ⟦ Δ ⤍ 0B- ⟧ ⟧ ⟧, λ ⤍ L_fork ⟧.φ ⟧'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_fork):+ 𝑛1·1 := ⟦ φ ↦ 01-:Δ, neg ↦ 0A-:Δ:φ ⟧ # 𝕄(ξ.a)+ 𝑛2·1 := ⟦ φ ↦ 02-:Δ, neg ↦ 0B-:Δ:φ ⟧ # 𝕄(ξ.b)+ 𝔻(𝜎1:λ) == 01-+ 𝑛3·1 := ⟦ φ ↦ 𝜎1:λ, neg ↦ 0A-:Δ:φ ⟧ # 𝑛1+ 𝔻(𝜎2:λ) == 02-+ 𝑛4·1 := ⟦ φ ↦ 𝜎2:λ, neg ↦ 0B-:Δ:φ ⟧ # 𝑛2+ 𝔻(𝜎3:λ) ∈ { 𝔻(𝜎1:λ), 𝔻(𝜎2:λ) }+ 𝑛5·1 := ⟦ φ ↦ 𝜎3:λ, neg ↦ 0A-:Δ:φ ⟧ # [𝑛3, 𝑛4]+ 𝑛·1·1 := 𝑛5·1 # 𝑛+ 𝑛·1·2 := 𝑛5·1 # 𝕄(𝑛·1·1)
@@ -0,0 +1,60 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# Two firings down a chain of dispatches: each mints a symbol of its own, and+# the operand of the second is the answer of the first, which the protocol+# names rather than brings down again — every symbol answers the same datum.+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.@'+deep: true+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ number(φ) ↦ ⟦ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ @ ↦ 5.plus( 6 ).plus( 7 ) ⟧+result: '⟦ φ ↦ 𝜎2:λ, plus(x) ↦ L_number_plus:λ ⟧'+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := 5+ 𝑛·0·2 := 𝑛·0·1.plus( x ↦ 6 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := 5+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := 6+ 𝑛·1·4 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 40-18-00-00-00-00-00-00 # 6.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.number( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.number( φ ↦ 𝜎1:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝑛·0·3 := 𝑛·1·6.plus( x ↦ 7 )+ 𝕄(Φ.φ.x):+ 𝑛·0·4 := Φ.bytes( φ ↦ 40-1C-00-00-00-00-00-00:Δ )+ 𝑛·0·5 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.number( φ ↦ 𝜎1:λ )+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵3):+ 𝕄(Φ.a🌵3):+ 𝑛·2·2 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝑛·2·3 := Φ.bytes( φ ↦ 40-1C-00-00-00-00-00-00:Δ )+ 𝛿·2·1 := 40-1C-00-00-00-00-00-00 # 7.0+ 𝛿2·2 := 𝛿·2·1 # 𝔻(ξ.x)+ 𝑛·2·4 := Φ.number( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·2·4):+ 𝑛·2·5 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·2·6 := 𝑛·2·5 # 𝕄(𝑛·2·4)
@@ -0,0 +1,34 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The firing of 'L_inner' mints 𝜎1 for its answer and then gets stuck, since+# nothing answers a dispatch off a symbol, and '--partial' parks its site. The+# protocol keeps what that firing wrote, so 𝜎1 is spelled there already. Before+# #1738 the parked frame handed back the state it started from, the count of+# minted symbols went back with it, and 'L_outer' minted 𝜎1 once more, for+# another value. Now the count never goes back, and 'L_outer' mints 𝜎2.+symbolic: |+ - λ: L_inner+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧.foo+ - λ: L_outer+ morph:+ 𝑛1: $.a+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+location: 'Q.y'+partial: true+input: '⟦ y ↦ ⟦ a ↦ ⟦ λ ⤍ L_inner ⟧.v, λ ⤍ L_outer ⟧.z ⟧'+result: '𝜎2:λ.z'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_outer):+ 𝕄(Φ.a🌵0):+ 𝔼(L_inner):+ 𝑛·2·1 := 𝜎1:λ.foo # 𝑛+ 𝕄(𝑛·2·1):+ unanswered(𝜎1) # 𝕄(𝜎1:λ)+ stuck(𝜎1)+ 𝑛1·1 := L_inner:λ.v # 𝕄(ξ.a)+ 𝑛·1·1 := 𝜎2:λ # 𝑛+ 𝑛·1·2 := 𝜎2:λ # 𝕄(𝑛·1·1)+ unanswered(𝜎2) # 𝕄(𝜎2:λ)
@@ -0,0 +1,43 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The program handed in is the answer an earlier run gave: its receiver is no+# number but the symbol 𝜎1 that run minted. The firing brings it down all the+# same, since a symbol dataizes to a fixed 42, and the protocol names the+# unknown that 42 stood for instead of writing the bytes twice.+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.@'+deep: true+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ number(φ) ↦ ⟦ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ @ ↦ Φ.number( φ ↦ ⟦ λ ⤍ 𝜎1 ⟧ ).plus( 7 ) ⟧+result: '⟦ φ ↦ 𝜎2:λ, plus(x) ↦ L_number_plus:λ ⟧'+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := Φ.number( φ ↦ 𝜎1:λ )+ 𝑛·0·2 := 𝑛·0·1.plus( x ↦ 7 )+ 𝕄(Φ.φ.x):+ 𝑛·0·3 := Φ.bytes( φ ↦ 40-1C-00-00-00-00-00-00:Δ )+ 𝑛·0·4 := Φ.number( φ ↦ 𝑛·0·3 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.number( φ ↦ 𝜎1:λ )+ 𝛿1·1 := 𝔻(𝜎1:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·2 := Φ.number( φ ↦ 𝑛·0·3 )+ 𝑛·1·3 := Φ.bytes( φ ↦ 40-1C-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-1C-00-00-00-00-00-00 # 7.0+ 𝛿2·1 := 𝛿·1·1 # 𝔻(ξ.x)+ 𝑛·1·4 := Φ.number( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·1·4):+ 𝑛·1·5 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·1·6 := 𝑛·1·5 # 𝕄(𝑛·1·4)
@@ -0,0 +1,116 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The memo of '--acyclic=plausible' serves the operands of a firing as much+# as the walk: the two branches of this fork spell one term, so the sum the+# second one starts from is the formation the first one fired, and the+# second branch reaches the normal form the first reached, symbol and all,+# through a firing that reduces nothing and answers what the first one did.+# The branches are met as 'morph' operands of the fork and not as bindings+# the deep walk went over first, since the fork is fired by the dispatch off+# it (#1476).+symbolic: |+ - λ: L_number_gt+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.bool( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_fork+ dataize:+ 𝛿1: $.ρ+ morph:+ 𝑛1: $.then+ 𝑛2: $.else+ 𝑛: 𝑛1+location: 'Q.@'+acyclic: plausible+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ bool(φ) ↦ ⟦ if ↦ ⟦ ρ ↦ ∅, then ↦ ∅, else ↦ ∅, λ ⤍ L_fork ⟧ ⟧,+ number(φ) ↦ ⟦+ gt(ρ, x) ↦ ⟦ λ ⤍ L_number_gt ⟧,+ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ @ ↦ 5.gt( 0 ).if( 1.plus( 2 ).plus( 3 ), 1.plus( 2 ).plus( 3 ) ).plus( 9 ) ⟧+result: '⟦ x ↦ 9, λ ⤍ L_number_plus ⟧'+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := 5+ 𝑛·0·2 := 𝑛·0·1.gt( x ↦ 0 )+ 𝔼(L_number_gt):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := 5+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := 0+ 𝑛·1·4 := Φ.bytes( φ ↦ 00-00-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 00-00-00-00-00-00-00-00 # 0.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.bool( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.bool( φ ↦ 𝜎1:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝑛·0·3 := 𝑛·1·6.if( then ↦ 1.plus( 2 ).plus( 3 ) )+ 𝑛·0·4 := 𝑛·0·3( else ↦ 1.plus( 2 ).plus( 3 ) )+ 𝔼(L_fork):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.bool( φ ↦ 𝜎1:λ )+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.ρ)+ 𝕄(Φ.a🌵3):+ 𝑛·2·2 := 1+ 𝑛·2·3 := 𝑛·2·2.plus( x ↦ 2 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵4):+ 𝕄(Φ.a🌵4):+ 𝑛·3·1 := 1+ 𝑛·3·2 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝛿·3·1 := 3F-F0-00-00-00-00-00-00 # 1.0+ 𝛿1·3 := 𝛿·3·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵5):+ 𝕄(Φ.a🌵5):+ 𝑛·3·3 := 2+ 𝑛·3·4 := Φ.bytes( φ ↦ 40-00-00-00-00-00-00-00:Δ )+ 𝛿·3·2 := 40-00-00-00-00-00-00-00 # 2.0+ 𝛿2·3 := 𝛿·3·2 # 𝔻(ξ.x)+ 𝑛·3·5 := Φ.number( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·3·5):+ 𝑛·3·6 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·3·7 := 𝑛·3·6 # 𝕄(𝑛·3·5)+ 𝑛·2·4 := 𝑛·3·6.plus( x ↦ 3 )+ 𝑛1·2 := 𝑛·2·4 # 𝕄(ξ.then)+ 𝕄(Φ.a🌵6):+ 𝑛·2·5 := Φ.number( φ ↦ 𝑛·3·2 )+ 𝑛·2·6 := 𝑛·2·5.plus( x ↦ 𝑛·3·3 )+ 𝔼(L_number_plus):+ 𝑛·4·1 := 𝑛·3·6 # 𝑛+ 𝑛·4·2 := 𝑛·3·7 # 𝕄(𝑛·4·1)+ 𝑛·2·7 := 𝑛·3·6.plus( x ↦ 3 )+ 𝑛2·2 := 𝑛·2·7 # 𝕄(ξ.else)+ 𝑛·2·8 := 𝑛·2·7 # 𝑛+ 𝑛·2·9 := 𝑛·2·7 # 𝕄(𝑛·2·8)+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵7):+ 𝕄(Φ.a🌵7):+ 𝑛·5·1 := Φ.number( φ ↦ 𝜎2:λ )+ 𝛿1·5 := 𝔻(𝜎2:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵8):+ 𝕄(Φ.a🌵8):+ 𝑛·5·2 := 3+ 𝑛·5·3 := Φ.bytes( φ ↦ 40-08-00-00-00-00-00-00:Δ )+ 𝛿·5·1 := 40-08-00-00-00-00-00-00 # 3.0+ 𝛿2·5 := 𝛿·5·1 # 𝔻(ξ.x)+ 𝑛·5·4 := Φ.number( φ ↦ 𝜎3:λ ) # 𝑛+ 𝕄(𝑛·5·4):+ 𝑛·5·5 := Φ.number( φ ↦ 𝜎3:λ )+ 𝑛·5·6 := 𝑛·5·5 # 𝕄(𝑛·5·4)+ 𝑛·0·5 := 𝑛·5·5.plus( x ↦ 9 )
@@ -0,0 +1,59 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# An operand is brought down by a whole run of 𝔻, so a λ function it fires on+# the way sits one level deeper than the firing waiting for it, and the metas+# of the two are told apart by which firing of the entry each belongs to. The+# judgment each firing is commented with says the same thing from the other+# side: the outer one was fired while 𝕄 reduced the program and the inner one+# by the 𝔻 bringing the operand down, under the binding it was bound to (#1306).+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.@'+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ number(φ) ↦ ⟦ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ @ ↦ 5.plus( 6.plus( 7 ) ).plus( 8 ) ⟧+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := 5+ 𝑛·0·2 := 𝑛·0·1.plus( x ↦ 6.plus( 7 ) )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := 5+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := 6+ 𝑛·1·4 := 𝑛·1·3.plus( x ↦ 7 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := 6+ 𝑛·2·2 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝛿·2·1 := 40-18-00-00-00-00-00-00 # 6.0+ 𝛿1·2 := 𝛿·2·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵3):+ 𝕄(Φ.a🌵3):+ 𝑛·2·3 := 7+ 𝑛·2·4 := Φ.bytes( φ ↦ 40-1C-00-00-00-00-00-00:Δ )+ 𝛿·2·2 := 40-1C-00-00-00-00-00-00 # 7.0+ 𝛿2·2 := 𝛿·2·2 # 𝔻(ξ.x)+ 𝑛·2·5 := Φ.number( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·2·5):+ 𝑛·2·6 := Φ.number( φ ↦ 𝜎1:λ )+ 𝑛·2·7 := 𝑛·2·6 # 𝕄(𝑛·2·5)+ 𝛿2·1 := 𝔻(𝜎1:λ) # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.number( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝑛·0·3 := 𝑛·1·6.plus( x ↦ 8 )
@@ -0,0 +1,70 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A λ binding naming a symbol rather than a name, which is what a value nobody+# worked out looks like: ⟦ λ ⤍ 𝜎1 ⟧. Dispatching an attribute off it asks 𝕄 to+# reduce it, 'ml' fires 𝔼 on the target, and before #1287 𝔼 refused the+# formation outright — a 'userError' nothing catches, so the whole run died on+# the first such term and everything standing after it never ran. 𝔼 now gets+# stuck on the symbol the way it gets stuck on a λ name no entry of the+# '--symbolic' file answers, so '--partial' parks the site: 'a' is left exactly+# as it was written, a taint with no root, and the walk goes on to 'b', which+# fires and computes. The site is written to the protocol as 'unanswered(𝜎1)',+# spelled the way every term carrying that symbol spells it.+#+# The site is recorded twice because the walk passes it twice — once for the+# dispatch 'x.plus' and once for the application 'x.plus( 5 )' around it — which+# is what a λ name nothing answers does on this shape too; nothing about the+# symbol makes it write more than a name would.+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ ) )+location: 'Q.demo'+deep: true+partial: true+input: >+ ⟦ bytes ↦ ⟦ φ ↦ ∅ ⟧,+ number ↦ ⟦ φ ↦ ∅, plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ demo ↦ ⟦+ a ↦ ⟦ λ ⤍ 𝜎1 ⟧.plus( 5 ),+ b ↦ Φ.number( φ ↦ Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎2 ⟧ ) ).plus( 5 ) ⟧ ⟧+result: |-+ ⟦+ a ↦ 𝜎1:λ.plus( 5 ),+ b ↦ ⟦ φ ↦ Φ.bytes( φ ↦ 𝜎3:λ ), plus(x) ↦ L_number_plus:λ ⟧+ ⟧+protocol: |+ 𝕄(Φ.demo):+ 𝕄(Φ.demo.a):+ unanswered(𝜎1) # 𝕄(𝜎1:λ)+ 𝑛·0·1 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝑛·0·2 := Φ.number( φ ↦ 𝑛·0·1 )+ unanswered(𝜎1) # 𝕄(𝜎1:λ)+ 𝕄(Φ.demo.b):+ 𝑛·0·3 := Φ.bytes( φ ↦ 𝜎2:λ )+ 𝑛·0·4 := Φ.number( φ ↦ 𝑛·0·3 )+ 𝑛·0·5 := Φ.number( φ ↦ 𝑛·0·3 )+ 𝑛·0·6 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝑛·0·7 := Φ.number( φ ↦ 𝑛·0·6 )+ 𝑛·0·8 := Φ.number( φ ↦ 𝑛·0·3 )+ 𝑛·0·9 := 𝑛·0·8.plus( x ↦ 𝑛·0·7 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.number( φ ↦ 𝑛·0·3 )+ 𝑛·1·2 := Φ.bytes( φ ↦ 𝜎2:λ )+ 𝛿1·1 := 𝔻(𝜎2:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := Φ.number( φ ↦ 𝑛·0·6 )+ 𝑛·1·4 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿2·1 := 𝛿·1·1 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.number( φ ↦ Φ.bytes( φ ↦ 𝜎3:λ ) ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.number( φ ↦ Φ.bytes( φ ↦ 𝜎3:λ ) )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)
@@ -0,0 +1,31 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A loop met while an operand is being brought down to data, with no frame of 𝕄+# ever handed the same term twice: the body of 'cyc' dispatches 'cyc' again, so+# every round 𝕄 stops at a formation of its own and only 𝔻 — 'box'+# contextualizing that body and 'norm' morphing what comes out — comes back to+# the term it started from. Before #1290 the guard of '--acyclic' was 𝕄's alone+# and this went round until the step budget ran out; now 𝔻 asks it too, and the+# spine around the firing parks with the term it had reached when the firing+# started, exactly as it does for a loop 𝕄 catches.+symbolic: |+ - λ: L_outer+ dataize:+ 𝛿1: ξ.arg+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+location: 'Q.x'+acyclic: proven+steps: 250+input: >+ ⟦ cyc ↦ ⟦ x ↦ ∅, φ ↦ Φ.cyc( ξ.x ) ⟧,+ x ↦ ⟦ arg ↦ Φ.cyc( ⟦⟧ ), λ ⤍ L_outer ⟧.bar ⟧+result: '⟦ arg ↦ Φ.cyc( ⟦⟧ ), λ ⤍ L_outer ⟧.bar'+protocol: |+ 𝕄(Φ.x):+ 𝔼(L_outer):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.cyc( x ↦ ⟦⟧ )+ 𝑛·1·2 := Φ.cyc( x ↦ ⟦⟧ )+ looped(𝑛·1·2) # proven
@@ -0,0 +1,31 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A loop met while an operand is being brought down to data, one whole run of 𝔻+# below the spine. That run reduces the operand under a synthetic attribute of+# its own, so what it parks on is no term of the program; the spine around the+# firing is what answers instead, with the term it had reached when the firing+# started (see 'down' in 'Morph'). The entry never fires, and the protocol keeps+# the firing it opened and the loop it met underneath.+symbolic: |+ - λ: L_outer+ dataize:+ 𝛿1: ξ.arg+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+ - λ: L_loop+ 𝑛: ⟦ λ ⤍ L_loop ⟧+location: 'Q.x'+acyclic: proven+steps: 250+input: >+ ⟦ x ↦ ⟦ arg ↦ ⟦ λ ⤍ L_loop ⟧.foo, λ ⤍ L_outer ⟧.bar ⟧+result: '⟦ arg ↦ L_loop:λ.foo, λ ⤍ L_outer ⟧.bar'+protocol: |+ 𝕄(Φ.x):+ 𝔼(L_outer):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝔼(L_loop):+ 𝑛·2·1 := L_loop:λ # 𝑛+ 𝑛·2·2 := L_loop:λ # 𝕄(𝑛·2·1)+ looped(L_loop:λ) # proven
@@ -0,0 +1,24 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The operand of a firing is itself stuck on a λ function no entry answers, so+# under '_partial' the block of the firing opens and binds nothing: 𝛿1 never+# came down, and the whole term is handed back the way it was reached.+symbolic: |+ - λ: L_pair+ dataize:+ 𝛿1: $.x+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+location: 'Q.y'+partial: true+input: >+ ⟦ y ↦ ⟦ x ↦ ⟦ λ ⤍ L_none ⟧.foo,+ λ ⤍ L_pair ⟧.z ⟧+result: '⟦ x ↦ L_none:λ.foo, λ ⤍ L_pair ⟧.z'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_pair):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ unanswered(L_none) # 𝕄(L_none:λ)+ stuck(L_none)
@@ -0,0 +1,21 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The 'dataize' operand of 'L_pair' is a formation whose φ is a void nothing+# filled, so no dataization rule matches it. Under '_partial' that parks the+# firing just as the terminator ⊥ does, and the protocol writes the dead end+# as 'unanswered(⊥)' with the formation beside it (#1401).+symbolic: |+ - λ: L_pair+ dataize:+ 𝛿1: $.x+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+location: 'Q.y'+partial: true+input: '⟦ y ↦ ⟦ x ↦ ⟦ φ ↦ ∅ ⟧, λ ⤍ L_pair ⟧.z ⟧'+result: '⟦ x(φ) ↦ ⟦⟧, λ ⤍ L_pair ⟧.z'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_pair):+ unanswered(⊥) # 𝔻(∅:φ)+ stuck(⊥)
@@ -0,0 +1,96 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# 'block' is applied to 'buffer' only, so its void 'data' stays unfilled and+# the 'dataize' operand 'ρ.data.size' of 'L_dataized' reaches the terminator ⊥.+# Under '_partial' that parks the firing the way an operand parked on a λ+# function no entry answers does, rather than ending the run: the protocol+# writes 'unanswered(⊥)' with the term 𝔻 could not dataize, and the walk goes on+# to 'L_root', whose own operand dies the same way (#1401).+symbolic: |+ - λ: L_dataized+ dataize:+ 𝛿1: $.target+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_entry+ dataize:+ 𝛿1: $.n+ morph:+ 𝑛1: $.v.φ+ 𝑛: Φ.l🌵.root( 𝑛1 )+ - λ: L_root+ dataize:+ 𝛿1: $.v+ 𝑛: ⟦ ⟧+location: 'Q.l🌵'+deep: true+acyclic: proven+partial: true+steps: 32+input: >+ ⟦+ number ↦ ⟦ φ ↦ ∅ ⟧,+ bytes ↦ ⟦ φ ↦ ∅, size ↦ ⟦ λ ⤍ L_bytes_size ⟧ ⟧,+ dataized ↦ ⟦ target ↦ ∅, λ ⤍ L_dataized ⟧,+ block ↦ ⟦ data ↦ ∅, buffer ↦ ∅, read ↦ ⟦ φ ↦ Φ.dataized( target ↦ ξ.ρ.data.size ).as-bytes ⟧ ⟧,+ l🌵 ↦ ⟦+ mark ↦ ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧,+ root ↦ ⟦ v ↦ ∅, λ ⤍ L_root ⟧,+ e1 ↦ Φ.l🌵.mark( n ↦ Φ.number( φ ↦ Φ.bytes( φ ↦ ⟦ Δ ⤍ 3F-F0-00-00-00-00-00-00 ⟧ ) ) )( v ↦ Φ.block( buffer ↦ Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎1 ⟧ ) ).read )+ ⟧+ ⟧+result: |-+ ⟦+ mark(n, v) ↦ L_entry:λ,+ root(v) ↦ L_root:λ,+ e1 ↦ ⟦ v ↦ Φ.dataized( target ↦ ⊥ ).as-bytes, λ ⤍ L_root ⟧+ ⟧+protocol: |+ 𝕄(Φ.l🌵):+ 𝕄(Φ.l🌵.e1):+ 𝑛·0·1 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝑛·0·2 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·0·3 := ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧( n ↦ 𝑛·0·2 )+ 𝑛·0·4 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·5 := Φ.block( buffer ↦ 𝑛·0·4 )+ 𝑛·0·6 := Φ.block( buffer ↦ 𝑛·0·4 )+ 𝑛·0·7 := ⟦ n ↦ ∅, v ↦ ∅, λ ⤍ L_entry ⟧( n ↦ 𝑛·0·2 )+ 𝑛·0·8 := 𝑛·0·7( v ↦ 𝑛·0·6.read )+ 𝔼(L_entry):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·1·2 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 3F-F0-00-00-00-00-00-00 # 1.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.n)+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := Φ.block( buffer ↦ 𝑛·0·4 )+ 𝑛·1·4 := Φ.dataized( target ↦ ⊥ )+ 𝔼(L_dataized):+ unanswered(⊥) # 𝔻(⊥)+ stuck(⊥)+ 𝑛·1·5 := Φ.dataized( target ↦ ⊥ )+ 𝑛·1·6 := Φ.dataized( target ↦ ⊥ )+ 𝔼(L_dataized):+ stuck(⊥)+ 𝑛·1·7 := Φ.dataized( target ↦ ⊥ )+ 𝑛·1·8 := Φ.dataized( target ↦ ⊥ )+ 𝔼(L_dataized):+ stuck(⊥)+ 𝑛·1·9 := Φ.dataized( target ↦ ⊥ )+ 𝔼(L_dataized):+ stuck(⊥)+ 𝑛1·1 := 𝑛·1·9.as-bytes # 𝕄(ξ.v.φ)+ 𝑛·1·10 := Φ.l🌵.root( 𝑛·1·9.as-bytes ) # 𝑛+ 𝕄(𝑛·1·10):+ 𝑛·1·11 := ⟦ v ↦ ∅, λ ⤍ L_root ⟧( v ↦ 𝑛·1·9.as-bytes )+ 𝑛·1·12 := 𝑛·1·11 # 𝕄(𝑛·1·10)+ 𝔼(L_root):+ 𝔻(Φ.a🌵6):+ 𝕄(Φ.a🌵6):+ 𝑛·6·1 := Φ.dataized( target ↦ ⊥ )+ 𝔼(L_dataized):+ unanswered(⊥) # 𝔻(⊥)+ stuck(⊥)+ stuck(⊥)
@@ -0,0 +1,27 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# Branches differing anywhere but in a symbol are not joined, and that is the+# whole rule: no fallback and no second alternative. Bringing two branches to+# one shape is the program's business rather than phino's, so a fork whose+# branches differ in structure gets stuck the way a λ function no entry answers+# does and '--partial' parks the site instead of failing the run.+symbolic: |+ - λ: L_fork+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ join:+ 𝑛3: [𝑛1, 𝑛2]+ 𝑛: 𝑛3+location: 'Q.y'+partial: true+input: '⟦ y ↦ ⟦ a ↦ ⟦ l ↦ ⟦ λ ⤍ 𝜎1 ⟧ ⟧, b ↦ ⟦ l ↦ ⟦ λ ⤍ 𝜎2 ⟧, x ↦ ⟦⟧ ⟧, λ ⤍ L_fork ⟧.l ⟧'+result: '⟦ a ↦ 𝜎1:λ:l, b ↦ ⟦ l ↦ 𝜎2:λ, x ↦ ⟦⟧ ⟧, λ ⤍ L_fork ⟧.l'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_fork):+ 𝑛1·1 := 𝜎1:λ:l # 𝕄(ξ.a)+ 𝑛2·1 := ⟦ l ↦ 𝜎2:λ, x ↦ ⟦⟧ ⟧ # 𝕄(ξ.b)+ stuck(L_fork)
@@ -0,0 +1,18 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The same λ function under '_partial': the run ends on the residue the spine+# had reached instead of failing.+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.x'+partial: true+input: '⟦ x ↦ ⟦ λ ⤍ L_none ⟧.foo ⟧'+result: 'L_none:λ.foo'+protocol: |+ 𝕄(Φ.x):+ unanswered(L_none) # 𝕄(L_none:λ)
@@ -0,0 +1,21 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The same entry answering with a firing of itself, under '_acyclic': morphing+# comes back to the very term it is already reducing, so it stops there instead+# of going round until the budget is gone. The budget is generous here, so what+# ends the run is the cut and not the limit.+symbolic: |+ - λ: L_loop+ 𝑛: ⟦ λ ⤍ L_loop ⟧+location: 'Q.x'+acyclic: proven+steps: 250+input: '⟦ x ↦ ⟦ λ ⤍ L_loop ⟧.foo ⟧'+result: 'L_loop:λ.foo'+protocol: |+ 𝕄(Φ.x):+ 𝔼(L_loop):+ 𝑛·1·1 := L_loop:λ # 𝑛+ 𝑛·1·2 := L_loop:λ # 𝕄(𝑛·1·1)+ looped(L_loop:λ) # proven
@@ -0,0 +1,33 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The very program of 'parks-a-firing-whose-operand-dataizes-in-circles', run+# with '--partial' as well. The two flags reach the same place by different+# roads: on its own '--acyclic' lets the loop travel up to the 𝕄 spine around+# the firing, while under '--partial' the operand's own run of 𝔻 ends on the+# residue it had reached and the firing is left with nothing to bind, so it gets+# stuck the way one whose λ function cannot fire does. Either way the site is+# parked and the answer is the same, which is what "--acyclic needs no+# --partial" means for a loop 𝔻 catches (#1290).+symbolic: |+ - λ: L_outer+ dataize:+ 𝛿1: ξ.arg+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+location: 'Q.x'+acyclic: proven+partial: true+steps: 250+input: >+ ⟦ cyc ↦ ⟦ x ↦ ∅, φ ↦ Φ.cyc( ξ.x ) ⟧,+ x ↦ ⟦ arg ↦ Φ.cyc( ⟦⟧ ), λ ⤍ L_outer ⟧.bar ⟧+result: '⟦ arg ↦ Φ.cyc( ⟦⟧ ), λ ⤍ L_outer ⟧.bar'+protocol: |+ 𝕄(Φ.x):+ 𝔼(L_outer):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.cyc( x ↦ ⟦⟧ )+ 𝑛·1·2 := Φ.cyc( x ↦ ⟦⟧ )+ looped(𝑛·1·2) # proven+ stuck(L_outer)
@@ -0,0 +1,22 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The same λ function no entry answers, under '_partial' and the deep walk: the+# spine parks the site and the walk goes over the residue it parked on, so 𝔼 is+# attempted on that one site twice. The protocol records it once, since what a+# 'unanswered(…)' line counts is the sites 𝔼 got stuck on and not the passes the+# walk made over them (#1300).+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.x'+deep: true+partial: true+input: '⟦ x ↦ ⟦ λ ⤍ L_none ⟧.foo ⟧'+result: 'L_none:λ.foo'+protocol: |+ 𝕄(Φ.x):+ unanswered(L_none) # 𝕄(L_none:λ)
@@ -0,0 +1,20 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A 'morph' operand of the firing is a symbol the program already carried:+# 𝕄 hands it back the way it found it, since a symbol is already a normal form+# and there is nothing under it to reduce. The answer then mints after it.+symbolic: |+ - λ: L_keep+ morph:+ 𝑛1: $.x+ 𝑛: ⟦ z ↦ ⟦ λ ⤍ 𝜎 ⟧ ⟧+location: 'Q.y'+input: '⟦ y ↦ ⟦ x ↦ ⟦ λ ⤍ 𝜎4 ⟧, λ ⤍ L_keep ⟧.z ⟧'+result: '𝜎5:λ'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_keep):+ 𝑛1·1 := 𝜎4:λ # 𝕄(ξ.x)+ 𝑛·1·1 := 𝜎5:λ:z # 𝑛+ 𝑛·1·2 := 𝜎5:λ:z # 𝕄(𝑛·1·1)
@@ -0,0 +1,118 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A branch is where a 'morph' operand earns its place: the condition comes+# down through 𝔻 and answers a symbol nobody has decided, both branches reach+# a normal form through 𝕄, and the answer is one of them. Every line of the+# firing points back at the line that minted the symbol it carries, which is+# how the dependencies between firings are read.+symbolic: |+ - λ: L_number_gt+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.bool( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+ - λ: L_fork+ dataize:+ 𝛿1: $.ρ+ morph:+ 𝑛1: $.then+ 𝑛2: $.else+ 𝑛: 𝑛1+location: 'Q.@'+deep: true+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ bool(φ) ↦ ⟦ if ↦ ⟦ ρ ↦ ∅, then ↦ ∅, else ↦ ∅, λ ⤍ L_fork ⟧ ⟧,+ number(φ) ↦ ⟦+ gt(ρ, x) ↦ ⟦ λ ⤍ L_number_gt ⟧,+ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ @ ↦ 5.gt( 0 ).if( 1.plus( 2 ), 3.plus( 4 ) ) ⟧+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := 5+ 𝑛·0·2 := 𝑛·0·1.gt( x ↦ 0 )+ 𝔼(L_number_gt):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := 5+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := 0+ 𝑛·1·4 := Φ.bytes( φ ↦ 00-00-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 00-00-00-00-00-00-00-00 # 0.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.bool( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.bool( φ ↦ 𝜎1:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝑛·0·3 := 𝑛·1·6.if( then ↦ 1.plus( 2 ) )+ 𝑛·0·4 := 𝑛·0·3( else ↦ 3.plus( 4 ) )+ 𝕄(Φ.φ.then):+ 𝑛·0·5 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝑛·0·6 := Φ.number( φ ↦ 𝑛·0·5 )+ 𝑛·0·7 := Φ.number( φ ↦ 𝑛·0·5 )+ 𝑛·0·8 := Φ.bytes( φ ↦ 40-00-00-00-00-00-00-00:Δ )+ 𝑛·0·9 := Φ.number( φ ↦ 𝑛·0·8 )+ 𝑛·0·10 := Φ.number( φ ↦ 𝑛·0·5 )+ 𝑛·0·11 := 𝑛·0·10.plus( x ↦ 𝑛·0·9 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.number( φ ↦ 𝑛·0·5 )+ 𝑛·2·2 := Φ.bytes( φ ↦ 3F-F0-00-00-00-00-00-00:Δ )+ 𝛿·2·1 := 3F-F0-00-00-00-00-00-00 # 1.0+ 𝛿1·2 := 𝛿·2·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵3):+ 𝕄(Φ.a🌵3):+ 𝑛·2·3 := Φ.number( φ ↦ 𝑛·0·8 )+ 𝑛·2·4 := Φ.bytes( φ ↦ 40-00-00-00-00-00-00-00:Δ )+ 𝛿·2·2 := 40-00-00-00-00-00-00-00 # 2.0+ 𝛿2·2 := 𝛿·2·2 # 𝔻(ξ.x)+ 𝑛·2·5 := Φ.number( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·2·5):+ 𝑛·2·6 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·2·7 := 𝑛·2·6 # 𝕄(𝑛·2·5)+ 𝕄(Φ.φ.else):+ 𝑛·0·12 := Φ.bytes( φ ↦ 40-08-00-00-00-00-00-00:Δ )+ 𝑛·0·13 := Φ.number( φ ↦ 𝑛·0·12 )+ 𝑛·0·14 := Φ.number( φ ↦ 𝑛·0·12 )+ 𝑛·0·15 := Φ.bytes( φ ↦ 40-10-00-00-00-00-00-00:Δ )+ 𝑛·0·16 := Φ.number( φ ↦ 𝑛·0·15 )+ 𝑛·0·17 := Φ.number( φ ↦ 𝑛·0·12 )+ 𝑛·0·18 := 𝑛·0·17.plus( x ↦ 𝑛·0·16 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵4):+ 𝕄(Φ.a🌵4):+ 𝑛·3·1 := Φ.number( φ ↦ 𝑛·0·12 )+ 𝑛·3·2 := Φ.bytes( φ ↦ 40-08-00-00-00-00-00-00:Δ )+ 𝛿·3·1 := 40-08-00-00-00-00-00-00 # 3.0+ 𝛿1·3 := 𝛿·3·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵5):+ 𝕄(Φ.a🌵5):+ 𝑛·3·3 := Φ.number( φ ↦ 𝑛·0·15 )+ 𝑛·3·4 := Φ.bytes( φ ↦ 40-10-00-00-00-00-00-00:Δ )+ 𝛿·3·2 := 40-10-00-00-00-00-00-00 # 4.0+ 𝛿2·3 := 𝛿·3·2 # 𝔻(ξ.x)+ 𝑛·3·5 := Φ.number( φ ↦ 𝜎3:λ ) # 𝑛+ 𝕄(𝑛·3·5):+ 𝑛·3·6 := Φ.number( φ ↦ 𝜎3:λ )+ 𝑛·3·7 := 𝑛·3·6 # 𝕄(𝑛·3·5)+ 𝔼(L_fork):+ 𝔻(Φ.a🌵6):+ 𝕄(Φ.a🌵6):+ 𝑛·4·1 := Φ.bool( φ ↦ 𝜎1:λ )+ 𝛿1·4 := 𝔻(𝜎1:λ) # 𝔻(ξ.ρ)+ 𝑛1·4 := 𝑛·2·7 # 𝕄(ξ.then)+ 𝑛2·4 := 𝑛·3·7 # 𝕄(ξ.else)+ 𝑛·4·2 := 𝑛1·4 # 𝑛+ 𝑛·4·3 := 𝑛1·4 # 𝕄(𝑛·4·2)
@@ -0,0 +1,36 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# An entry answering with a firing of itself fires until the budget is gone.+# Recursion is nothing phino prevents on its own — that is the object model's+# business — so without '_acyclic' the step limit is what ends the run, and+# every firing it paid for is in the protocol. This is the control the pack+# asking for the guard stands against.+symbolic: |+ - λ: L_loop+ 𝑛: ⟦ λ ⤍ L_loop ⟧+location: 'Q.x'+steps: 6+input: '⟦ x ↦ ⟦ λ ⤍ L_loop ⟧.foo ⟧'+fails: 'reaching the limit of steps'+protocol: |+ 𝕄(Φ.x):+ 𝔼(L_loop):+ 𝑛·1·1 := L_loop:λ # 𝑛+ 𝑛·1·2 := L_loop:λ # 𝕄(𝑛·1·1)+ 𝔼(L_loop):+ 𝑛·2·1 := L_loop:λ # 𝑛+ 𝑛·2·2 := L_loop:λ # 𝕄(𝑛·2·1)+ 𝔼(L_loop):+ 𝑛·3·1 := L_loop:λ # 𝑛+ 𝑛·3·2 := L_loop:λ # 𝕄(𝑛·3·1)+ 𝔼(L_loop):+ 𝑛·4·1 := L_loop:λ # 𝑛+ 𝑛·4·2 := L_loop:λ # 𝕄(𝑛·4·1)+ 𝔼(L_loop):+ 𝑛·5·1 := L_loop:λ # 𝑛+ 𝑛·5·2 := L_loop:λ # 𝕄(𝑛·5·1)+ 𝔼(L_loop):+ 𝑛·6·1 := L_loop:λ # 𝑛+ 𝕄(𝑛·6·1):+ starved(6)
@@ -0,0 +1,37 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A 'symbolize' line reduces nothing: it stands the data of a term another line+# of the entry has already bound into unknowns, so a normal form reached from a+# literal is written the way one reached from an unknown is written and the two+# of them compare as expressions. Here 𝑛1 came from a literal and 𝑛2 from a+# value nobody worked out: after the stage both of them carry ⟦ λ ⤍ 𝜎 ⟧ where+# they differ. What is known about each fresh symbol stands on a line of its+# own, since a 𝜎 is the name of a λ function and nothing binds bytes to it, and+# a term that carried no datum at all passes through as it was. The comments of+# the two pairs of lines are what tells them apart: a 'morph' operand is+# commented with the judgment that reduced it and the term it was reduced from,+# '𝕄(ξ.a)', where a 'symbolize' line names the meta it was told to stand and no+# judgment at all, since none ran (#1306).+symbolic: |+ - λ: L_join+ morph:+ 𝑛1: $.a+ 𝑛2: $.b+ symbolize:+ 𝑛3: 𝑛1+ 𝑛4: 𝑛2+ 𝑛: ⟦ l ↦ 𝑛3 ⟧+location: 'Q.y'+input: '⟦ y ↦ ⟦ a ↦ ⟦ Δ ⤍ 01- ⟧, b ↦ ⟦ λ ⤍ 𝜎7 ⟧, λ ⤍ L_join ⟧.l ⟧'+result: '𝜎8:λ'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_join):+ 𝑛1·1 := 01-:Δ # 𝕄(ξ.a)+ 𝑛2·1 := 𝜎7:λ # 𝕄(ξ.b)+ 𝔻(𝜎8:λ) == 01-+ 𝑛3·1 := 𝜎8:λ # 𝑛1+ 𝑛4·1 := 𝑛2·1 # 𝑛2+ 𝑛·1·1 := 𝜎8:λ:l # 𝑛+ 𝑛·1·2 := 𝜎8:λ:l # 𝕄(𝑛·1·1)
@@ -0,0 +1,45 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A program written by an earlier run holds symbols of its own, so minting+# starts after the last of them and a fresh symbol is never spelled like one+# the input was already written with.+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.@'+deep: true+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ number(φ) ↦ ⟦ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ old ↦ ⟦ λ ⤍ 𝜎3 ⟧,+ @ ↦ 5.plus( 6 ) ⟧+result: '⟦ φ ↦ 𝜎4:λ, plus(x) ↦ L_number_plus:λ ⟧'+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := 5+ 𝑛·0·2 := 𝑛·0·1.plus( x ↦ 6 )+ 𝕄(Φ.φ.x):+ 𝑛·0·3 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝑛·0·4 := Φ.number( φ ↦ 𝑛·0·3 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := 5+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := Φ.number( φ ↦ 𝑛·0·3 )+ 𝑛·1·4 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 40-18-00-00-00-00-00-00 # 6.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.number( φ ↦ 𝜎4:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.number( φ ↦ 𝜎4:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)
@@ -0,0 +1,128 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# A factorial with an accumulator, under '--acyclic=plausible'. Every round+# wraps the accumulator in one more 'pair', which no entry answers, so no two+# rounds are ever the same formation up to a renaming of symbols and+# '--acyclic=proven' goes round forever. The formation 'if' the deep walk fires+# on the second round holds the one it fired on the first, under the wrapper it+# gained, which is what the plausible guard compares by, so the second firing+# is cut before it opens and its 'looped' line names the mode that cut it+# (#1451). Every round is a copy of 'Φ.fact', but its φ reads the 'n' and the+# 'acc' of the copy it stands in, so the walk enters it in every round rather+# than once for the whole object (#1485). The argument 'n' and every symbol+# 'dec' answers stand in a carrier '⟦ φ ↦ 𝜎 ⟧', since the walk defers a copy+# one of whose arguments is a bare symbol instead of entering it (#1729).+# The cut 'if' is the φ of a copy of 'Φ.fact', so the cut answers that copy+# with a fresh symbol, which the 'join' of the first 'if' pairs with the datum+# of the other branch, and the run answers a symbol instead of getting stuck+# (#1735).+symbolic: |+ - λ: L_zero+ dataize:+ 𝛿1: $.x+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+ - λ: L_dec+ dataize:+ 𝛿1: $.x+ 𝑛: ⟦ φ ↦ ⟦ λ ⤍ 𝜎 ⟧ ⟧+ - λ: L_if+ dataize:+ 𝛿1: $.c+ morph:+ 𝑛1: $.left+ 𝑛2: $.right+ symbolize:+ 𝑛3: 𝑛1+ 𝑛4: 𝑛2+ join:+ 𝑛5: [𝑛3, 𝑛4]+ 𝑛: 𝑛5+location: 'Q.x'+deep: true+acyclic: plausible+partial: true+steps: 250+input: >+ ⟦ if ↦ ⟦ c ↦ ∅, left ↦ ∅, right ↦ ∅, λ ⤍ L_if ⟧,+ zero ↦ ⟦ x ↦ ∅, λ ⤍ L_zero ⟧,+ dec ↦ ⟦ x ↦ ∅, λ ⤍ L_dec ⟧,+ pair ↦ ⟦ head ↦ ∅, tail ↦ ∅ ⟧,+ fact ↦ ⟦ n ↦ ∅, acc ↦ ∅, φ ↦ Φ.if( c ↦ Φ.zero( x ↦ ξ.n ), left ↦ ξ.acc, right ↦ Φ.fact( n ↦ Φ.dec( x ↦ ξ.n ), acc ↦ Φ.pair( head ↦ ξ.n, tail ↦ ξ.acc ) ) ) ⟧,+ x ↦ Φ.fact( n ↦ ⟦ φ ↦ ⟦ λ ⤍ 𝜎1 ⟧ ⟧, acc ↦ ⟦ Δ ⤍ 00- ⟧ ) ⟧+result: |-+ ⟦ n ↦ 𝜎1:λ:φ, acc ↦ 00-:Δ, φ ↦ 𝜎8:λ ⟧+protocol: |+ 𝕄(Φ.x):+ 𝑛·0·1 := Φ.fact( n ↦ 𝜎1:λ:φ )+ 𝑛·0·2 := 𝑛·0·1( acc ↦ 00-:Δ )+ 𝕄(Φ.x.φ):+ 𝑛·0·3 := Φ.zero( x ↦ 𝜎1:λ:φ )+ 𝔼(L_zero):+ 𝛿1·1 := 𝔻(𝜎1:λ) # 𝔻(ξ.x)+ 𝑛·1·1 := 𝜎2:λ # 𝑛+ 𝑛·1·2 := 𝜎2:λ # 𝕄(𝑛·1·1)+ 𝑛·0·4 := Φ.if( c ↦ 𝜎2:λ )+ 𝑛·0·5 := Φ.if( c ↦ 𝜎2:λ )+ 𝑛·0·6 := 𝑛·0·5( left ↦ 00-:Δ )+ 𝑛·0·7 := Φ.dec( x ↦ 𝜎1:λ:φ )+ 𝔼(L_dec):+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.x)+ 𝑛·2·1 := 𝜎3:λ:φ # 𝑛+ 𝑛·2·2 := 𝜎3:λ:φ # 𝕄(𝑛·2·1)+ 𝑛·0·8 := Φ.fact( n ↦ 𝜎3:λ:φ )+ 𝑛·0·9 := Φ.pair( head ↦ 𝜎1:λ:φ )+ 𝑛·0·10 := Φ.pair( head ↦ 𝜎1:λ:φ )+ 𝑛·0·11 := 𝑛·0·10( tail ↦ 00-:Δ )+ 𝑛·0·12 := Φ.fact( n ↦ 𝜎3:λ:φ )+ 𝑛·0·13 := 𝑛·0·12( acc ↦ 𝑛·0·11 )+ 𝑛·0·14 := Φ.if( c ↦ 𝜎2:λ )+ 𝑛·0·15 := 𝑛·0·14( left ↦ 00-:Δ )+ 𝑛·0·16 := 𝑛·0·15( right ↦ 𝑛·0·13 )+ 𝔼(L_if):+ 𝛿1·3 := 𝔻(𝜎2:λ) # 𝔻(ξ.c)+ 𝑛1·3 := 00-:Δ # 𝕄(ξ.left)+ 𝕄(Φ.a🌵4):+ 𝑛·3·1 := Φ.fact( n ↦ 𝜎3:λ:φ )+ 𝑛·3·2 := 𝑛·3·1( acc ↦ 𝑛·0·11 )+ 𝕄(Φ.a🌵4.acc):+ 𝑛·3·3 := Φ.pair( head ↦ 𝜎1:λ:φ )+ 𝑛·3·4 := Φ.pair( head ↦ 𝜎1:λ:φ )+ 𝑛·3·5 := 𝑛·3·4( tail ↦ 00-:Δ )+ 𝕄(Φ.a🌵4.φ):+ 𝑛·3·6 := Φ.zero( x ↦ 𝜎3:λ:φ )+ 𝔼(L_zero):+ 𝛿1·4 := 𝔻(𝜎3:λ) # 𝔻(ξ.x)+ 𝑛·4·1 := 𝜎4:λ # 𝑛+ 𝑛·4·2 := 𝜎4:λ # 𝕄(𝑛·4·1)+ 𝑛·3·7 := Φ.if( c ↦ 𝜎4:λ )+ 𝑛·3·8 := Φ.pair( head ↦ 𝜎1:λ:φ )+ 𝑛·3·9 := 𝑛·3·8( tail ↦ 00-:Δ )+ 𝑛·3·10 := Φ.if( c ↦ 𝜎4:λ )+ 𝑛·3·11 := 𝑛·3·10( left ↦ 𝑛·3·9 )+ 𝑛·3·12 := Φ.dec( x ↦ 𝜎3:λ:φ )+ 𝔼(L_dec):+ 𝛿1·5 := 𝔻(𝜎3:λ) # 𝔻(ξ.x)+ 𝑛·5·1 := 𝜎5:λ:φ # 𝑛+ 𝑛·5·2 := 𝜎5:λ:φ # 𝕄(𝑛·5·1)+ 𝑛·3·13 := Φ.fact( n ↦ 𝜎5:λ:φ )+ 𝑛·3·14 := Φ.pair( head ↦ 𝜎3:λ:φ )+ 𝑛·3·15 := Φ.pair( head ↦ 𝜎1:λ:φ )+ 𝑛·3·16 := 𝑛·3·15( tail ↦ 00-:Δ )+ 𝑛·3·17 := Φ.pair( head ↦ 𝜎3:λ:φ )+ 𝑛·3·18 := 𝑛·3·17( tail ↦ 𝑛·3·16 )+ 𝑛·3·19 := Φ.fact( n ↦ 𝜎5:λ:φ )+ 𝑛·3·20 := 𝑛·3·19( acc ↦ 𝑛·3·18 )+ 𝑛·3·21 := Φ.if( c ↦ 𝜎4:λ )+ 𝑛·3·22 := 𝑛·3·21( left ↦ 𝑛·3·16 )+ 𝑛·3·23 := 𝑛·3·22( right ↦ 𝑛·3·20 )+ looped(𝑛·0·16) := 𝜎6 # plausible+ 𝑛2·3 := 𝜎6:λ # 𝕄(ξ.right)+ 𝔻(𝜎7:λ) == 00-+ 𝑛3·3 := 𝜎7:λ # 𝑛1+ 𝑛4·3 := 𝑛2·3 # 𝑛2+ 𝔻(𝜎8:λ) ∈ { 𝔻(𝜎7:λ), 𝔻(𝜎6:λ) }+ 𝑛5·3 := 𝜎8:λ # [𝑛3, 𝑛4]+ 𝑛·3·24 := 𝑛5·3 # 𝑛+ 𝑛·3·25 := 𝑛5·3 # 𝕄(𝑛·3·24)
@@ -0,0 +1,50 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The memo of '--acyclic=plausible' keeps what a firing answered by the λ+# function and the operands it brought down, beside the formation it fired.+# Here 'a' and 'b' fire two formations, since one reads 'x' and the other+# reads 'y', so the memo of formations misses the second. Yet both bring the+# same datum down, and an entry answers from its operands alone. Before #1661+# the firing under 'b' minted '𝜎2' for the very value '𝜎1' already named. Now+# it brings its operand down, finds the firing already answered and takes+# '𝜎1', minting nothing.+symbolic: |+ - λ: L_dataized+ dataize:+ 𝛿1: $.target+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+deep: true+partial: true+acyclic: plausible+input: >+ ⟦ dataized(target) ↦ L_dataized:λ,+ a ↦ Φ.dataized( target ↦ Φ.x ),+ b ↦ Φ.dataized( target ↦ Φ.y ),+ x ↦ ⟦ Δ ⤍ 01- ⟧,+ y ↦ ⟦ Δ ⤍ 01- ⟧ ⟧+result: >+ ⟦ dataized(target) ↦ L_dataized:λ,+ a ↦ 𝜎1:λ,+ b ↦ 𝜎1:λ,+ x ↦ 01-:Δ,+ y ↦ 01-:Δ ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.a):+ 𝑛·0·1 := Φ.dataized( target ↦ Φ.x )+ 𝔼(L_dataized):+ 𝔻(Φ.a🌵0):+ 𝛿·1·1 := 01-+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.target)+ 𝑛·1·1 := 𝜎1:λ # 𝑛+ 𝑛·1·2 := 𝜎1:λ # 𝕄(𝑛·1·1)+ 𝕄(Φ.b):+ 𝑛·0·2 := Φ.dataized( target ↦ Φ.y )+ 𝔼(L_dataized):+ 𝔻(Φ.a🌵1):+ 𝛿·2·1 := 01-+ 𝛿1·2 := 𝛿·2·1 # 𝔻(ξ.target)+ 𝑛·2·1 := 𝑛·1·2 # 𝑛+ 𝑛·2·2 := 𝑛·1·2 # 𝕄(𝑛·2·1)
@@ -0,0 +1,252 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The memo of '--acyclic=plausible' keeps a stall the step budget made beside+# the steps its firing had spent, and tells it to a firing of the same+# formation that has spent at least as many. The operand of 'x.arg' runs out+# of steps two firings down, so the stall is kept. Before #1521 it was dropped,+# and 'x' walked the nest again inside its own firing, while 'y.arg' and 'y'+# fired it all over. Now the firing inside 'x' is told the stall, and so are+# 'y.arg' and 'y', which stand as deep as 'x.arg' and 'x' did.+symbolic: |+ - λ: L_outer+ dataize:+ 𝛿1: ξ.arg+ 𝑛: ⟦ λ ⤍ 𝜎 ⟧+deep: true+partial: true+acyclic: plausible+steps: 4+input: >+ ⟦ x ↦ ⟦ λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ λ ⤍ L_none ⟧ ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧,+ y ↦ ⟦ λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ λ ⤍ L_none ⟧ ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧ ⟧+protocol: |+ 𝕄(Φ):+ 𝑛·0·1 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 )+ 𝑛·0·2 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 )+ 𝑛·0·3 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 )+ 𝑛·0·4 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 ) ⟧( v ↦ 1 ) ⟧( v ↦ 1 )+ 𝑛·0·5 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 ) ⟧( v ↦ 1 )+ 𝑛·0·6 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·7 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·2 ⟧( v ↦ 1 )+ 𝑛·0·8 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·3 ⟧( v ↦ 1 )+ 𝑛·0·9 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·4 ⟧( v ↦ 1 )+ 𝑛·0·10 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·5 ⟧( v ↦ 1 )+ 𝑛·0·11 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·6 ⟧( v ↦ 1 )+ 𝑛·0·12 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·13 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·9 ⟧( v ↦ 1 )+ 𝑛·0·14 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·10 ⟧( v ↦ 1 )+ 𝑛·0·15 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·11 ⟧( v ↦ 1 )+ 𝑛·0·16 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·12 ⟧( v ↦ 1 )+ 𝑛·0·17 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·18 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·14 ⟧( v ↦ 1 )+ 𝑛·0·19 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·15 ⟧( v ↦ 1 )+ 𝑛·0·20 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·16 ⟧( v ↦ 1 )+ 𝑛·0·21 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·17 ⟧( v ↦ 1 )+ 𝑛·0·22 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·23 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·20 ⟧( v ↦ 1 )+ 𝑛·0·24 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·21 ⟧( v ↦ 1 )+ 𝑛·0·25 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·22 ⟧( v ↦ 1 )+ 𝑛·0·26 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·27 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·24 ⟧( v ↦ 1 )+ 𝑛·0·28 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·25 ⟧( v ↦ 1 )+ 𝑛·0·29 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·26 ⟧( v ↦ 1 )+ 𝑛·0·30 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·31 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·29 ⟧( v ↦ 1 )+ 𝑛·0·32 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·30 ⟧( v ↦ 1 )+ 𝑛·0·33 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·34 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·32 ⟧( v ↦ 1 )+ 𝑛·0·35 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·33 ⟧( v ↦ 1 )+ 𝑛·0·36 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·37 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·36 ⟧( v ↦ 1 )+ 𝑛·0·38 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·39 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·38 ⟧( v ↦ 1 )+ 𝑛·0·40 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·41 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·42 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝕄(Φ.x):+ 𝕄(Φ.x.arg):+ 𝑛·0·43 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·27 ⟧( v ↦ 1 )+ 𝑛·0·44 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·34 ⟧( v ↦ 1 )+ 𝑛·0·45 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·39 ⟧( v ↦ 1 )+ 𝑛·0·46 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·42 ⟧( v ↦ 1 )+ 𝑛·0·47 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·48 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·45 ⟧( v ↦ 1 )+ 𝑛·0·49 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·46 ⟧( v ↦ 1 )+ 𝑛·0·50 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·47 ⟧( v ↦ 1 )+ 𝑛·0·51 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·52 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·50 ⟧( v ↦ 1 )+ 𝑛·0·53 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·51 ⟧( v ↦ 1 )+ 𝑛·0·54 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·55 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·54 ⟧( v ↦ 1 )+ 𝑛·0·56 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·57 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ starved(4)+ starved(4)+ starved(4)+ starved(4)+ 𝑛·0·58 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·43 ⟧( v ↦ 1 )+ 𝑛·0·59 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·48 ⟧( v ↦ 1 )+ 𝑛·0·60 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·52 ⟧( v ↦ 1 )+ 𝑛·0·61 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·55 ⟧( v ↦ 1 )+ 𝑛·0·62 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·57 ⟧( v ↦ 1 )+ 𝑛·0·63 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·64 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·60 ⟧( v ↦ 1 )+ 𝑛·0·65 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·61 ⟧( v ↦ 1 )+ 𝑛·0·66 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·62 ⟧( v ↦ 1 )+ 𝑛·0·67 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·63 ⟧( v ↦ 1 )+ 𝑛·0·68 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·69 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·66 ⟧( v ↦ 1 )+ 𝑛·0·70 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·67 ⟧( v ↦ 1 )+ 𝑛·0·71 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·68 ⟧( v ↦ 1 )+ 𝑛·0·72 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·73 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·71 ⟧( v ↦ 1 )+ 𝑛·0·74 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·72 ⟧( v ↦ 1 )+ 𝑛·0·75 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·76 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·75 ⟧( v ↦ 1 )+ 𝑛·0·77 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·78 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝔼(L_outer):+ 𝔻(Φ.a🌵0):+ 𝔼(L_outer):+ 𝔻(Φ.a🌵1):+ 𝔼(L_outer):+ starved(4) # 𝔻(Φ.a🌵2)+ stuck(L_outer)+ stuck(L_outer)+ 𝑛·0·79 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·64 ⟧( v ↦ 1 )+ 𝑛·0·80 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·69 ⟧( v ↦ 1 )+ 𝑛·0·81 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·73 ⟧( v ↦ 1 )+ 𝑛·0·82 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·76 ⟧( v ↦ 1 )+ 𝑛·0·83 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·78 ⟧( v ↦ 1 )+ 𝑛·0·84 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·85 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·81 ⟧( v ↦ 1 )+ 𝑛·0·86 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·82 ⟧( v ↦ 1 )+ 𝑛·0·87 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·83 ⟧( v ↦ 1 )+ 𝑛·0·88 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·84 ⟧( v ↦ 1 )+ 𝑛·0·89 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·90 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·87 ⟧( v ↦ 1 )+ 𝑛·0·91 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·88 ⟧( v ↦ 1 )+ 𝑛·0·92 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·89 ⟧( v ↦ 1 )+ 𝑛·0·93 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·94 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·92 ⟧( v ↦ 1 )+ 𝑛·0·95 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·93 ⟧( v ↦ 1 )+ 𝑛·0·96 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·97 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·96 ⟧( v ↦ 1 )+ 𝑛·0·98 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·99 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝔼(L_outer):+ 𝔻(Φ.a🌵3):+ 𝔼(L_outer):+ stall(L_outer)+ stuck(L_outer)+ 𝕄(Φ.y):+ 𝕄(Φ.y.arg):+ 𝑛·0·100 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·90 ⟧( v ↦ 1 )+ 𝑛·0·101 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·94 ⟧( v ↦ 1 )+ 𝑛·0·102 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·97 ⟧( v ↦ 1 )+ 𝑛·0·103 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·99 ⟧( v ↦ 1 )+ 𝑛·0·104 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·105 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·102 ⟧( v ↦ 1 )+ 𝑛·0·106 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·103 ⟧( v ↦ 1 )+ 𝑛·0·107 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·104 ⟧( v ↦ 1 )+ 𝑛·0·108 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·109 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·107 ⟧( v ↦ 1 )+ 𝑛·0·110 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·108 ⟧( v ↦ 1 )+ 𝑛·0·111 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·112 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·111 ⟧( v ↦ 1 )+ 𝑛·0·113 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·114 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ starved(4)+ starved(4)+ starved(4)+ starved(4)+ 𝑛·0·115 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·100 ⟧( v ↦ 1 )+ 𝑛·0·116 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·105 ⟧( v ↦ 1 )+ 𝑛·0·117 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·109 ⟧( v ↦ 1 )+ 𝑛·0·118 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·112 ⟧( v ↦ 1 )+ 𝑛·0·119 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·114 ⟧( v ↦ 1 )+ 𝑛·0·120 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·121 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·117 ⟧( v ↦ 1 )+ 𝑛·0·122 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·118 ⟧( v ↦ 1 )+ 𝑛·0·123 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·119 ⟧( v ↦ 1 )+ 𝑛·0·124 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·120 ⟧( v ↦ 1 )+ 𝑛·0·125 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·126 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·123 ⟧( v ↦ 1 )+ 𝑛·0·127 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·124 ⟧( v ↦ 1 )+ 𝑛·0·128 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·125 ⟧( v ↦ 1 )+ 𝑛·0·129 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·130 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·128 ⟧( v ↦ 1 )+ 𝑛·0·131 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·129 ⟧( v ↦ 1 )+ 𝑛·0·132 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·133 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·132 ⟧( v ↦ 1 )+ 𝑛·0·134 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·135 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝔼(L_outer):+ stall(L_outer)+ 𝑛·0·136 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·121 ⟧( v ↦ 1 )+ 𝑛·0·137 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·126 ⟧( v ↦ 1 )+ 𝑛·0·138 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·130 ⟧( v ↦ 1 )+ 𝑛·0·139 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·133 ⟧( v ↦ 1 )+ 𝑛·0·140 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·135 ⟧( v ↦ 1 )+ 𝑛·0·141 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·142 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·138 ⟧( v ↦ 1 )+ 𝑛·0·143 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·139 ⟧( v ↦ 1 )+ 𝑛·0·144 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·140 ⟧( v ↦ 1 )+ 𝑛·0·145 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·141 ⟧( v ↦ 1 )+ 𝑛·0·146 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·147 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·144 ⟧( v ↦ 1 )+ 𝑛·0·148 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·145 ⟧( v ↦ 1 )+ 𝑛·0·149 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·146 ⟧( v ↦ 1 )+ 𝑛·0·150 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·151 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·149 ⟧( v ↦ 1 )+ 𝑛·0·152 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·150 ⟧( v ↦ 1 )+ 𝑛·0·153 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·154 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·153 ⟧( v ↦ 1 )+ 𝑛·0·155 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·156 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝔼(L_outer):+ stall(L_outer)+ 𝑛·0·157 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·142 ⟧( v ↦ 1 )+ 𝑛·0·158 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·147 ⟧( v ↦ 1 )+ 𝑛·0·159 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·151 ⟧( v ↦ 1 )+ 𝑛·0·160 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·154 ⟧( v ↦ 1 )+ 𝑛·0·161 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·156 ⟧( v ↦ 1 )+ 𝑛·0·162 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·163 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·158 ⟧( v ↦ 1 )+ 𝑛·0·164 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·159 ⟧( v ↦ 1 )+ 𝑛·0·165 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·160 ⟧( v ↦ 1 )+ 𝑛·0·166 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·161 ⟧( v ↦ 1 )+ 𝑛·0·167 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·162 ⟧( v ↦ 1 )+ 𝑛·0·168 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·169 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·165 ⟧( v ↦ 1 )+ 𝑛·0·170 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·166 ⟧( v ↦ 1 )+ 𝑛·0·171 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·167 ⟧( v ↦ 1 )+ 𝑛·0·172 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·168 ⟧( v ↦ 1 )+ 𝑛·0·173 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·174 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·170 ⟧( v ↦ 1 )+ 𝑛·0·175 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·171 ⟧( v ↦ 1 )+ 𝑛·0·176 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·172 ⟧( v ↦ 1 )+ 𝑛·0·177 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·173 ⟧( v ↦ 1 )+ 𝑛·0·178 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·179 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·176 ⟧( v ↦ 1 )+ 𝑛·0·180 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·177 ⟧( v ↦ 1 )+ 𝑛·0·181 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·178 ⟧( v ↦ 1 )+ 𝑛·0·182 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·183 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·180 ⟧( v ↦ 1 )+ 𝑛·0·184 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·181 ⟧( v ↦ 1 )+ 𝑛·0·185 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·182 ⟧( v ↦ 1 )+ 𝑛·0·186 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·187 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·185 ⟧( v ↦ 1 )+ 𝑛·0·188 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·186 ⟧( v ↦ 1 )+ 𝑛·0·189 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·190 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·188 ⟧( v ↦ 1 )+ 𝑛·0·191 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·189 ⟧( v ↦ 1 )+ 𝑛·0·192 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·193 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·192 ⟧( v ↦ 1 )+ 𝑛·0·194 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·195 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ 𝑛·0·194 ⟧( v ↦ 1 )+ 𝑛·0·196 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·197 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )+ 𝑛·0·198 := ⟦ v ↦ ∅, λ ⤍ L_outer, arg ↦ L_none:λ ⟧( v ↦ 1 )
@@ -0,0 +1,40 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# Both operands of the firing are symbols the program came in with, and both+# dataize to the very same 42. Only the protocol tells them apart: it writes+# the symbol each datum was manufactured for, so 𝜎2 and 𝜎5 stay two unknowns+# and not one.+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q.@'+deep: true+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ number(φ) ↦ ⟦ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ @ ↦ Φ.number( φ ↦ ⟦ λ ⤍ 𝜎2 ⟧ ).plus(+ Φ.number( φ ↦ ⟦ λ ⤍ 𝜎5 ⟧ ) ) ⟧+result: '⟦ φ ↦ 𝜎6:λ, plus(x) ↦ L_number_plus:λ ⟧'+protocol: |+ 𝕄(Φ.φ):+ 𝑛·0·1 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·0·2 := 𝑛·0·1.plus( x ↦ Φ.number( φ ↦ 𝜎5:λ ) )+ 𝕄(Φ.φ.x):+ 𝑛·0·3 := Φ.number( φ ↦ 𝜎5:λ )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.number( φ ↦ 𝜎2:λ )+ 𝛿1·1 := 𝔻(𝜎2:λ) # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·2 := Φ.number( φ ↦ 𝜎5:λ )+ 𝛿2·1 := 𝔻(𝜎5:λ) # 𝔻(ξ.x)+ 𝑛·1·3 := Φ.number( φ ↦ 𝜎6:λ ) # 𝑛+ 𝕄(𝑛·1·3):+ 𝑛·1·4 := Φ.number( φ ↦ 𝜎6:λ )+ 𝑛·1·5 := 𝑛·1·4 # 𝕄(𝑛·1·3)
@@ -0,0 +1,54 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The memo of '--acyclic=plausible' keeps an answer by the operands a firing+# brought down, and a symbol is an operand of its own: every symbol dataizes+# to the one manufactured datum, so two firings over two symbols come down to+# the same bytes, yet they stand for two values nobody worked out. A memo+# keyed on the bytes would answer the second firing with the symbol the first+# one minted and make the two values one; this one keys on the symbol, so each+# firing mints a symbol of its own.+symbolic: |+ - λ: L_dataized+ dataize:+ 𝛿1: $.target+ 𝑛: Φ.bytes( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+deep: true+acyclic: plausible+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ dataized(target) ↦ L_dataized:λ,+ x ↦ Φ.dataized( target ↦ Φ.bytes( φ ↦ 𝜎1:λ ) ),+ y ↦ Φ.dataized( target ↦ Φ.bytes( φ ↦ 𝜎2:λ ) ) ⟧+result: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ dataized(target) ↦ L_dataized:λ,+ x ↦ ⟦ φ ↦ 𝜎3:λ ⟧,+ y ↦ ⟦ φ ↦ 𝜎4:λ ⟧ ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.x):+ 𝑛·0·1 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝑛·0·2 := Φ.dataized( target ↦ 𝑛·0·1 )+ 𝔼(L_dataized):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.bytes( φ ↦ 𝜎1:λ )+ 𝛿1·1 := 𝔻(𝜎1:λ) # 𝔻(ξ.target)+ 𝑛·1·2 := Φ.bytes( φ ↦ 𝜎3:λ ) # 𝑛+ 𝕄(𝑛·1·2):+ 𝑛·1·3 := Φ.bytes( φ ↦ 𝜎3:λ )+ 𝑛·1·4 := 𝑛·1·3 # 𝕄(𝑛·1·2)+ 𝕄(Φ.y):+ 𝑛·0·3 := Φ.bytes( φ ↦ 𝜎2:λ )+ 𝑛·0·4 := Φ.dataized( target ↦ 𝑛·0·3 )+ 𝔼(L_dataized):+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·2·1 := Φ.bytes( φ ↦ 𝜎2:λ )+ 𝛿1·2 := 𝔻(𝜎2:λ) # 𝔻(ξ.target)+ 𝑛·2·2 := Φ.bytes( φ ↦ 𝜎4:λ ) # 𝑛+ 𝕄(𝑛·2·2):+ 𝑛·2·3 := Φ.bytes( φ ↦ 𝜎4:λ )+ 𝑛·2·4 := 𝑛·2·3 # 𝕄(𝑛·2·2)
@@ -0,0 +1,73 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The synonym of '--acyclic=plausible': every dispatch on 'Φ.num' copies the+# object, and the deep walk entered the bindings of every copy as if they were+# new, so the test of 'num' was brought to its normal form and fired once+# under 'a', once under 'b' and once under 'c' (#1480). The copy goes by a+# name in the world, 'Φ.num( φ ↦ … )', and the object part of that name is a+# synonym of it, so the walk enters 'test' of 'Φ.num' in the first copy it+# meets and leaves it as written in every later one. The φ each copy fills is+# an argument of that copy and not a binding of 'Φ.num', so it is entered+# every time.+symbolic: |+ - λ: L_id+ morph:+ 𝑛1: $.x+ 𝑛: 𝑛1+ - λ: L_twice+ dataize:+ 𝛿1: $.ρ+ 𝑛: Φ.num( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+deep: true+partial: true+acyclic: plausible+steps: 32+input: >+ ⟦ num ↦ ⟦ φ ↦ ∅, twice ↦ ⟦ ρ ↦ ∅, λ ⤍ L_twice ⟧, test ↦ Φ.num( φ ↦ ⟦ Δ ⤍ 01- ⟧ ).twice ⟧,+ a ↦ ⟦ λ ⤍ L_id, x ↦ Φ.num( φ ↦ ⟦ Δ ⤍ 2A- ⟧ ) ⟧,+ b ↦ ⟦ λ ⤍ L_id, x ↦ Φ.num( φ ↦ ⟦ Δ ⤍ 2B- ⟧ ) ⟧,+ c ↦ ⟦ λ ⤍ L_id, x ↦ Φ.num( φ ↦ ⟦ Δ ⤍ 2C- ⟧ ) ⟧ ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.a):+ 𝕄(Φ.a.x):+ 𝑛·0·1 := Φ.num( φ ↦ 2A-:Δ )+ 𝔼(L_id):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.num( φ ↦ 2A-:Δ )+ 𝕄(Φ.a🌵0.test):+ 𝑛·1·2 := Φ.num( φ ↦ 01-:Δ )+ 𝑛·1·3 := Φ.num( φ ↦ 01-:Δ )+ 𝔼(L_twice):+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·2·1 := Φ.num( φ ↦ 01-:Δ )+ 𝛿·2·1 := 01-+ 𝛿1·2 := 𝛿·2·1 # 𝔻(ξ.ρ)+ 𝑛·2·2 := Φ.num( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·2·2):+ 𝑛·2·3 := Φ.num( φ ↦ 𝜎1:λ )+ 𝑛·2·4 := 𝑛·2·3 # 𝕄(𝑛·2·2)+ 𝑛1·1 := 𝑛·1·1 # 𝕄(ξ.x)+ 𝑛·1·4 := 𝑛·1·1 # 𝑛+ 𝑛·1·5 := 𝑛·1·1 # 𝕄(𝑛·1·4)+ 𝕄(Φ.b):+ 𝕄(Φ.b.x):+ 𝑛·0·2 := Φ.num( φ ↦ 2B-:Δ )+ 𝔼(L_id):+ 𝕄(Φ.a🌵2):+ 𝑛·3·1 := Φ.num( φ ↦ 2B-:Δ )+ 𝑛1·3 := 𝑛·3·1 # 𝕄(ξ.x)+ 𝑛·3·2 := 𝑛·3·1 # 𝑛+ 𝑛·3·3 := 𝑛·3·1 # 𝕄(𝑛·3·2)+ 𝕄(Φ.c):+ 𝕄(Φ.c.x):+ 𝑛·0·3 := Φ.num( φ ↦ 2C-:Δ )+ 𝔼(L_id):+ 𝕄(Φ.a🌵3):+ 𝑛·4·1 := Φ.num( φ ↦ 2C-:Δ )+ 𝑛1·4 := 𝑛·4·1 # 𝕄(ξ.x)+ 𝑛·4·2 := 𝑛·4·1 # 𝑛+ 𝑛·4·3 := 𝑛·4·1 # 𝕄(𝑛·4·2)
@@ -0,0 +1,80 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The synonym of '--acyclic=plausible' lets the walk enter a binding of an+# object of the world in the first copy it meets and leave it as written in+# every later one (#1480). A body reading ξ reads the copy it stands in, and+# two copies filling 'v' with different numbers make two different programs of+# the φ of 'dbl', so that φ is walked in every copy and 'L_twice' fires under+# 'a' and under 'b', each with a symbol of its own (#1485).+symbolic: |+ - λ: L_id+ morph:+ 𝑛1: $.x+ 𝑛: 𝑛1+ - λ: L_twice+ dataize:+ 𝛿1: $.ρ+ 𝑛: Φ.num( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+deep: true+partial: true+acyclic: plausible+steps: 32+input: >+ ⟦ num ↦ ⟦ φ ↦ ∅, twice ↦ ⟦ ρ ↦ ∅, λ ⤍ L_twice ⟧ ⟧,+ dbl ↦ ⟦ v ↦ ∅, φ ↦ ξ.v.twice ⟧,+ a ↦ ⟦ λ ⤍ L_id, x ↦ Φ.dbl( v ↦ Φ.num( φ ↦ ⟦ Δ ⤍ 2A- ⟧ ) ) ⟧,+ b ↦ ⟦ λ ⤍ L_id, x ↦ Φ.dbl( v ↦ Φ.num( φ ↦ ⟦ Δ ⤍ 2B- ⟧ ) ) ⟧ ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.a):+ 𝕄(Φ.a.x):+ 𝑛·0·1 := Φ.num( φ ↦ 2A-:Δ )+ 𝑛·0·2 := Φ.dbl( v ↦ 𝑛·0·1 )+ 𝔼(L_id):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.dbl( v ↦ 𝑛·0·1 )+ 𝕄(Φ.a🌵0.v):+ 𝑛·1·2 := Φ.num( φ ↦ 2A-:Δ )+ 𝕄(Φ.a🌵0.φ):+ 𝑛·1·3 := Φ.num( φ ↦ 2A-:Δ )+ 𝑛·1·4 := Φ.num( φ ↦ 2A-:Δ )+ 𝔼(L_twice):+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·2·1 := Φ.num( φ ↦ 2A-:Δ )+ 𝛿·2·1 := 2A-+ 𝛿1·2 := 𝛿·2·1 # 𝔻(ξ.ρ)+ 𝑛·2·2 := Φ.num( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·2·2):+ 𝑛·2·3 := Φ.num( φ ↦ 𝜎1:λ )+ 𝑛·2·4 := 𝑛·2·3 # 𝕄(𝑛·2·2)+ 𝑛1·1 := 𝑛·1·1 # 𝕄(ξ.x)+ 𝑛·1·5 := 𝑛1·1 # 𝑛+ 𝑛·1·6 := 𝑛1·1 # 𝕄(𝑛·1·5)+ 𝕄(Φ.b):+ 𝕄(Φ.b.x):+ 𝑛·0·3 := Φ.num( φ ↦ 2B-:Δ )+ 𝑛·0·4 := Φ.dbl( v ↦ 𝑛·0·3 )+ 𝔼(L_id):+ 𝕄(Φ.a🌵2):+ 𝑛·3·1 := Φ.dbl( v ↦ 𝑛·0·3 )+ 𝕄(Φ.a🌵2.v):+ 𝑛·3·2 := Φ.num( φ ↦ 2B-:Δ )+ 𝕄(Φ.a🌵2.φ):+ 𝑛·3·3 := Φ.num( φ ↦ 2B-:Δ )+ 𝑛·3·4 := Φ.num( φ ↦ 2B-:Δ )+ 𝔼(L_twice):+ 𝔻(Φ.a🌵3):+ 𝕄(Φ.a🌵3):+ 𝑛·4·1 := Φ.num( φ ↦ 2B-:Δ )+ 𝛿·4·1 := 2B-+ 𝛿1·4 := 𝛿·4·1 # 𝔻(ξ.ρ)+ 𝑛·4·2 := Φ.num( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·4·2):+ 𝑛·4·3 := Φ.num( φ ↦ 𝜎2:λ )+ 𝑛·4·4 := 𝑛·4·3 # 𝕄(𝑛·4·2)+ 𝑛1·3 := 𝑛·3·1 # 𝕄(ξ.x)+ 𝑛·3·5 := 𝑛1·3 # 𝑛+ 𝑛·3·6 := 𝑛1·3 # 𝕄(𝑛·3·5)
@@ -0,0 +1,24 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A deep walk under '_partial': the binding stuck on a λ function no entry+# answers is left as it is, and the walk goes on to the binding after it+# instead of giving the whole run up.+symbolic: |+ - λ: L_answers+ 𝑛: ⟦ foo ↦ ⟦⟧, λ ⤍ 𝜎 ⟧+location: 'Q'+deep: true+partial: true+input: >+ ⟦ x ↦ ⟦ λ ⤍ L_none, ρ ↦ ∅ ⟧.foo,+ y ↦ ⟦ λ ⤍ L_answers, ρ ↦ ∅ ⟧.foo ⟧+result: '⟦ x ↦ L_none:λ.foo, y ↦ L_answers:λ.foo ⟧'+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.x):+ unanswered(L_none) # 𝕄(L_none:λ)+ 𝕄(Φ.y):+ 𝔼(L_answers):+ 𝑛·1·1 := ⟦ foo ↦ ⟦⟧, λ ⤍ 𝜎1 ⟧ # 𝑛+ 𝑛·1·2 := ⟦ foo ↦ ⟦⟧, λ ⤍ 𝜎1 ⟧ # 𝕄(𝑛·1·1)
@@ -0,0 +1,36 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A firing the deep walk opened and could not make: the entry of 'L_root'+# dataizes what it was applied to, that operand never comes down to data, and+# the firing is parked the way a term 𝕄 could not reduce is. The walk goes on+# to the binding after it instead of ending the whole run, so one argument+# nothing can dataize taints its own binding and nothing else (#1288).+symbolic: |+ - λ: L_root+ dataize:+ 𝛿1: $.v+ 𝑛: ⟦ ⟧+location: 'Q'+deep: true+partial: true+input: >+ ⟦ root(v) ↦ ⟦ λ ⤍ L_root ⟧,+ e1 ↦ Φ.root( ⟦ λ ⤍ L_none ⟧.foo ),+ e2 ↦ Φ.root( ⟦ λ ⤍ 𝜎1 ⟧ ) ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.e1):+ unanswered(L_none) # 𝕄(L_none:λ)+ 𝑛·0·1 := Φ.root( v ↦ L_none:λ.foo )+ 𝔼(L_root):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ unanswered(L_none) # 𝕄(L_none:λ)+ stuck(L_none)+ 𝕄(Φ.e2):+ 𝑛·0·2 := Φ.root( v ↦ 𝜎1:λ )+ 𝔼(L_root):+ 𝛿1·2 := 𝔻(𝜎1:λ) # 𝔻(ξ.v)+ 𝑛·2·1 := ⟦⟧ # 𝑛+ 𝑛·2·2 := ⟦⟧ # 𝕄(𝑛·2·1)
@@ -0,0 +1,30 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A name of the protocol stands for the very term it was given to and for no+# other. A 'symbolize' line stands the data of a term into unknowns without+# touching what the term carries first, so the copy it binds and the term it+# was made of open with the same 𝜎 and differ further down — here 𝑛1 carries+# '02-' under φ where 𝑛2 carries the symbol that datum was stood into — under+# φ, since the value of a term is reached where its φ chain ends and a datum+# standing anywhere else is left alone (#1293). The+# line of 𝑛2 writes the term out, since naming it after 𝑛1 would say nothing+# was replaced on the very line that replaced something, while the '𝔻(…) == …'+# above it says something was (#1292).+symbolic: |+ - λ: L_stand+ morph:+ 𝑛1: $.b+ symbolize:+ 𝑛2: 𝑛1+ 𝑛: ⟦ l ↦ 𝑛2 ⟧+location: 'Q.y'+input: '⟦ y ↦ ⟦ b ↦ ⟦ λ ⤍ 𝜎7, φ ↦ ⟦ Δ ⤍ 02- ⟧ ⟧, λ ⤍ L_stand ⟧.l ⟧'+protocol: |+ 𝕄(Φ.y):+ 𝔼(L_stand):+ 𝑛1·1 := ⟦ λ ⤍ 𝜎7, φ ↦ 02-:Δ ⟧ # 𝕄(ξ.b)+ 𝔻(𝜎8:λ) == 02-+ 𝑛2·1 := ⟦ λ ⤍ 𝜎7, φ ↦ 𝜎8:λ ⟧ # 𝑛1+ 𝑛·1·1 := ⟦ λ ⤍ 𝜎7, φ ↦ 𝜎8:λ ⟧:l # 𝑛+ 𝑛·1·2 := ⟦ λ ⤍ 𝜎7, φ ↦ 𝜎8:λ ⟧:l # 𝕄(𝑛·1·1)
@@ -0,0 +1,77 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+# The site a firing is written under, which the '--deep' walk refines as it+# enters a binding: both firings are of the same entry and answer the same way,+# so the locator standing beside them is the one thing telling a reader which+# part of the program each of them belongs to. A locator reaches a binding and+# no further: the λ function of the first one fires on a dispatch standing+# inside 'mark', which no locator names, so the firing is written under+# 'Φ.foo.mark' — the binding the walk had entered.+symbolic: |+ - λ: L_number_plus+ dataize:+ 𝛿1: $.ρ+ 𝛿2: $.x+ 𝑛: Φ.number( φ ↦ ⟦ λ ⤍ 𝜎 ⟧ )+location: 'Q'+deep: true+input: >+ ⟦ bytes(φ) ↦ ⟦⟧,+ number(φ) ↦ ⟦ plus(ρ, x) ↦ ⟦ λ ⤍ L_number_plus ⟧ ⟧,+ foo ↦ ⟦ mark ↦ 5.plus( 6 ) ⟧,+ bar ↦ 7.plus( 8 ) ⟧+protocol: |+ 𝕄(Φ):+ 𝕄(Φ.foo):+ 𝕄(Φ.foo.mark):+ 𝑛·0·1 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝑛·0·2 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·0·3 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·0·4 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝑛·0·5 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝑛·0·6 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·0·7 := 𝑛·0·6.plus( x ↦ 𝑛·0·5 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵0):+ 𝕄(Φ.a🌵0):+ 𝑛·1·1 := Φ.number( φ ↦ 𝑛·0·1 )+ 𝑛·1·2 := Φ.bytes( φ ↦ 40-14-00-00-00-00-00-00:Δ )+ 𝛿·1·1 := 40-14-00-00-00-00-00-00 # 5.0+ 𝛿1·1 := 𝛿·1·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵1):+ 𝕄(Φ.a🌵1):+ 𝑛·1·3 := Φ.number( φ ↦ 𝑛·0·4 )+ 𝑛·1·4 := Φ.bytes( φ ↦ 40-18-00-00-00-00-00-00:Δ )+ 𝛿·1·2 := 40-18-00-00-00-00-00-00 # 6.0+ 𝛿2·1 := 𝛿·1·2 # 𝔻(ξ.x)+ 𝑛·1·5 := Φ.number( φ ↦ 𝜎1:λ ) # 𝑛+ 𝕄(𝑛·1·5):+ 𝑛·1·6 := Φ.number( φ ↦ 𝜎1:λ )+ 𝑛·1·7 := 𝑛·1·6 # 𝕄(𝑛·1·5)+ 𝕄(Φ.bar):+ 𝑛·0·8 := Φ.bytes( φ ↦ 40-1C-00-00-00-00-00-00:Δ )+ 𝑛·0·9 := Φ.number( φ ↦ 𝑛·0·8 )+ 𝑛·0·10 := Φ.number( φ ↦ 𝑛·0·8 )+ 𝑛·0·11 := Φ.bytes( φ ↦ 40-20-00-00-00-00-00-00:Δ )+ 𝑛·0·12 := Φ.number( φ ↦ 𝑛·0·11 )+ 𝑛·0·13 := Φ.number( φ ↦ 𝑛·0·8 )+ 𝑛·0·14 := 𝑛·0·13.plus( x ↦ 𝑛·0·12 )+ 𝔼(L_number_plus):+ 𝔻(Φ.a🌵2):+ 𝕄(Φ.a🌵2):+ 𝑛·2·1 := Φ.number( φ ↦ 𝑛·0·8 )+ 𝑛·2·2 := Φ.bytes( φ ↦ 40-1C-00-00-00-00-00-00:Δ )+ 𝛿·2·1 := 40-1C-00-00-00-00-00-00 # 7.0+ 𝛿1·2 := 𝛿·2·1 # 𝔻(ξ.ρ)+ 𝔻(Φ.a🌵3):+ 𝕄(Φ.a🌵3):+ 𝑛·2·3 := Φ.number( φ ↦ 𝑛·0·11 )+ 𝑛·2·4 := Φ.bytes( φ ↦ 40-20-00-00-00-00-00-00:Δ )+ 𝛿·2·2 := 40-20-00-00-00-00-00-00 # 8.0+ 𝛿2·2 := 𝛿·2·2 # 𝔻(ξ.x)+ 𝑛·2·5 := Φ.number( φ ↦ 𝜎2:λ ) # 𝑛+ 𝕄(𝑛·2·5):+ 𝑛·2·6 := Φ.number( φ ↦ 𝜎2:λ )+ 𝑛·2·7 := 𝑛·2·6 # 𝕄(𝑛·2·5)
@@ -0,0 +1,11 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoContextualizationInference}+ \phinoName{ca}+ \phinoPremise{ \phinoContextualize{ n_1 }{ k }{ n_2 } }+ \phinoPremise{ \phinoContextualize{ e }{ k }{ n_3 } }+ \phinoConclusion{ \phinoContextualize{ n_1 ( \tau -> e ) }{ k }{ n_2 ( \tau -> n_3 ) } }+ \end{phinoContextualizationInference}
@@ -0,0 +1,11 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoContextualizationInference}+ \phinoName{caa}+ \phinoPremise{ \phinoContextualize{ n_1 }{ k }{ n_2 } }+ \phinoPremise{ \phinoContextualize{ e }{ k }{ n_3 } }+ \phinoConclusion{ \phinoContextualize{ n_1 ( \phiTerminal{\alpha_{i}} -> e ) }{ k }{ n_2 ( \phiTerminal{\alpha_{i}} -> n_3 ) } }+ \end{phinoContextualizationInference}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoContextualizationInference}+ \phinoName{cd}+ \phinoPremise{ \phinoContextualize{ n_1 }{ k }{ n_2 } }+ \phinoConclusion{ \phinoContextualize{ n_1 . \tau }{ k }{ n_2 . \tau } }+ \end{phinoContextualizationInference}
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoContextualizationInference}+ \phinoName{cf}+ \phinoConclusion{ \phinoContextualize{ [[ B ]] }{ k }{ [[ B ]] } }+ \end{phinoContextualizationInference}
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoContextualizationInference}+ \phinoName{cg}+ \phinoConclusion{ \phinoContextualize{ Q }{ k }{ Q } }+ \end{phinoContextualizationInference}
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoContextualizationInference}+ \phinoName{ct}+ \phinoConclusion{ \phinoContextualize{ T }{ k }{ T } }+ \end{phinoContextualizationInference}
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoContextualizationInference}+ \phinoName{cxi}+ \phinoConclusion{ \phinoContextualize{ \phiTerminal{\xi} }{ k }{ k } }+ \end{phinoContextualizationInference}
@@ -0,0 +1,13 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoDataizationInference}+ \phinoName{box}+ \phinoCondition{ [ D \char44{} L ] \cap \lparen B_1 \cup B_2 \rparen = \emptyset }+ \phinoPremise{ \phinoContextualize{ e_2 }{ [[ B_1, @ -> e_2, B_2 ]] }{ e_3 } }+ \phinoPremise{ \phinoNormalize{ e_3 }{ n } }+ \phinoPremise{ \phinoDataize{ n }{ e_1 }{ s_1 }{ \delta }{ s_2 } }+ \phinoConclusion{ \phinoDataize{ [[ B_1, @ -> e_2, B_2 ]] }{ e_1 }{ s_1 }{ \delta }{ s_2 } }+ \end{phinoDataizationInference}
@@ -0,0 +1,11 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoDataizationInference}+ \phinoName{delta}+ \phinoLabel{\Delta}+ \phinoCondition{ [ L ] \cap \lparen B_1 \cup B_2 \rparen = \emptyset }+ \phinoConclusion{ \phinoDataize{ [[ B_1, D> \delta, B_2 ]] }{ e }{ s }{ \delta }{ s } }+ \end{phinoDataizationInference}
@@ -0,0 +1,12 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoDataizationInference}+ \phinoName{fire}+ \phinoCondition{ [ D ] \cap \lparen B_1 \cup B_2 \rparen = \emptyset }+ \phinoPremise{ \phinoEvaluate{ [[ B_1, L> f, B_2 ]] }{ e }{ s_1 }{ n }{ s_2 } }+ \phinoPremise{ \phinoDataize{ n }{ e }{ s_2 }{ \delta }{ s_3 } }+ \phinoConclusion{ \phinoDataize{ [[ B_1, L> f, B_2 ]] }{ e }{ s_1 }{ \delta }{ s_3 } }+ \end{phinoDataizationInference}
@@ -0,0 +1,11 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoDataizationInference}+ \phinoName{none}+ \phinoCondition{ [ D \char44{} L \char44{} @ ] \cap B = \emptyset }+ \phinoPremise{ \phinoDataize{ T }{ e }{ s_1 }{ \delta }{ s_2 } }+ \phinoConclusion{ \phinoDataize{ [[ B ]] }{ e }{ s_1 }{ \delta }{ s_2 } }+ \end{phinoDataizationInference}
@@ -0,0 +1,12 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoDataizationInference}+ \phinoName{norm}+ \phinoCondition{ \phinoNotFormation{ n_1 } \phiText{and} n_1 \not= T }+ \phinoPremise{ \phinoMorph{ n_1 }{ e }{ s_1 }{ n_2 }{ s_2 } }+ \phinoPremise{ \phinoDataize{ n_2 }{ e }{ s_2 }{ \delta }{ s_3 } }+ \phinoConclusion{ \phinoDataize{ n_1 }{ e }{ s_1 }{ \delta }{ s_3 } }+ \end{phinoDataizationInference}
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoMorphingInference}+ \phinoName{dead}+ \phinoConclusion{ \phinoMorph{ T }{ e }{ s }{ T }{ s } }+ \end{phinoMorphingInference}
@@ -0,0 +1,12 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoMorphingInference}+ \phinoName{ma}+ \phinoPremise{ \phinoMorph{ n_1 }{ e }{ s_1 }{ n_2 }{ s_2 } }+ \phinoPremise{ \phinoNormalize{ n_2 ( \tau -> k ) }{ n_3 } }+ \phinoPremise{ \phinoMorph{ n_3 }{ e }{ s_2 }{ n_4 }{ s_3 } }+ \phinoConclusion{ \phinoMorph{ n_1 ( \tau -> k ) }{ e }{ s_1 }{ n_4 }{ s_3 } }+ \end{phinoMorphingInference}
@@ -0,0 +1,12 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoMorphingInference}+ \phinoName{maa}+ \phinoPremise{ \phinoMorph{ n_1 }{ e }{ s_1 }{ n_2 }{ s_2 } }+ \phinoPremise{ \phinoNormalize{ n_2 ( \phiTerminal{\alpha_{i}} -> k ) }{ n_3 } }+ \phinoPremise{ \phinoMorph{ n_3 }{ e }{ s_2 }{ n_4 }{ s_3 } }+ \phinoConclusion{ \phinoMorph{ n_1 ( \phiTerminal{\alpha_{i}} -> k ) }{ e }{ s_1 }{ n_4 }{ s_3 } }+ \end{phinoMorphingInference}
@@ -0,0 +1,11 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoMorphingInference}+ \phinoName{maad}+ \phinoCondition{ \phinoNotAbsolute{ n_1 } }+ \phinoPremise{ \phinoMorph{ T }{ e }{ s_1 }{ n_2 }{ s_2 } }+ \phinoConclusion{ \phinoMorph{ n ( \phiTerminal{\alpha_{i}} -> n_1 ) }{ e }{ s_1 }{ n_2 }{ s_2 } }+ \end{phinoMorphingInference}
@@ -0,0 +1,11 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoMorphingInference}+ \phinoName{mad}+ \phinoCondition{ \phinoNotAbsolute{ n_1 } }+ \phinoPremise{ \phinoMorph{ T }{ e }{ s_1 }{ n_2 }{ s_2 } }+ \phinoConclusion{ \phinoMorph{ n ( \tau -> n_1 ) }{ e }{ s_1 }{ n_2 }{ s_2 } }+ \end{phinoMorphingInference}
@@ -0,0 +1,13 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoMorphingInference}+ \phinoName{md}+ \phinoCondition{ \phinoNotFormation{ n_1 } }+ \phinoPremise{ \phinoMorph{ n_1 }{ e }{ s_1 }{ n_2 }{ s_2 } }+ \phinoPremise{ \phinoNormalize{ n_2 . \tau }{ n_3 } }+ \phinoPremise{ \phinoMorph{ n_3 }{ e }{ s_2 }{ n_4 }{ s_3 } }+ \phinoConclusion{ \phinoMorph{ n_1 . \tau }{ e }{ s_1 }{ n_4 }{ s_3 } }+ \end{phinoMorphingInference}
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoMorphingInference}+ \phinoName{mf}+ \phinoConclusion{ \phinoMorph{ [[ B ]] }{ e }{ s }{ [[ B ]] }{ s } }+ \end{phinoMorphingInference}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoMorphingInference}+ \phinoName{mg}+ \phinoPremise{ \phinoMorph{ T }{ Q }{ s_1 }{ n }{ s_2 } }+ \phinoConclusion{ \phinoMorph{ Q }{ Q }{ s_1 }{ n }{ s_2 } }+ \end{phinoMorphingInference}
@@ -0,0 +1,13 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoMorphingInference}+ \phinoName{ml}+ \phinoLabel{\lambda}+ \phinoPremise{ \phinoEvaluate{ [[ B_1, L> f, B_2 ]] }{ e }{ s_1 }{ n_1 }{ s_2 } }+ \phinoPremise{ \phinoNormalize{ n_1 . \tau }{ n_2 } }+ \phinoPremise{ \phinoMorph{ n_2 }{ e }{ s_2 }{ n_3 }{ s_3 } }+ \phinoConclusion{ \phinoMorph{ [[ B_1, L> f, B_2 ]] . \tau }{ e }{ s_1 }{ n_3 }{ s_3 } }+ \end{phinoMorphingInference}
@@ -0,0 +1,13 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoMorphingInference}+ \phinoName{mphi}+ \phinoLabel{\varphi}+ \phinoCondition{ @ \in B \phiText{and} [ \tau \char44{} L ] \cap B = \emptyset }+ \phinoPremise{ \phinoNormalize{ [[ B ]] . @ . \tau }{ n_1 } }+ \phinoPremise{ \phinoMorph{ n_1 }{ e }{ s_1 }{ n_2 }{ s_2 } }+ \phinoConclusion{ \phinoMorph{ [[ B ]] . \tau }{ e }{ s_1 }{ n_2 }{ s_2 } }+ \end{phinoMorphingInference}
@@ -0,0 +1,13 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoMorphingInference}+ \phinoName{universe}+ \phinoLabel{\Phi}+ \phinoCondition{ e \not= Q }+ \phinoPremise{ \phinoNormalize{ e }{ n_1 } }+ \phinoPremise{ \phinoMorph{ n_1 }{ e }{ s_1 }{ n_2 }{ s_2 } }+ \phinoConclusion{ \phinoMorph{ Q }{ e }{ s_1 }{ n_2 }{ s_2 } }+ \end{phinoMorphingInference}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \begin{phinoMorphingInference}+ \phinoName{xi}+ \phinoPremise{ \phinoMorph{ T }{ e }{ s_1 }{ n }{ s_2 } }+ \phinoConclusion{ \phinoMorph{ \phiTerminal{\xi} }{ e }{ s_1 }{ n }{ s_2 } }+ \end{phinoMorphingInference}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{alpha}+ { [[ B_1, \tau -> ?, B_2 ]] ( \phiTerminal{\alpha_{i}} -> e ) }+ { [[ B_1, \tau -> ?, B_2 ]] ( \tau -> e ) }+ { i = \vert \overline{ B_1 } \vert \phiText{and} \tau \not= \phiTerminal{\rho} }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{amiss}+ { [[ B ]] ( \phiTerminal{\alpha_{i}} -> e ) }+ { T }+ { \vert \overline{ B } \vert \leq i }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{copy}+ { [[ B_1, \tau -> ?, B_2 ]] ( \tau -> k ) }+ { [[ B_1, \tau -> k, B_2 ]] }+ { }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{dc}+ { T ( \tau -> e ) }+ { T }+ { }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{dca}+ { T ( \phiTerminal{\alpha_{i}} -> e ) }+ { T }+ { }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{dd}+ { T . \tau }+ { T }+ { }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{dl}+ { [[ B_1, L> f, B_2 ]] }+ { T }+ { D \in \lparen B_1 \cup B_2 \rparen }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{dot}+ { [[ B_1, \tau -> n, B_2 ]] . \tau }+ { e_1 ( \phiTerminal{\rho} -> e_2 ) }+ { [ D \char44{} L ] \not\subseteq \lparen B_1 \cup B_2 \rparen }+ { \phinoContextualize{ n }{ [[ B_1, B_2 ]] }{ e_1 } \phiText{and} \phinoNamed{ e_2 }{ [[ B_1, \tau -> n, B_2 ]] } }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{miss}+ { [[ B ]] ( \tau -> e ) }+ { T }+ { \tau \notin B \phiText{and} \tau \not= \phiTerminal{\rho} }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{norho}+ { [[ B ]] . \phiTerminal{\rho} }+ { T }+ { \phiTerminal{\rho} \notin B }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{null}+ { [[ B_1, \tau -> ?, B_2 ]] . \tau }+ { T }+ { }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{over}+ { [[ B_1, \tau -> e_1, B_2 ]] ( \tau -> e_2 ) }+ { T }+ { \tau \not= \phiTerminal{\rho} }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{overa}+ { [[ B_1, \tau -> e_1, B_2 ]] ( \phiTerminal{\alpha_{i}} -> e_2 ) }+ { T }+ { i = \vert \overline{ B_1 } \vert \phiText{and} \tau \not= \phiTerminal{\rho} }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{skip}+ { [[ B ]] ( \phiTerminal{\rho} -> e ) }+ { [[ B ]] }+ { \phiTerminal{\rho} \notin B }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{stay}+ { [[ B_1, \phiTerminal{\rho} -> e_1, B_2 ]] ( \phiTerminal{\rho} -> e_2 ) }+ { [[ B_1, \phiTerminal{\rho} -> e_1, B_2 ]] }+ { }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+latex: |-+ \phinoNormalizationRule{stop}+ { [[ B ]] . \tau }+ { T }+ { [ \tau \char44{} @ \char44{} L ] \cap B = \emptyset }+ { }
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: |+ [[+ org -> [[ eolang -> [[ number -> [[]], bytes -> [[ ]] ]] ]], some -> Q+ ]]+hidden: ['Q.org']+shown: []+result: 'Φ:some'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ org -> [[ eolang -> [[]] ]] ]]'+hidden: ['Q.org.eolang']+shown: []+result: '⟦⟧:org'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+expression: '[[ org -> [[ eolang -> [[ number -> [[ ]], bytes -> [[ ]], string -> [[ ]] ]] ]], xyz -> [[ ]] ]]'+shown: ['Q.org.eolang']+hidden: ['Q.org.eolang.bytes', 'Q.org.eolang.string']+result: '⟦⟧:number:eolang:org'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+expression: '[[ org -> [[ eolang -> [[ number -> [[ ]], bytes -> [[ ]], string -> [[ ]] ]] ]], xyz -> [[ abc -> [[ ]] ]] ]]'+shown: ['Q.org.eolang.number']+hidden: []+result: '⟦⟧:number:eolang:org'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '[[ org -> Q.x ]]'+hidden: ['Q.org']+shown: []+result: '⟦⟧'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: '[[ t -> [[ xi🌵 -> ?, q -> ?, a -> ?, x -> [[ ]], k -> [[ xi🌵 -> ? ]] ]] ]]'+hidden: ['Q.t.k.xi🌵']+shown: []+result: '⟦ t(xi🌵, q, a) ↦ ⟦ x ↦ ⟦⟧, k ↦ ⟦⟧ ⟧ ⟧'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+expression: '⟦ order ↦ ⟦ qty ↦ ∅, json ↦ ⟦ xi🌵 ↦ ξ ⟧ ⟧ ⟧'+hidden: ['Q.order.json.xi🌵']+shown: []+result: '⟦ order(qty) ↦ ⟦ json ↦ ⟦⟧ ⟧ ⟧'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ @ -> Q.x, y -> [[ D> 01-02 ]] ]]+result: |-+ \begin{phiquation}+ [[ @ -> Q . |x|, |y| -> |01-02| : D ]]{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ Q.x.y.z+result: |-+ \begin{phiquation}+ Q . |x| . |y| . |z|{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ my_attr -> Q.a@b ]]+result: |-+ \begin{phiquation}+ Q . |a\char64{}b| : |my\char95{}attr|{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x -> "a_b $c% &d #e ^g {h} @i ~j \\k" ]]+result: |-+ \begin{phiquation}+ "a\char95{}b \char36{}c\char37{} \char38{}d \char35{}e \char94{}g \char123{}h\char125{} \char64{}i \char126{}j \char92{}\char92{}k" : |x|{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ foo(a, b) -> [[ @ -> $.a ]] ]]+result: |-+ \begin{phiquation}+ [[ |foo|(|a|, |b|) -> |a| : @ ]]{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x -> 3.14, y -> -2.5 ]]+result: |-+ \begin{phiquation}+ [[ |x| -> |3.14|, |y| -> |-2.5| ]]{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ L> Fn_plus, x -> ? ]]+result: |-+ \begin{phiquation}+ [[ L> |Fn\char95{}plus|, |x| -> ? ]]{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ f -> Q.foo(x -> Q.a, y -> $) ]]+result: |-+ \begin{phiquation}+ Q . |foo| ( |x| -> Q . |a|, |y| -> \phiTerminal{\xi} ) : |f|{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ t🌵1 -> Q ]]+result: |-+ \begin{phiquation}+ Q : |t[U+1F335]1|{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x -> [[ y -> 42 ]] ]]+result: |-+ \begin{phiquation}+ |42| : |y| : |x|{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ nameφ -> Q ]]+result: |-+ \begin{phiquation}+ Q : |name\phiTerminal{\varphi}|{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ f -> Q.foo(Q.a, Q.b) ]]+result: |-+ \begin{phiquation}+ Q . |foo| ( Q . |a|, Q . |b| ) : |f|{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ n -> 42, s -> "hello" ]]+result: |-+ \begin{phiquation}+ [[ |n| -> |42|, |s| -> "hello" ]]{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ [[ x -> $.^.y, z -> $.w ]]+result: |-+ \begin{phiquation}+ [[ |x| -> \phiTerminal{\rho} . |y|, |z| -> |w| ]]{.}+ \end{phiquation}
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+# yamllint disable rule:line-length+---+expression: |+ T+result: |-+ \begin{phiquation}+ T{.}+ \end{phiquation}
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ ]]'+right: '[[ x -> 1 ]]'+result: '1:x'
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ x -> 1 ]]'+right: '[[ x -> 1 ]]'+result: '1:x'
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ D> 42-, x -> [[ ]] ]]'+right: '[[ D> 42-, y -> [[ ]] ]]'+result: '⟦ Δ ⤍ 42-, x ↦ ⟦⟧, y ↦ ⟦⟧ ⟧'
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ x -> ? ]]'+right: '[[ x -> ? ]]'+result: '∅:x'
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ bytes -> [[ @ -> ?, ^ -> ? ]] ]]'+right: |+ [[ bytes -> [[+ as-bytes -> [[ ^ -> ?, @ -> $.^ ]], L> Package, ^ -> ?+ ]] ]]+result: '⟦ bytes(φ) ↦ ⟦ as-bytes(ρ) ↦ ρ:φ, ρ ↦ ∅ ⟧ ⟧'
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: |+ [[ bytes -> [[+ as-bytes -> [[ ^ -> ?, @ -> $.^ ]], L> Package, ^ -> ?+ ]] ]]+right: '[[ bytes -> [[ @ -> ?, ^ -> ? ]] ]]'+result: '⟦ as-bytes(ρ) ↦ ρ:φ, φ ↦ ∅, ρ ↦ ∅ ⟧:bytes'
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ x -> [[ y -> Q ]] ]]'+right: '[[ x -> [[ y -> $ ]] ]]'+fails: "Can't merge two bindings, conflict found"
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ x -> [[ ]] ]]'+right: '[[ x -> Q ]]'+fails: "Can't merge two bindings, conflict found"
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: 'Q'+right: '$'+fails: 'Invalid expression format'
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ x -> ? ]]'+right: '[[ x -> 1 ]]'+fails: "Can't merge two bindings, conflict found"
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ D> 42- ]]'+right: '[[ D> 13- ]]'+fails: "Can't merge two bindings, conflict found"
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ L> Atom ]]'+right: '[[ L> Other ]]'+fails: "Can't merge two bindings, conflict found"
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ x -> 1 ]]'+right: '[[ x -> 2 ]]'+fails: "Can't merge two bindings, conflict found"
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ f -> [[ x -> ?, y -> ?, @ -> $.x ]] ]]'+right: '[[ f -> [[ x -> ? ]] ]]'+result: '⟦ f ↦ ⟦ x ↦ ∅, y ↦ ∅, φ ↦ ξ.x ⟧ ⟧'
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ f -> [[ x -> ? ]] ]]'+right: '[[ f -> [[ x -> ?, y -> ?, @ -> $.x ]] ]]'+result: '⟦ f ↦ ⟦ x ↦ ∅, y ↦ ∅, φ ↦ ξ.x ⟧ ⟧'
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ org -> [[ number -> [[ ]], L> Package, ^ -> ? ]] ]]'+right: '[[ org -> [[ text -> [[ ]], L> Package, ^ -> ? ]] ]]'+result: '⟦ number ↦ ⟦⟧, text ↦ ⟦⟧, λ ⤍ Package, ρ ↦ ∅ ⟧:org'
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ f -> [[ y -> ? ]] ]]'+right: '[[ f -> [[ x -> ?, y -> ? ]] ]]'+result: '⟦ f ↦ ⟦ x ↦ ∅, y ↦ ∅ ⟧ ⟧'
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ a -> 1, k -> [[ p -> 1 ]] ]]'+right: '[[ b -> 2, k -> [[ q -> 2 ]] ]]'+result: '⟦ a ↦ 1, b ↦ 2, k ↦ ⟦ p ↦ 1, q ↦ 2 ⟧ ⟧'
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ x -> 1 ]]'+right: '[[ y -> 2 ]]'+result: '⟦ x ↦ 1, y ↦ 2 ⟧'
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ x -> [[ y -> 1 ]] ]]'+right: '[[ x -> [[ z -> 2 ]] ]]'+result: '⟦ y ↦ 1, z ↦ 2 ⟧:x'
@@ -0,0 +1,6 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+left: '[[ org -> [[ eolang -> [[ number -> [[ ]] ]] ]] ]]'+right: '[[ org -> [[ eolang -> [[ bytes -> [[ ]] ]] ]] ]]'+result: '⟦ number ↦ ⟦⟧, bytes ↦ ⟦⟧ ⟧:eolang:org'
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The same shape with nothing around the unapplied formation: the ⊥ still+# fills the only void of 'plus', so 'saturated' would let it fire (#1196).+location: 'Q.@'+model: true+symbolic: true+input: '[[ a -> [[ @ -> 5.plus( $.^ ) ]] ]]'+result: '5.plus( ρ ):φ:a'
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# An atom deeper on a binding's spine gets stuck exactly as it does under 𝕄+# alone: the run fails, unless '_partial' parks it.+input: '[[ x -> [[ L> Sym_arg_0 ]].foo ]]'+fails: "No entry of --symbolic answers the λ function 'Sym_arg_0'"
@@ -0,0 +1,20 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The λ function nested in the argument fires before the one around it, so+# the symbol standing for the whole sum is the second the run minted.+location: 'Q.@'+model: true+symbolic: true+input: '[[ x -> 5.plus( 6.plus( 7 ) ) ]]'+result: |-+ ⟦+ φ ↦ 𝜎2:λ,+ as-bytes ↦ φ,+ plus(ρ, x) ↦ L_number_plus:λ,+ times(ρ, x) ↦ L_number_times:λ,+ div(ρ, x) ↦ L_number_div:λ,+ gt(ρ, x) ↦ L_number_gt:λ,+ eq(ρ, x) ↦ ρ.as-bytes.eq( x.as-bytes ):φ,+ nope(ρ) ↦ L_number_nope:λ+ ⟧:x
@@ -0,0 +1,20 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# Two firings down a chain of dispatches, and what stands is the symbol the+# last of them minted: the first is what the second brought down.+location: 'Q.@'+model: true+symbolic: true+input: '[[ x -> 5.plus( 6 ).plus( 7 ) ]]'+result: |-+ ⟦+ φ ↦ 𝜎2:λ,+ as-bytes ↦ φ,+ plus(ρ, x) ↦ L_number_plus:λ,+ times(ρ, x) ↦ L_number_times:λ,+ div(ρ, x) ↦ L_number_div:λ,+ gt(ρ, x) ↦ L_number_gt:λ,+ eq(ρ, x) ↦ ρ.as-bytes.eq( x.as-bytes ):φ,+ nope(ρ) ↦ L_number_nope:λ+ ⟧:x
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# No entry of the file answers 'L_number_nope', so there is nothing to fire+# and the binding keeps the name it was written under.+location: 'Q.@'+model: true+symbolic: true+input: '[[ x -> 5.nope ]]'+result: '5.nope:x'
@@ -0,0 +1,13 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A λ-formation whose bindings are still void is a method waiting to be+# applied, not an application waiting to be computed: nothing demands one,+# so 𝔻 never meets one, while the walk meets every one the object model+# declares. Both the void ρ of 'not' and the void 'b' of 'eq' keep their+# atoms unfired here.+location: 'Q.bytes'+model: true+symbolic: true+input: '[[ ]]'+result: '⟦ φ ↦ ∅, not(ρ) ↦ L_bytes_not:λ, eq(ρ, b) ↦ L_bytes_eq:λ ⟧'
@@ -0,0 +1,12 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A formation standing unapplied inside its parent still holds ρ ↦ ∅, so the+# ξ.ρ its body reaches is an input the next dispatch supplies, not ⊥. The+# walk reduces that body in the formation's own scope, where ρ is void, and+# must not hand the ⊥ that comes back to the λ of 'plus' (#1196).+location: 'Q.@'+model: true+symbolic: true+input: '[[ foo -> [[ n -> ?, a -> [[ @ -> 5.plus( $.^ ) ]] ]] ]]'+result: '⟦ foo(n) ↦ 5.plus( ρ ):φ:a ⟧'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The same stuck atom under '_partial': the binding stays as it was written+# and the walk goes on.+partial: true+input: '[[ x -> [[ L> Sym_arg_0 ]].foo ]]'+result: 'Sym_arg_0:λ.foo:x'
@@ -0,0 +1,23 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The ξ of a binding reaches the formation the binding sits in, so 'n' is+# what the firing brings down, and a symbol stands where its answer belongs.+location: 'Q.@'+model: true+symbolic: true+input: '[[ n -> 5, x -> $.n.plus( 6 ) ]]'+result: |-+ ⟦+ n ↦ 5,+ x ↦ ⟦+ φ ↦ 𝜎1:λ,+ as-bytes ↦ φ,+ plus(ρ, x) ↦ L_number_plus:λ,+ times(ρ, x) ↦ L_number_times:λ,+ div(ρ, x) ↦ L_number_div:λ,+ gt(ρ, x) ↦ L_number_gt:λ,+ eq(ρ, x) ↦ ρ.as-bytes.eq( x.as-bytes ):φ,+ nope(ρ) ↦ L_number_nope:λ+ ⟧+ ⟧
@@ -0,0 +1,20 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# 'mf' hands a bare saturated λ-formation back and leaves firing it to 𝔻;+# the walk fires it and stands the symbol it answered with in its place.+location: 'Q.@'+model: true+symbolic: true+input: '[[ x -> 5.plus( 6 ) ]]'+result: |-+ ⟦+ φ ↦ 𝜎1:λ,+ as-bytes ↦ φ,+ plus(ρ, x) ↦ L_number_plus:λ,+ times(ρ, x) ↦ L_number_times:λ,+ div(ρ, x) ↦ L_number_div:λ,+ gt(ρ, x) ↦ L_number_gt:λ,+ eq(ρ, x) ↦ ρ.as-bytes.eq( x.as-bytes ):φ,+ nope(ρ) ↦ L_number_nope:λ+ ⟧:x
@@ -0,0 +1,22 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# Nothing demands the argument of a λ function that cannot fire, so 𝔻 never+# reaches it; the walk does, and the λ function around it stays in place.+location: 'Q.@'+model: true+symbolic: true+input: '[[ x -> [[ y -> ?, L> L_bar ]]( y -> 6.plus( 7 ) ) ]]'+result: |-+ ⟦ y ↦ ∅, λ ⤍ L_bar ⟧(+ y ↦ ⟦+ φ ↦ 𝜎1:λ,+ as-bytes ↦ φ,+ plus(ρ, x) ↦ L_number_plus:λ,+ times(ρ, x) ↦ L_number_times:λ,+ div(ρ, x) ↦ L_number_div:λ,+ gt(ρ, x) ↦ L_number_gt:λ,+ eq(ρ, x) ↦ ρ.as-bytes.eq( x.as-bytes ):φ,+ nope(ρ) ↦ L_number_nope:λ+ ⟧+ ):x
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A formation that declares no ρ has no receiver, so asking it for one is+# dead and does not go through its φ (#1859).+location: 'Q.x'+input: '[[ x -> [[ @ -> $.y, y -> [[ ]] ]].^ ]]'+result: '⊥'
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# 𝕄 is total where 𝔻 is not: the 'xi' axiom morphs ξ to ⊥, so the run ends+# with an answer rather than with a failure.+location: 'Q.x'+input: '[[ x -> $ ]]'+result: '⊥'
@@ -0,0 +1,34 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The 'normalize' premise of 'mphi' unrolls the loop of 'walk' one round per+# cycle, since the 'eq' deciding the 'if' is a λ the normalizer cannot answer,+# so it runs out of '--max-cycles'. The unfinished term is not a normal form+# and no morphing rule takes it, so the run names the budget it spent instead+# of failing because no morphing rule takes it (#1496).+location: 'Q.x'+input: |+ ⟦+ tuple(length, head, tail) ↦ ⟦ empty ↦ ⟦ ⟧ ⟧,+ map(pairs) ↦ ⟦+ φ ↦ ctor(+ entries ↦ pairs.length.eq( 0 ).if(+ Φ.tuple.empty,+ walk( tup ↦ pairs ).φ+ )+ ),+ ctor(entries) ↦ ⟦ keys ↦ entries ⟧,+ walk(ρ, tup) ↦ ⟦+ φ ↦ tup.length.eq( 0 ).if( Φ.tuple.empty, prev ),+ prev ↦ ρ.walk( tup ↦ tup.tail ).φ+ ⟧+ ⟧,+ x ↦ Φ.map(+ pairs ↦ Φ.tuple(+ length ↦ L_len:λ, head ↦ L_head:λ, tail ↦ L_tail:λ+ )+ ).keys+ ⟧+fails: >-+ Normalization did not finish before reaching the limit of cycles:+ --max-cycles=25
@@ -0,0 +1,8 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# 𝕄 never fires a bare λ-formation, so only an atom sitting under a dispatch+# (the 'ml' rule) can get stuck, and without '_partial' it fails the run.+location: 'Q.x'+input: '[[ x -> [[ L> Sym_arg_0 ]].foo ]]'+fails: "No entry of --symbolic answers the λ function 'Sym_arg_0'"
@@ -0,0 +1,12 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# 𝕄 maps normal forms to formations, and 'morph' does not normalize what it is+# handed. A dispatch off a formation with neither φ nor λ is not a normal form,+# since 'dot' of normalization eats it, and no morphing rule takes it, so the+# run tells the user so instead of failing with a bare "user error" (#1442).+location: 'Q.t'+input: '⟦ t ↦ ⟦ x ↦ ⟦⟧ ⟧.x ⟧'+fails: >-+ Morphing expects a normal form, but no morphing rule matches:+ ⟦⟧:x.x
@@ -0,0 +1,7 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The Q locator aims the run at the whole program, and a formation is already+# what 'mf' hands back.+input: '[[ D> 00- ]]'+result: '00-:Δ'
@@ -0,0 +1,13 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# An object nested in an object of the world is named by the whole path it is+# reached by: its ρ says which object it was dispatched off, so the name is+# found among the objects that one declares and nowhere else (#1446).+location: 'Q.t'+input: |+ ⟦+ a ↦ ⟦ ρ ↦ ∅, b ↦ ⟦ ρ ↦ ∅, c ↦ ⟦ ρ ↦ ∅ ⟧, d ↦ ⟦ Δ ⤍ 01- ⟧ ⟧ ⟧,+ t ↦ Φ.a.b.c+ ⟧+result: 'Φ.a.b:ρ'
@@ -0,0 +1,17 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A dispatch off a top-level object of the world decorates the body it reaches+# with the object it was dispatched on, and that object is 'Φ.number'. Writing+# it out would copy every method it declares into the term, 'sin' included,+# though only 'plus' is ever dispatched. The world is immutable, so the ρ+# carries the path instead, the way the whole world is written Φ, and whoever+# reads it resolves it to the very formation that would have stood there+# (#1446).+location: 'Q.t'+input: |+ ⟦+ number ↦ ⟦ φ ↦ ∅, plus ↦ ⟦ ρ ↦ ∅, x ↦ ∅ ⟧, sin ↦ ⟦ ρ ↦ ∅ ⟧ ⟧,+ t ↦ Φ.number.plus+ ⟧+result: '⟦ ρ ↦ Φ.number, x ↦ ∅ ⟧'
@@ -0,0 +1,14 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# An object of the world applied to an argument is still named, not copied:+# the formation 'Φ.number( φ ↦ … )' morphs to is 'number' with its void filled,+# so the ρ of a method dispatched off it carries the application as it was+# written, and the methods 'number' declares stay out of the term (#1446).+location: 'Q.t'+input: |+ ⟦+ number ↦ ⟦ φ ↦ ∅, plus ↦ ⟦ ρ ↦ ∅, x ↦ ∅ ⟧, sin ↦ ⟦ ρ ↦ ∅ ⟧ ⟧,+ t ↦ Φ.number( φ ↦ ⟦ Δ ⤍ 01- ⟧ ).plus+ ⟧+result: '⟦ ρ ↦ Φ.number( φ ↦ 01-:Δ ), x ↦ ∅ ⟧'
@@ -0,0 +1,13 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# A dispatch off Φ decorates the body it reaches, one declaring its ρ, with+# the object it was dispatched on, and that object is the whole program.+# Writing it out would copy the world into the term, and again into every term+# the body then dispatches, so the copies compound until one term weighs+# hundreds of times what the program does. Φ is the name of that object, so+# the ρ carries the name instead, and whoever reads it resolves it through the+# 'universe' rule to the very formation that would have stood there (#1318).+location: 'Q.t'+input: '⟦ a ↦ ⟦ b ↦ ⟦ Δ ⤍ 01- ⟧, ρ ↦ ∅ ⟧, t ↦ Φ.a ⟧'+result: '⟦ b ↦ 01-:Δ, ρ ↦ Φ ⟧'
@@ -0,0 +1,46 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The same premise under '_partial': the run parks where 𝕄 reached, the+# dispatch whose 'normalize' premise ran out of '--max-cycles' (#1496).+location: 'Q.x'+partial: true+input: |+ ⟦+ tuple(length, head, tail) ↦ ⟦ empty ↦ ⟦ ⟧ ⟧,+ map(pairs) ↦ ⟦+ φ ↦ ctor(+ entries ↦ pairs.length.eq( 0 ).if(+ Φ.tuple.empty,+ walk( tup ↦ pairs ).φ+ )+ ),+ ctor(entries) ↦ ⟦ keys ↦ entries ⟧,+ walk(ρ, tup) ↦ ⟦+ φ ↦ tup.length.eq( 0 ).if( Φ.tuple.empty, prev ),+ prev ↦ ρ.walk( tup ↦ tup.tail ).φ+ ⟧+ ⟧,+ x ↦ Φ.map(+ pairs ↦ Φ.tuple(+ length ↦ L_len:λ, head ↦ L_head:λ, tail ↦ L_tail:λ+ )+ ).keys+ ⟧+result: |+ ⟦+ pairs ↦ Φ.tuple(+ length ↦ L_len:λ, head ↦ L_head:λ, tail ↦ L_tail:λ+ ),+ φ ↦ ctor(+ entries ↦ pairs.length.eq( 0 ).if(+ Φ.tuple.empty,+ walk( tup ↦ pairs ).φ+ )+ ),+ ctor(entries) ↦ ⟦ keys ↦ entries ⟧,+ walk(ρ, tup) ↦ ⟦+ φ ↦ tup.length.eq( 0 ).if( Φ.tuple.empty, prev ),+ prev ↦ ρ.walk( tup ↦ tup.tail ).φ+ ⟧+ ⟧.keys
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The same atom under '_partial': the run ends on the residue the spine had+# reached instead of failing.+location: 'Q.x'+partial: true+input: '[[ x -> [[ L> Sym_arg_0 ]].foo ]]'+result: 'Sym_arg_0:λ.foo'
@@ -0,0 +1,45 @@+⟦+ all-the-basics -> [[+ no-xi ↦ a.b(c ↦ d).c,+ no-xi-in-formation ↦ ⟦+ φ ↦ ρ,+ t ↦ φ+ ⟧,+ k ↦ ⟦+ x ↦ ξ.t (z ↦ ξ.f) . the-атрибут (p ↦ ξ.ρ.ρ.ρ.f, t ↦ ξ.ρ),+ t ↦ ∅,+ Δ ⤍ 42-41-40+ ⟧.thank.you (z ↦ ξ.f) . very (z ↦ ξ.f) . much (z ↦ ξ.f),+ self ↦ ξ,+ φ ↦ ξ.φ,+ error-on-purpose ↦ ⊥,+ the-атрибут ↦ Φ.ρ,+ hi-大家 ↦ ⟦ ⟧,+ sss ↦ Φ.r,+ alpha-dispatch ↦ ξ.x.y,+ k1 ↦ ⟦ λ ⤍ Function_name_i64, first ↦ ⟦ λ ⤍ Function_name, Δ ⤍ 42- ⟧ ⟧,+ terminator-application ↦ ⊥ (t ↦ ξ.t),+ terminator-dispatch ↦ ⊥.t,+ string ↦ "Hello",+ int ↦ 42,+ float ↦ 12.3,+ float-with-exponent ↦ 0.36e-10,+ string-dot ↦ "Hello".print,+ string-application ↦ "Hello"(z ↦ ξ.f),+ int-dot ↦ 42.plus,+ int-application ↦ 42(z ↦ ξ.f),+ float-dot ↦ 52.1.print,+ float-application ↦ 52.1(z ↦ ξ.f, k ↦ ξ.i),+ minus ↦ -0,+ inline-application ↦ Φ.x(+ "Hello", 42, Φ.y("world", 11.plus(12)), 42.5+ ),+ default-package ↦ Φ.number(42),+ inline-voids(text, φ) ↦ ⟦ ⟧,+ empty-inline-voids() ↦ ⟦+ num ↦ 42+ ⟧,+ with-void-phi-sweet(φ) ↦ ⟦⟧,+ with-void-phi-salty ↦ ⟦ φ ↦ ∅ ⟧+ ]]+⟧
@@ -0,0 +1,21 @@++ [[+ number -> [[+ a -> ?,+ b -> Q.org.^.@,+ c -> $.xyz(+ q -> Q.y,+ ~0 -> $.a.b+ ),+ z -> [[+ L> Func,+ D> 00-,+ def -> Q.txt.sprintf,+ num -> 42,+ str -> "Hello, world!"+ ]],+ w -> x(-42, "Hi", y, Q.io.text),+ error -> T+ ]]+ ]]+
@@ -0,0 +1,16 @@+[[+ number -> [[+ a -> ?,+ b -> Q.org.^.@,+ c -> $.xyz(+ q -> Q.y,+ ~0 -> $.a.b+ ),+ z -> [[+ L> Func,+ D> 00-,+ def -> Q.txt.sprintf+ ]],+ error -> T+ ]]+]]
@@ -0,0 +1,1 @@+⟦ k(text, φ) ↦ ⟦ ⟧⟧
@@ -0,0 +1,1 @@+⟦ k ↦ ⟦ Δ ⤍ 42- ⟧ ⟧
@@ -0,0 +1,41 @@++ ⟦+ eo ↦ ⟦+ example ↦ ⟦+ fibonacci ↦ ⟦+ n ↦ ∅,+ φ ↦ ξ.n.lt(+ α0 ↦ Φ.number(+ α0 ↦ Φ.bytes(+ α0 ↦ ⟦ Δ ⤍ 40-00-00-00-00-00-00-00 ⟧+ )+ )+ ).if(+ α0 ↦ ξ.n,+ α1 ↦ Φ.eo.example.fibonacci(+ α0 ↦ ξ.n.minus(+ α0 ↦ Φ.number(+ α0 ↦ Φ.bytes(+ α0 ↦ ⟦ Δ ⤍ 3F-F0-00-00-00-00-00-00 ⟧+ )+ )+ )+ ).plus(+ α0 ↦ Φ.eo.example.fibonacci(+ α0 ↦ ξ.n.minus(+ α0 ↦ Φ.number(+ α0 ↦ Φ.bytes(+ α0 ↦ ⟦ Δ ⤍ 40-00-00-00-00-00-00-00 ⟧+ )+ )+ )+ )+ )+ )+ ⟧,+ λ ⤍ Package+ ⟧,+ λ ⤍ Package+ ⟧+ ⟧+
@@ -0,0 +1,1 @@+[[foo ↦ Q.org.eolang]]
@@ -0,0 +1,16 @@+⟦+ eo ↦ ⟦+ example ↦ ⟦+ fibonacci(n) ↦ ⟦+ φ ↦ n.lt(2).if(+ n,+ Φ.eo.example.fibonacci(n.minus(1)).plus(+ Φ.eo.example.fibonacci(n.minus(2))+ )+ )+ ⟧,+ λ ⤍ Package+ ⟧,+ λ ⤍ Package+ ⟧+⟧
@@ -0,0 +1,65 @@+⟦+ j$Foo ↦ ⟦+ φ ↦ Φ.jeo.class,+ version ↦ 65,+ access ↦ 33,+ supername ↦ "java/lang/Object",+ interfaces ↦ ⟦+ φ ↦ Φ.jeo.seq.of0+ ⟧,+ name ↦ "Foo",+ j$main ↦ ⟦+ φ ↦ Φ.jeo.method,+ access ↦ 9,+ descriptor ↦ "([Ljava/lang/String;)V",+ signature ↦ "",+ maxs ↦ ⟦+ φ ↦ Φ.jeo.maxs,+ val26 ↦ 7,+ val27 ↦ 4+ ⟧,+ params ↦ ⟦+ φ ↦ Φ.jeo.params,+ arg0 ↦ ⟦+ φ ↦ Φ.jeo.param,+ index ↦ 0,+ access ↦ 0,+ type ↦ "[Ljava/lang/String;"+ ⟧+ ⟧,+ body ↦ ⟦+ φ ↦ Φ.jeo.seq.of50,+ instruction30 ↦ ⟦+ φ ↦ Φ.jeo.opcode.iconst_5,+ val31 ↦ 8+ ⟧,+ instruction178 ↦ ⟦+ φ ↦ Φ.hone.map,+ opcode ↦ "invokestatic",+ class ↦ "Foo",+ target-handle ↦ 6,+ target-class ↦ "Foo",+ target-method ↦ "lambda$main$0",+ target-signature ↦ "(Ljava/lang/Object;)Ljava/lang/Integer;",+ bridge-input ↦ "Ljava/lang/Integer;",+ bridge-output ↦ "Ljava/lang/Integer;",+ accepted ↦ "Ljava/lang/Integer;",+ returned ↦ "Ljava/lang/Integer;"+ ⟧,+ instruction179 ↦ ⟦+ φ ↦ Φ.hone.o-filter,+ opcode ↦ "invokestatic",+ class ↦ "Foo",+ target-handle ↦ 6,+ target-class ↦ "Foo",+ target-method ↦ "lambda$main$1",+ target-signature ↦ "(I)Z",+ bridge-input ↦ "Ljava/lang/Integer;",+ bridge-output ↦ "Ljava/lang/Integer;",+ accepted ↦ "I",+ returned ↦ "I"+ ⟧+ ⟧+ ⟧+ ⟧+⟧
@@ -0,0 +1,3 @@+[[+ r -> [[ x -> ? ]](~18446744073709551616 -> [[]])+]]
@@ -0,0 +1,3 @@+[[+ a -> x"y+]]
@@ -0,0 +1,3 @@+[[+ x -> Q.y(D> 00-).z+]]
@@ -0,0 +1,4 @@+[[+ x -> 5,+ x -> 6+]]
@@ -0,0 +1,3 @@+[[+ a -> [[ L> 𝜎-0 ]]+]]
@@ -0,0 +1,3 @@+[[+ a -> [[ L> 𝜎-3 ]]+]]
@@ -0,0 +1,3 @@+[[+ a -> [[ L> 𝜎18446744073709551617 ]]+]]
@@ -0,0 +1,3 @@+[[+ a -> [[ L> 𝜎00 ]]+]]
@@ -0,0 +1,5 @@+[[+ x -> [[+ L> SOME+ ]]+]]
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ x -> ?, y -> [[ ]] ]](~0 -> Q.y)+output: |-+ ⟦ x ↦ ∅, y -> [[ ]] ⟧(x ↦ Φ.y)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ q -> $.y, w -> ?, z -> ?, x -> ?, y -> [[ ]] ]](~3 -> Q.y)+output: |-+ ⟦ q -> $.y, w -> ?, z -> ?, x -> ?, y -> [[ ]] ⟧(x ↦ Φ.y)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ a -> ?, ^ -> ?, x -> ? ]](~1 -> Q.y)+output: |-+ ⟦ a ↦ ∅, ρ ↦ ∅, x ↦ ∅ ⟧(x ↦ Φ.y)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ ^ -> ?, x -> ? ]](~0 -> Q.y)+output: |-+ ⟦ ρ ↦ ∅, x ↦ ∅ ⟧(x ↦ Φ.y)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ q -> $.y, x -> ?, y -> [[ ]] ]](~1 -> Q.y)+output: |-+ ⟦ q -> $.y, x ↦ ∅, y -> [[ ]] ⟧(x ↦ Φ.y)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ x -> ? ]](~0 -> Q.y)+output: |-+ ⟦ x ↦ ∅ ⟧(x ↦ Φ.y)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ ^ -> Q.y, x -> ? ]](~0 -> Q.z)+output: |-+ ⟦ ρ ↦ Φ.y, x ↦ ∅ ⟧(x ↦ Φ.z)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ D> 42-, x -> ? ]](~0 -> Q.y)+output: |-+ ⟦ D> 42-, x ↦ ∅ ⟧(x ↦ Φ.y)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ L> Fn, x -> ? ]](~1 -> Q.y)+output: |-+ ⟦ L> Fn, x ↦ ∅ ⟧(α1 ↦ Φ.y)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ L> Fn, x -> ? ]](~2 -> Q.y)+output: |-+ ⟦ L> Fn, x ↦ ∅ ⟧(~2 ↦ Φ.y)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ L> Fn, x -> ? ]](~0 -> Q.y)+output: |-+ ⟦ L> Fn, x ↦ ∅ ⟧(x ↦ Φ.y)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ x -> ? ]](~2 -> Q.y)+output: |-+ ∅:x( α2 ↦ Φ.y )
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['alpha']+input: |+ [[ x -> ?, y -> $.x ]](~1 -> Q.y)+output: |-+ ⟦ x -> ?, y -> $.x ⟧(~1 ↦ Φ.y)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['copy']+input: |+ ⟦ k ↦ ⟦ x ↦ ξ.t, t ↦ ∅ ⟧(t ↦ ⟦ρ ↦ ⟦⟧⟧) ⟧+output: |-+ ⟦ k ↦ ⟦ x ↦ ξ.t, t ↦ ⟦ρ ↦ ⟦⟧⟧ ⟧ ⟧
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['copy']+input: |+ ⟦ k ↦ ⟦ x ↦ ∅, y ↦ ξ.x ⟧(x ↦ ⟦ρ ↦ ⟦⟧⟧).y ⟧+output: |-+ ⟦ k ↦ ⟦ x ↦ ⟦ρ ↦ ⟦⟧⟧, y ↦ ξ.x ⟧.y ⟧
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['copy']+input: |+ ⟦ a ↦ ⟦ b ↦ ∅ ⟧ (b ↦ ⟦⟧) ⟧+output: |-+ ⟦⟧:b:a
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['copy']+input: |+ ⟦ a ↦ ⟦ b ↦ ∅ ⟧ (b ↦ ⟦⟧).a ⟧+output: |-+ ⟦⟧:b.a:a
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['dc']+input: |+ ⊥(ρ ↦ ⟦ x ↦ ξ.t, t ↦ ∅ ⟧)+output: |-+ ⊥
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+repeat: 2+rules:+ basic: ['dc']+input: |+ ⟦ a ↦ ⟦ b ↦ ⊥(t ↦ ⟦⟧, u ↦ ⟦⟧) ⟧ ⟧+output: |-+ ⟦ a ↦ ⟦ b ↦ ⊥ ⟧ ⟧
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['dca']+input: |+ ⊥(α0 ↦ ⟦ x ↦ ξ.t, t ↦ ∅ ⟧)+output: |-+ ⊥
@@ -0,0 +1,11 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['dd']+input: |+ ⟦ a ↦ ⊥.x ⟧+output: |-+ ⟦+ a ↦ ⊥+ ⟧
@@ -0,0 +1,12 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# With 'dot' tried before 'dl', a formation holding both λ and Δ still+# collapses to ⊥ and never leaves a ρ ↦ ⊥ behind (#1395).+rules:+ basic: ['dot', 'dl', 'dd']+repeat: 5+input: |+ ⟦ x ↦ Φ.y, λ ⤍ Foo, Δ ⤍ 00- ⟧.x+output: |-+ ⊥
@@ -0,0 +1,16 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The λ-and-Δ guard of 'dot' still lets a formation with λ alone be+# dispatched (#1395).+rules:+ basic: ['dot']+input: |+ ⟦ x ↦ Φ.y, λ ⤍ Foo ⟧.x+output: |-+ Φ.y(+ ρ ↦ ⟦+ x ↦ Φ.y,+ λ ⤍ Foo+ ⟧+ )
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['dot']+input: |+ ⟦ x ↦ ξ.t, t ↦ ∅ ⟧.x+output: |-+ ⟦ t ↦ ∅ ⟧.t(ρ ↦ ⟦ x ↦ ξ.t, t ↦ ∅ ⟧)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['dot']+input: |+ ⟦ x ↦ ⟦t ↦ ⟦ρ ↦ ⟦⟧ ⟧ ⟧.t ⟧.x+output: |-+ ⟦ x ↦ ⟦ρ ↦ ⟦⟧⟧(ρ ↦ ⟦t ↦ ⟦ρ ↦ ⟦⟧⟧⟧) ⟧.x
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['dot']+input: |+ ⟦ x ↦ ⟦ρ ↦ ⟦⟧⟧ ⟧.x+output: |-+ ⟦ρ ↦ ⟦⟧⟧(ρ ↦ ⟦x ↦ ⟦ρ ↦ ⟦⟧⟧⟧)
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+repeat: 2+rules:+ basic: ['dot']+input: |+ ⟦ x ↦ ⟦ρ ↦ ⟦⟧⟧, y ↦ ξ.x ⟧.y+output: |-+ ⟦ρ ↦ ⟦⟧⟧(ρ ↦ ⟦ x ↦ ⟦ρ ↦ ⟦⟧⟧ ⟧)(ρ ↦ ⟦ x ↦ ⟦ρ ↦ ⟦⟧⟧, y ↦ ξ.x ⟧)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['dot']+input: |+ ⟦ x ↦ ⟦ρ ↦ ⟦⟧⟧, y ↦ ξ.x ⟧.x(ρ ↦ ⟦ x ↦ ⟦ρ ↦ ⟦⟧⟧, y ↦ ξ.x ⟧)+output: |-+ ⟦ρ ↦ ⟦⟧⟧(ρ ↦ ⟦ x ↦ ⟦ρ ↦ ⟦⟧⟧, y ↦ ξ.x ⟧)(ρ ↦ ⟦ x ↦ ⟦ρ ↦ ⟦⟧⟧, y ↦ ξ.x ⟧)
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['dot']+input: |+ ⟦ m ↦ ⟦ x ↦ ξ.t, φ ↦ ⟦ t ↦ ⟦⟧ ⟧ ⟧.x ⟧+output: |-+ ⟦ m ↦ ⟦ φ ↦ ⟦ t ↦ ⟦⟧ ⟧ ⟧.t(ρ ↦ ⟦ x ↦ ξ.t, φ ↦ ⟦ t ↦ ⟦⟧ ⟧ ⟧) ⟧
@@ -0,0 +1,10 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# yamllint disable rule:line-length+rules:+ basic: ['dot']+input: |+ ⟦ m ↦ ⟦ x ↦ ξ.t, φ ↦ ⟦ t ↦ ⟦⟧ ⟧ ⟧.φ.t(ρ ↦ ⟦ x ↦ ξ.t, φ ↦ ⟦ t ↦ ⟦⟧ ⟧ ⟧) ⟧+output: |-+ ⟦ m ↦ ⟦ t ↦ ⟦⟧ ⟧(ρ ↦ ⟦ x ↦ ξ.t, φ ↦ ⟦ t ↦ ⟦⟧ ⟧ ⟧).t(ρ ↦ ⟦ x ↦ ξ.t, φ ↦ ⟦ t ↦ ⟦⟧ ⟧ ⟧) ⟧
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['dot']+input: |+ ⟦ a ↦ ξ.b ⟧.a+output: |-+ ⟦⟧.b (ρ ↦ ⟦ a ↦ ξ.b ⟧)
@@ -0,0 +1,15 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# 'dot' leaves a formation holding both λ and Δ to 'dl', so the normal form+# does not hang on rule order (#1395).+rules:+ basic: ['dot']+input: |+ ⟦ x ↦ Φ.y, λ ⤍ Foo, Δ ⤍ 00- ⟧.x+output: |-+ ⟦+ x ↦ Φ.y,+ λ ⤍ Foo,+ Δ ⤍ 00-+ ⟧.x
@@ -0,0 +1,9 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+rules:+ basic: ['dot']+input: |+ [[ t -> ⊥.z ]].t+output: |-+ [[ t -> ⊥.z ]].t
@@ -0,0 +1,12 @@+# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com+# SPDX-License-Identifier: MIT+---+# The ξ of the dispatched body stands for the formation without the+# dispatched binding, on purpose, so a body that is ξ answers the formation+# one attribute short rather than itself (#967, #1438).+rules:+ basic: ['dot']+input: |+ ⟦ a ↦ ξ ⟧.a+output: |-+ ⟦⟧ (ρ ↦ ⟦ a ↦ ξ ⟧)
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff