Home / Input Output / plutus
May 22, 5-6 PM (0)
May 22, 6-7 PM (0)
May 22, 7-8 PM (0)
May 22, 8-9 PM (0)
May 22, 9-10 PM (0)
May 22, 10-11 PM (0)
May 22, 11-12 AM (0)
May 23, 12-1 AM (0)
May 23, 1-2 AM (0)
May 23, 2-3 AM (0)
May 23, 3-4 AM (0)
May 23, 4-5 AM (0)
May 23, 5-6 AM (0)
May 23, 6-7 AM (0)
May 23, 7-8 AM (0)
May 23, 8-9 AM (0)
May 23, 9-10 AM (0)
May 23, 10-11 AM (0)
May 23, 11-12 PM (0)
May 23, 12-1 PM (0)
May 23, 1-2 PM (0)
May 23, 2-3 PM (0)
May 23, 3-4 PM (0)
May 23, 4-5 PM (0)
May 23, 5-6 PM (0)
May 23, 6-7 PM (0)
May 23, 7-8 PM (0)
May 23, 8-9 PM (0)
May 23, 9-10 PM (0)
May 23, 10-11 PM (0)
May 23, 11-12 AM (0)
May 24, 12-1 AM (0)
May 24, 1-2 AM (0)
May 24, 2-3 AM (0)
May 24, 3-4 AM (0)
May 24, 4-5 AM (0)
May 24, 5-6 AM (0)
May 24, 6-7 AM (0)
May 24, 7-8 AM (0)
May 24, 8-9 AM (0)
May 24, 9-10 AM (0)
May 24, 10-11 AM (0)
May 24, 11-12 PM (0)
May 24, 12-1 PM (0)
May 24, 1-2 PM (0)
May 24, 2-3 PM (0)
May 24, 3-4 PM (0)
May 24, 4-5 PM (0)
May 24, 5-6 PM (0)
May 24, 6-7 PM (0)
May 24, 7-8 PM (0)
May 24, 8-9 PM (0)
May 24, 9-10 PM (0)
May 24, 10-11 PM (0)
May 24, 11-12 AM (0)
May 25, 12-1 AM (0)
May 25, 1-2 AM (0)
May 25, 2-3 AM (0)
May 25, 3-4 AM (0)
May 25, 4-5 AM (0)
May 25, 5-6 AM (0)
May 25, 6-7 AM (0)
May 25, 7-8 AM (0)
May 25, 8-9 AM (0)
May 25, 9-10 AM (1)
May 25, 10-11 AM (1)
May 25, 11-12 PM (2)
May 25, 12-1 PM (0)
May 25, 1-2 PM (0)
May 25, 2-3 PM (0)
May 25, 3-4 PM (0)
May 25, 4-5 PM (0)
May 25, 5-6 PM (0)
May 25, 6-7 PM (0)
May 25, 7-8 PM (0)
May 25, 8-9 PM (0)
May 25, 9-10 PM (0)
May 25, 10-11 PM (0)
May 25, 11-12 AM (0)
May 26, 12-1 AM (0)
May 26, 1-2 AM (0)
May 26, 2-3 AM (0)
May 26, 3-4 AM (0)
May 26, 4-5 AM (0)
May 26, 5-6 AM (0)
May 26, 6-7 AM (0)
May 26, 7-8 AM (1)
May 26, 8-9 AM (0)
May 26, 9-10 AM (1)
May 26, 10-11 AM (1)
May 26, 11-12 PM (2)
May 26, 12-1 PM (0)
May 26, 1-2 PM (3)
May 26, 2-3 PM (4)
May 26, 3-4 PM (0)
May 26, 4-5 PM (1)
May 26, 5-6 PM (1)
May 26, 6-7 PM (1)
May 26, 7-8 PM (1)
May 26, 8-9 PM (0)
May 26, 9-10 PM (1)
May 26, 10-11 PM (1)
May 26, 11-12 AM (1)
May 27, 12-1 AM (0)
May 27, 1-2 AM (1)
May 27, 2-3 AM (0)
May 27, 3-4 AM (0)
May 27, 4-5 AM (0)
May 27, 5-6 AM (0)
May 27, 6-7 AM (0)
May 27, 7-8 AM (0)
May 27, 8-9 AM (0)
May 27, 9-10 AM (0)
May 27, 10-11 AM (0)
May 27, 11-12 PM (1)
May 27, 12-1 PM (6)
May 27, 1-2 PM (4)
May 27, 2-3 PM (2)
May 27, 3-4 PM (0)
May 27, 4-5 PM (0)
May 27, 5-6 PM (0)
May 27, 6-7 PM (0)
May 27, 7-8 PM (0)
May 27, 8-9 PM (0)
May 27, 9-10 PM (0)
May 27, 10-11 PM (0)
May 27, 11-12 AM (1)
May 28, 12-1 AM (2)
May 28, 1-2 AM (1)
May 28, 2-3 AM (0)
May 28, 3-4 AM (0)
May 28, 4-5 AM (0)
May 28, 5-6 AM (0)
May 28, 6-7 AM (1)
May 28, 7-8 AM (2)
May 28, 8-9 AM (1)
May 28, 9-10 AM (1)
May 28, 10-11 AM (3)
May 28, 11-12 PM (0)
May 28, 12-1 PM (2)
May 28, 1-2 PM (0)
May 28, 2-3 PM (1)
May 28, 3-4 PM (0)
May 28, 4-5 PM (0)
May 28, 5-6 PM (0)
May 28, 6-7 PM (0)
May 28, 7-8 PM (0)
May 28, 8-9 PM (0)
May 28, 9-10 PM (0)
May 28, 10-11 PM (1)
May 28, 11-12 AM (0)
May 29, 12-1 AM (0)
May 29, 1-2 AM (0)
May 29, 2-3 AM (0)
May 29, 3-4 AM (0)
May 29, 4-5 AM (0)
May 29, 5-6 AM (0)
May 29, 6-7 AM (0)
May 29, 7-8 AM (0)
May 29, 8-9 AM (0)
May 29, 9-10 AM (3)
May 29, 10-11 AM (0)
May 29, 11-12 PM (1)
May 29, 12-1 PM (1)
May 29, 1-2 PM (7)
May 29, 2-3 PM (0)
May 29, 3-4 PM (0)
May 29, 4-5 PM (0)
May 29, 5-6 PM (0)
65 commits this week May 22, 2026 - May 29, 2026
Refresh GHC 9.12 gt / geq budget goldens after checkBinRel rewrite
The previous commit (642442a85f) regenerated the GHC 9.6 column only.
plutus-ledger-api-plugin-test is also buildable on GHC 9.12 per the
ghc-version-support common stanza, and Hydra runs it there; the
checkBinRel rewrite changes the compiled UPLC enough to move the
budgets in both columns. Same regen, run in nix develop .#ghc912.

For IntersectMBO/plutus-private#2243.
Correct the unionWith fusion wording
The fusion is a constant-factor change, not the elimination of the These
intermediate it was described as. Map.union still produces a per-key These
and the inner These is still built transiently for shared keys; what the
fusion removes is one of the two outer Map.map passes over the post-union
map, plus the wrap-then-remap of single-side currencies. Adjust the
changelog and drop Note [Single-pass unionWith] accordingly; the merge
structure is plain from the code.

For IntersectMBO/plutus-private#2243.
Make the unionWith property test differential against the builtin
Compare the typed unionWith (+) against the builtin unionValue path on
CEK rather than against host-Haskell unionWith: a shared-source oracle
cannot catch a bug that lands the same way on both sides. Inputs are
restricted to the well-formed domain unsafeDataAsValue accepts, and
results are compared up to key order and zero-sum entries. Bindings use
plinthc instead of the compile splice.

Also rephrase Note [Single-pass unionWith] and the checkBinRel docstring
to describe the present structure without contrasting against history.

For IntersectMBO/plutus-private#2243.
Fuse unionWith and checkBinRel in V1.Data.Value
Drop the internal unionVal and checkPred helpers; inline the merge logic
into unionWith and checkBinRel respectively. The previous chain built a
Map CurrencySymbol (Map TokenName (These Integer Integer)) intermediate
via unionVal, then re-walked it to apply f -- three outer passes for a
single conceptual merge.

The fused unionWith now runs Map.union once and a single outer Map.map,
collapsing the These shape inline per currency-symbol entry. The
Map TokenName (These Integer Integer) stage is gone; the outer Map.map
runs once instead of twice. checkBinRel is refactored along the same
shape with Map.union + Map.all, which gives geq / leq / gt / lt
short-circuit termination on the first failing pair.

Adds Spec.Data.Value.test_unionWith: a QuickCheck property that compiles
unionWith via TH, evaluates on the CEK machine, and compares against the
host-Haskell unionWith for the same inputs. Differential test against
the Plinth compiler: any divergence is a compilation bug, not a
semantics bug.

The Spec.Data.Budget gt / geq budget goldens are regenerated: short-circuit
checkBinRel reduces gt4 / geq4 by ~46% (the worst-case adverse input);
other shapes drop 0.7-3% from removing one outer pass over the These
intermediate. The remaining diff is the cost-model anchor; that
component is unrelated to this change.

Budget evidence (union matrix vs builtin, unsafeDataAsValue baseline)
lives on the companion experimental branch
yura/issue-2243-fused-unionwith-evidence, stacked on the sibling
valueOf-evidence branch.

For IntersectMBO/plutus-private#2243.
Correct the unionWith fusion wording
The fusion is a constant-factor change, not the elimination of the These
intermediate it was described as. Map.union still produces a per-key These
and the inner These is still built transiently for shared keys; what the
fusion removes is one of the two outer Map.map passes over the post-union
map, plus the wrap-then-remap of single-side currencies. Adjust the
changelog and drop Note [Single-pass unionWith] accordingly; the merge
structure is plain from the code.

For IntersectMBO/plutus-private#2243.
Make the unionWith property test differential against the builtin
Compare the typed unionWith (+) against the builtin unionValue path on
CEK rather than against host-Haskell unionWith: a shared-source oracle
cannot catch a bug that lands the same way on both sides. Inputs are
restricted to the well-formed domain unsafeDataAsValue accepts, and
results are compared up to key order and zero-sum entries. Bindings use
plinthc instead of the compile splice.

Also rephrase Note [Single-pass unionWith] and the checkBinRel docstring
to describe the present structure without contrasting against history.

For IntersectMBO/plutus-private#2243.
Add Spec.Data.Value.Budget — non-builtin valueOf evidence
Adds `Spec.Data.Value.Budget` with the lookup matrix for `valueOf` across
S1 / S3 / S8 / S100 value shapes at ada / middle / last / miss positions,
plus the standalone `unsafeDataAsValue` baseline per shape. Generated 96
golden files (eval / pir / uplc per bundle, 32 bundles total) capture CPU
and Memory cost evidence.

Companion to the merge PR for `valueOf` rewrite. This branch is kept
separate so the goldens — which only regenerate on upstream plugin or
cost-model changes, not on actual regressions — don't bloat the main
PR's diff or CI.

For IntersectMBO/plutus-private#2242.
Add valueOf golden coverage in Spec.Data.Budget
Adds a PIR-readable snapshot and four budget snapshots for the new `valueOf`
implementation, registered alongside the existing golden coverage for
`gt`, `geq`, and `currencySymbolValueOf`.

Scenarios:
- valueOf_hit_first: ada-like first-position lookup, exercises short-circuit on the first outer step.
- valueOf_hit_middle: key at the middle of the outer map.
- valueOf_hit_last: key at the last entry, full outer scan.
- valueOf_miss: absent key, full scan with no inner walk.

These tests catch regressions in `valueOf` compilation and cost that would
otherwise surface only through downstream callers (`currencySymbolValueOf`,
`assetClassValueOf`, `geq`, etc.).
Optimal non-builtin valueOf in plutus-ledger-api Data.Value
Rewrites `PlutusLedgerApi.V1.Data.Value.valueOf` so the non-builtin lookup
path walks the underlying `BuiltinList` directly via `unsafeDataAsMap` /
`unsafeDataAsB` / `unsafeDataAsI`, compares keys with `equalsByteString`,
and short-circuits on the first match. No `Maybe` is materialised: the
"absent" answer is `0`, returned in-place by the `nilCase` of each
traversal. Avoids `withCurrencySymbol`'s continuation + `Map.lookup`'s
`Maybe`-wrapping, and bypasses the `ToData k`/`UnsafeFromData a` dictionary
work that `AssocMap.lookup` does per element. Semantics preserved.

Adds `Spec.Data.Value.test_valueOf`: a QuickCheck property that compiles
`valueOf` via TH, evaluates it on the CEK machine, and compares the result
against the host-Haskell `valueOf` for the same inputs. Differential test
against the Plinth compiler — any divergence is a compilation bug, not a
semantics bug.

Budget evidence (lookup matrix, `unsafeDataAsValue` baseline) lives on the
companion experimental branch `yura/issue-2242-valueof-evidence`, kept out
of this PR to avoid carrying ~96 golden files that would only ever regenerate
on upstream plugin/cost-model changes.

For IntersectMBO/plutus-private#2242.
Add Spec.Data.Value.UnionBudget -- raw sorted-merge vs builtin matrix
Compares the on-chain builtin union path (unsafeDataAsValue + unionValue +
mkValue) against a hand-rolled sorted-merge over the raw BuiltinData
representation, so V3 guidance on union cost rests on concrete numbers
rather than estimates.

The new module Spec.Data.Value.UnionBudget adds 8 goldenBundle entries:
union_S1,3,8,100 in builtin and raw variants. Both bundle paths take two
BuiltinData-encoded Values, the same value on both sides, mirroring the
conservation-of-value pattern from production validators, produce the
merged BuiltinData, and report the CEK budget. The bundle does not chain
a lookupCoin or valueOf on the result so the measured cost is the union
itself, not a union-then-lookup composite.

The hand-rolled unionValuePositiveRaw is a Plinth translation of
Philip's pvalueUnionFast (Plutarch, slack thread 1776810760.659419).
Sorted-merge with a three-way branch on key comparison; assumes both
inputs sorted by lexicographic key and inner-pair values strictly
positive. Sorted-merge is O(L + R) per level; lookup-and-merge through
AssocMap.union would be O(L x R).

unionValuePositiveRaw is module-internal and not exported from
plutus-ledger-api. The positive-quantity precondition is documented at
the call site, not encoded in the type system. The unionValueNonZero
variant from the slack discussion is left for a follow-up commit; the
production case Philip cares about is tx outputs, which are strictly
positive.

Result matrix, raw vs builtin CPU ratio: S1 5.20x, S3 5.65x, S8 5.83x,
S100 4.47x. Byte-identical output between builtin and raw at every
shape; the raw column closes most of the gap that the typed unionWith
from plutus#7799 opens. Goldens regenerated under both GHC 9.6 and GHC
9.12 (per ghc-version-support cabal stanza). 24 goldens times 2 GHC
versions equals 48 files.

For IntersectMBO/plutus-private#2243.
Refresh GHC 9.12 gt / geq budget goldens after checkBinRel rewrite
The previous commit (642442a85f) regenerated the GHC 9.6 column only.
plutus-ledger-api-plugin-test is also buildable on GHC 9.12 per the
ghc-version-support common stanza, and Hydra runs it there; the
checkBinRel rewrite changes the compiled UPLC enough to move the
budgets in both columns. Same regen, run in nix develop .#ghc912.

For IntersectMBO/plutus-private#2243.
Add Spec.Data.Value.Budget — non-builtin valueOf evidence
Adds `Spec.Data.Value.Budget` with the lookup matrix for `valueOf` across
S1 / S3 / S8 / S100 value shapes at ada / middle / last / miss positions,
plus the standalone `unsafeDataAsValue` baseline per shape. Generated 96
golden files (eval / pir / uplc per bundle, 32 bundles total) capture CPU
and Memory cost evidence.

Companion to the merge PR for `valueOf` rewrite. This branch is kept
separate so the goldens — which only regenerate on upstream plugin or
cost-model changes, not on actual regressions — don't bloat the main
PR's diff or CI.

For IntersectMBO/plutus-private#2242.
Add valueOf golden coverage in Spec.Data.Budget
Adds a PIR-readable snapshot and four budget snapshots for the new `valueOf`
implementation, registered alongside the existing golden coverage for
`gt`, `geq`, and `currencySymbolValueOf`.

Scenarios:
- valueOf_hit_first: ada-like first-position lookup, exercises short-circuit on the first outer step.
- valueOf_hit_middle: key at the middle of the outer map.
- valueOf_hit_last: key at the last entry, full outer scan.
- valueOf_miss: absent key, full scan with no inner walk.

These tests catch regressions in `valueOf` compilation and cost that would
otherwise surface only through downstream callers (`currencySymbolValueOf`,
`assetClassValueOf`, `geq`, etc.).
Optimal non-builtin valueOf in plutus-ledger-api Data.Value
Rewrites `PlutusLedgerApi.V1.Data.Value.valueOf` so the non-builtin lookup
path walks the underlying `BuiltinList` directly via `unsafeDataAsMap` /
`unsafeDataAsB` / `unsafeDataAsI`, compares keys with `equalsByteString`,
and short-circuits on the first match. No `Maybe` is materialised: the
"absent" answer is `0`, returned in-place by the `nilCase` of each
traversal. Avoids `withCurrencySymbol`'s continuation + `Map.lookup`'s
`Maybe`-wrapping, and bypasses the `ToData k`/`UnsafeFromData a` dictionary
work that `AssocMap.lookup` does per element. Semantics preserved.

Adds `Spec.Data.Value.test_valueOf`: a QuickCheck property that compiles
`valueOf` via TH, evaluates it on the CEK machine, and compares the result
against the host-Haskell `valueOf` for the same inputs. Differential test
against the Plinth compiler — any divergence is a compilation bug, not a
semantics bug.

Budget evidence (lookup matrix, `unsafeDataAsValue` baseline) lives on the
companion experimental branch `yura/issue-2242-valueof-evidence`, kept out
of this PR to avoid carrying ~96 golden files that would only ever regenerate
on upstream plugin/cost-model changes.

For IntersectMBO/plutus-private#2242.
Metatheory: define semantic versions of value and purity (#7802)
Adds semantic definitions of values and purity, based on the current UPLC reduction semantics. Also changes Reduction.lagda.md semantics to be closer to the pdf spec, in the sense that it is only defined for closed terms.

Semantic versions of Value and Pure are needed for proving certain translation relations sound. Proving that Pure (syntactic) implies pure (semantic) will be next.