Skip to content

Multi Sets#3698

Draft
lks9 wants to merge 6 commits into
mainfrom
MultiSet
Draft

Multi Sets#3698
lks9 wants to merge 6 commits into
mainfrom
MultiSet

Conversation

@lks9

@lks9 lks9 commented Dec 11, 2025

Copy link
Copy Markdown
Contributor

Intended Change

This adds multisets in KeY, to show permutation properties. This complements the existing formalizations using seqPerm and bsum.

  • Adds (\mset int k; low <= k <= high; t) extended JML quantifier
  • Adds msetRange{int k;}(low, high, t) to JavaDL and other constructors such as msetSingle, msetSum
  • Adds rules for multisets

Plan

There were some fixes needed to actually prove permutation properties of quicksort or similar.

  • Solve the issue with applyEq or hideAuxiliaryEq. Three instantiations of hideAuxiliaryEq were needed, Quicksort_sort.zproof.zip
  • Check that the fix in EqualityConstraint.java, function normalize() does not break anything
  • Make the quicksort example work for the full specification, not just the permutation property
  • Add Quicksort example as test case
  • Resolve merge conflicts
  • Document the changes

Type of pull request

  • New feature (non-breaking change which adds functionality)
  • There are changes to the (Java) code
  • There are changes to the taclet rule base

Additional information

Quicksort could not be shown without the changes to EqualityConstraint.java. As far as I understand it, the isRigid() guard prevents normalization and is therefore a completeness bug in the current version of KeY. Credits go to @unp1. Apparently, in an old KeY 1.x version, the isRigid() guard was needed for soundness as it would prevent normalization with constrained program variables.

The basic idea of the MSet rules is as follows:

  1. If a single array element is updated, we should decompose the msetRange into a msetSum of the msetSingle with the updated element and msetRange for the remaining part without the update.
  2. msetSum is converted into a normal form using associativity and commutativity.
  3. The points above convert an equation over two msets A = B into A_decomposed = B. To bring B in the same form (although there are no updates), msetRange is also decomposed on side B an equation using the rule mset_extract_triggered and friends.

Alternatively to the decomposition approach, we could also back-convert the normal form of msetSums (e.g. A_decomposed) into a big msetRange. However, we have not implemented this.

The contributions within this pull request are licensed under GPLv2 (only) for inclusion in KeY.

@lks9 lks9 changed the title Multi set Multi Sets Dec 11, 2025
@Drodt Drodt added this to the v3.0.0 milestone Jan 7, 2026
\heuristics(simplify)
};

msetUnionSubset {

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.

This rule is at the moment not automatically applied as mSetEl is not instantiated. It seems also not to be correct because the test should check for all mSetEl in s?

After a fix it should not be in simplify as it might result in an infinite loop.

\heuristics(polySimp_expand, polySimp_addOrder)
};

msetUnionAssociativity {

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.

Here and in other places we should define a term order for multisets and use that one. The ordering using poly_... checks whether its arguments are monomials and plynomials which does not work here as expected.

\heuristics(simplify)
};

msetSumWithMSetEmpty1 {

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.

with a working term order only one of the msetSumWithMSetEmpty1/2 rules should be needed

\heuristics(polySimp_expand, polySimp_addAssoc)
};

msetDiffWithMSetEmpty1 {

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.

similar remark as for msetSumWithMSetEmpty

\heuristics(simplify)
};

msetIntersecSubset {

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.

see remark for mSetUnion

Mset msetSum(Mset, Mset);
Mset msetRange {false, false, true}(int, int, any);
}

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.

Some of the rules check for subset. We should add a predicate for that and use that one in the assumes of the rules instead of an if-then-else

@unp1

unp1 commented Feb 19, 2026

Copy link
Copy Markdown
Member

@lks9 The review remarks are mostly for myself, so that I don't forget to address them when looking into the strategies for this PR

@wadoon

wadoon commented Jun 28, 2026

Copy link
Copy Markdown
Member

Error message:

1615       INFO  Test worker     d.u.i.k.u.ParserExceptionTest Original stacktrace leading to failed junit assertion in doubleDecl.key Rule set out_of_bounds was not previous defined. at file:/home/weigl/work/key/key.core/build/resources/main/de/uka/ilkd/key/proof/rules/msetRules.key:34:21 (file:/home/weigl/work/key/key.core/build/resources/main/de/uka/ilkd/key/proof/rules/msetRules.key:34:21)

@wadoon
wadoon requested a review from unp1 June 28, 2026 04:09
@wadoon

wadoon commented Jul 3, 2026

Copy link
Copy Markdown
Member

KaKeY: If not ready until July 8th, the PR is postponed to milestone v3.1.0

@lks9

lks9 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

I would suggest removing the rules for union, intersection, and diff. They have never been correct. For our verification purposes, sum, single, and range are the operators to use. I see no need for union, intersection, and diff. Should we also remove the constructors for union, intersection, and diff? I would say, comment them out for future additions.

I was absent in the KaKeY because I did not know that you would discuss this MR. If you think it can/should be finished by July 8th, I can help.

@unp1

unp1 commented Jul 3, 2026

Copy link
Copy Markdown
Member

@lks9 I am rewriting them currently to parametric versions and remove the union, intersec and diff. We can then have a look at the result together thanks next week. Thanks!

@unp1 unp1 modified the milestones: v3.0.0, v3.1.0 Jul 3, 2026
@unp1

unp1 commented Jul 3, 2026

Copy link
Copy Markdown
Member

The PR is moved to 3.1
The problem is that for parametric functions and sort, we currently have two blockers:

  1. We would need to be able to declare parametric model / ghost fields in JML. Otherwise, the type is not clear, and it cannot be derived by some other expression, such as a Set<[Object]> might be defined to contain only Strings without becoming a Set<[String]>.
  2. LDTs do not realy work for parametric functions as well e.g. when converting a Literal. The EmptyMSet Literal in a JML expression does not have any type (yet) hence, either that need to have a specifc type (empty set of int, String etc.) or the LDT has to get an additional parameter with the sort

Without solving both issues first, the use of the mset theory is rather limited and we will not have a solution for them before 3.0

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.

5 participants