Skip to content

Decode Z3 models containing sets#2422

Open
Vedthakar wants to merge 2 commits into
cedar-policy:mainfrom
Vedthakar:decode-z3-set-models
Open

Decode Z3 models containing sets#2422
Vedthakar wants to merge 2 commits into
cedar-policy:mainfrom
Vedthakar:decode-z3-set-models

Conversation

@Vedthakar

Copy link
Copy Markdown
Contributor

Fixes #2415 by adding support for decoding Z3 set models in SymCC.

Previously, model decoding could fail on valid Z3 set representations such as:

((as const (Set Bool)) true)
(store ...)
(lambda ...)
(_ as-array k!N)

This change adds support for decoding these set encodings, reconstructing finite Cedar sets from Z3 models, and introduces explicit errors for unsupported or non-finite set models.

Also adds test coverage for the reported Z3 set model formats and associated error cases.

Closes #2415

Checklist for requesting a review

The change in this PR is (choose one, and delete the other options):

A breaking change requiring a major version bump to cedar-policy (e.g., changes to the signature of an existing API).
A backwards-compatible change requiring a minor version bump to cedar-policy (e.g., addition of a new API).
A bug fix or other functionality change requiring a patch to cedar-policy.
A change "invisible" to users (e.g., documentation, changes to "internal" crates like cedar-policy-core, cedar-validator, etc.)
A change (breaking or otherwise) that only impacts unreleased or experimental code.

I confirm that this PR (choose one, and delete the other options):

Updates the "Unreleased" section of the CHANGELOG with a description of my change (required for major/minor version bumps).
Does not update the CHANGELOG because my change does not significantly impact released code.

I confirm that cedar-spec (choose one, and delete the other options):

Does not require updates because my change does not impact the Cedar formal model or DRT infrastructure.
Requires updates, and I have made / will make these updates myself.
Requires updates, but I do not plan to make them in the near future.
I'm not sure how my change impacts cedar-spec.

I confirm that docs.cedarpolicy.com (choose one, and delete the other options):

Does not require updates because my change does not impact the Cedar language specification.
Requires updates, and I have made / will make these updates myself.
I'm not sure how my change impacts the documentation.

One minor note: depending on Cedar maintainer preference, they may consider this a feature request implementation rather than a pure bug fix because the issue is labeled feature-request. If someone comments on that, it's normal, but I'd still mark it as a patch-level functionality change exactly as you've done.

@john-h-kastner-aws

Copy link
Copy Markdown
Contributor

hi! Thanks for doing this.

Can you provide some more documentation on exactly what you've added parsing for and what you've left unhandled? Ideally pointing to some z3 docs on what it emits if you were able to find those.

@Vedthakar Vedthakar force-pushed the decode-z3-set-models branch from 2ef2796 to 3d35134 Compare June 22, 2026 18:26
@Vedthakar

Copy link
Copy Markdown
Contributor Author

Thanks for the suggestion — I've added documentation to decoder.rs that explicitly describes the Z3 set-model encodings we support, the ones we intentionally leave unhandled, and where each path is implemented.

The docs now distinguish between:

Existing support (via decode_literal_app)

  • (as set.empty <set-ty>)
  • (set.singleton <val>)
  • (set.union <set1> <set2>) when both operands are set literals

Support added in this PR (via decode_set_array)

  • ((as const (Set <ty>)) <bool>)
  • (store <set-array> <key> <bool>)
  • (lambda ((x <ty>)) <body>)
  • (_ as-array k!N) with helper define-fun bodies

The documentation also calls out the intentionally unsupported cases and the corresponding DecodeError variants (NonFiniteSet, UnsupportedSetModel, SetUnionNonLiterals), along with the reasoning behind those limitations.

I've added references to the SMT-LIB get-model specification and Z3 model/function-interpretation documentation. I wasn't able to find a single authoritative source that enumerates every set-model encoding Z3 may emit, so the documented forms are the ones we've observed in solver output and exercised in the decoder tests.

The coverage table and references now live in the module-level docs in cedar-policy-symcc/src/symcc/decoder.rs.

Signed-off-by: Ved Thakar <ved06.thakar@gmail.com>
Signed-off-by: Ved Thakar <ved06.thakar@gmail.com>
@Vedthakar Vedthakar force-pushed the decode-z3-set-models branch from be7811d to 25f0eca Compare June 22, 2026 18:40
@github-actions

Copy link
Copy Markdown

Coverage Report

Head Commit: 2ef279609e17fa280f2c0ec4a02e83ccbd828f52

Base Commit: 1b05ecfc34a9a2405045248971c2f601a92b7478

Download the full coverage report.

Coverage of Added or Modified Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 82.39%

Status: PASSED ✅

Details
File Status Covered Coverage Missed Lines
cedar-policy-symcc/src/symcc/decoder.rs 🟢 234/284 82.39% 414, 446, 448, 453-454, 464, 467, 469-471, 473, 483, 496, 513-516, 525, 527-529, 531-533, 535, 549-551, 567-569, 572-574, 598, 600, 614, 618, 624, 628, 632, 634, 636, 648, 650, 754, 773, 790, 797, 1204

Coverage of All Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 87.90%

Status: PASSED ✅

Details
Package Status Covered Coverage Base Coverage
cedar-language-server 🟢 4722/5102 92.55% --
cedar-policy 🟢 4573/5687 80.41% --
cedar-policy-cli 🟡 1257/1649 76.23% --
cedar-policy-core 🟢 24721/28046 88.14% --
cedar-policy-formatter 🟢 914/1088 84.01% --
cedar-policy-symcc 🟢 7045/7584 92.89% --
cedar-wasm 🔴 0/28 0.00% --

@github-actions

Copy link
Copy Markdown

Coverage Report

Head Commit: 3d351349604a99b63a6ab9b7c6b9284f957c1d96

Base Commit: 1b05ecfc34a9a2405045248971c2f601a92b7478

Download the full coverage report.

Coverage of Added or Modified Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 82.39%

Status: PASSED ✅

Details
File Status Covered Coverage Missed Lines
cedar-policy-symcc/src/symcc/decoder.rs 🟢 234/284 82.39% 414, 446, 448, 453-454, 464, 467, 469-471, 473, 483, 496, 513-516, 525, 527-529, 531-533, 535, 549-551, 567-569, 572-574, 598, 600, 614, 618, 624, 628, 632, 634, 636, 648, 650, 754, 773, 790, 797, 1204

Coverage of All Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 87.90%

Status: PASSED ✅

Details
Package Status Covered Coverage Base Coverage
cedar-language-server 🟢 4722/5102 92.55% --
cedar-policy 🟢 4573/5687 80.41% --
cedar-policy-cli 🟡 1257/1649 76.23% --
cedar-policy-core 🟢 24721/28046 88.14% --
cedar-policy-formatter 🟢 914/1088 84.01% --
cedar-policy-symcc 🟢 7045/7584 92.89% --
cedar-wasm 🔴 0/28 0.00% --

@john-h-kastner-aws

Copy link
Copy Markdown
Contributor

I also have to ask here how much of this change was implemented by an LLM. As noted on the issue, one should be able to make a reasonable implementation, but I need to maintain a high standard of confidence that model decoding is in fact correct.

I want to know if you feel you can vouch for the correctness of this code.

@@ -0,0 +1,52 @@
thread 'rustc' panicked at /rustc-dev/e0e95a71872dfe9e15d22bddea9ac45c85ddda1a/compiler/rustc_middle/src/query/on_disk_cache.rs:663:9:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is including these files intentional?

@github-actions

Copy link
Copy Markdown

Coverage Report

Head Commit: be7811d6c25726ab814a081e1852753f8f88e23b

Base Commit: 1b05ecfc34a9a2405045248971c2f601a92b7478

Download the full coverage report.

Coverage of Added or Modified Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 82.18%

Status: PASSED ✅

Details
File Status Covered Coverage Missed Lines
cedar-policy-symcc/src/symcc/decoder.rs 🟢 249/303 82.18% 437, 451, 454, 460, 467, 469, 478, 486, 492, 510, 512, 517-518, 528, 531, 533-535, 537, 547, 560, 577-580, 589, 591-593, 595-597, 599, 613-615, 631-633, 636-638, 662, 664, 678, 682, 688, 692, 696, 698, 700, 717, 719, 1164

Coverage of All Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 87.90%

Status: PASSED ✅

Details
Package Status Covered Coverage Base Coverage
cedar-language-server 🟢 4722/5102 92.55% --
cedar-policy 🟢 4573/5687 80.41% --
cedar-policy-cli 🟡 1257/1649 76.23% --
cedar-policy-core 🟢 24731/28056 88.15% --
cedar-policy-formatter 🟢 914/1088 84.01% --
cedar-policy-symcc 🟢 7045/7584 92.89% --
cedar-wasm 🔴 0/28 0.00% --

@github-actions

Copy link
Copy Markdown

Coverage Report

Head Commit: 25f0eca9ad7f01299ebeb4741a178b4aabf3b76a

Base Commit: 1b05ecfc34a9a2405045248971c2f601a92b7478

Download the full coverage report.

Coverage of Added or Modified Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 82.18%

Status: PASSED ✅

Details
File Status Covered Coverage Missed Lines
cedar-policy-symcc/src/symcc/decoder.rs 🟢 249/303 82.18% 437, 451, 454, 460, 467, 469, 478, 486, 492, 510, 512, 517-518, 528, 531, 533-535, 537, 547, 560, 577-580, 589, 591-593, 595-597, 599, 613-615, 631-633, 636-638, 662, 664, 678, 682, 688, 692, 696, 698, 700, 717, 719, 1164

Coverage of All Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 87.90%

Status: PASSED ✅

Details
Package Status Covered Coverage Base Coverage
cedar-language-server 🟢 4722/5102 92.55% --
cedar-policy 🟢 4573/5687 80.41% --
cedar-policy-cli 🟡 1257/1649 76.23% --
cedar-policy-core 🟢 24731/28056 88.15% --
cedar-policy-formatter 🟢 914/1088 84.01% --
cedar-policy-symcc 🟢 7045/7584 92.89% --
cedar-wasm 🔴 0/28 0.00% --

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Decode z3 models containing sets

3 participants