Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mark MAP.lookup* rules as preserving-definedness, add in_keys rules #3987

Closed
wants to merge 1,382 commits into from

Conversation

jberthold
Copy link
Member

@jberthold jberthold commented Feb 14, 2024

  • The symbolic Map.lookup rules preserve definedness by ensuring that the decomposed map argument is well-defined (no duplicate keys). If not (i.e., the LHS was undefined), the RHS will include ensures #Bottom.
  • Likewise, the symbolic Map.lookupOrDefault rules preserve definedness by ensuring that the decomposed map argument is well-defined (no duplicate keys). If not (i.e., the LHS was undefined), the RHS will include ensures #Bottom.
  • Rules are added to express the MAP.in_keys semantics in K instead of using inline kore as the existing simplification rules did.
    • K in_keys(.Map) simplifies to K =/= K to carry undefined key arguments over to the RHS
    • As in the lookup rules, K in_keys( <decomposed> ) cases use an ensures clause to carry undefined Map arguments to the RHS.
    • The addition of these rules enables the backend to prune some redundant conditions in related tests for operations on symbolic maps, test expectations have been updated accordingly.

This PR addresses an issue reported in runtimeverification/hs-backend-booster#498 Alternatively, this can be addressed by implementing hooks in booster for the MAP.lookup* and MAP.in_keys functions (see runtimeverification/hs-backend-booster#506)

devops and others added 17 commits February 9, 2024 16:27
* The symbolic `Map.lookup` rules preserve definedness by ensuring
  that the decomposed map argument is well-defined (no duplicate
  keys). If not (i.e., the LHS was undefined), the RHS will include
  `ensures #Bottom`.
* Likewise, the symbolic `Map.lookupOrDefault` rules preserve
  definedness by ensuring that the decomposed map argument is
  well-defined (no duplicate keys). If not (i.e., the LHS was
  undefined), the RHS will include `ensures #Bottom`.
* Rules are added to express the `MAP.in_keys` semantics in K instead
  of using inline kore as the existing simplification rules did.
  - `K in_keys(.Map)` simplifies to `K =/= K` to carry undefined key
    arguments over to the RHS
  - As in the `lookup` rules, `K in_keys( <decomposed> )` cases use
    an `ensures` clause to carry undefined `Map` arguments to the RHS.
@rv-jenkins rv-jenkins changed the base branch from master to develop February 14, 2024 03:49
Many `in_keys` expressions in the expectations can now be evaluated to
`true` or identified as redundant (a more specific condition is
present).
jberthold added a commit to runtimeverification/hs-backend-booster that referenced this pull request Feb 19, 2024
## Stronger `Map` matching

Previously, only fully concrete maps (all keys and values identical)
would have matched, which is highly unlikely when matching
simplification rules.
Now we compare the key sets for (syntactic) equality after substituting
with the current substitution, and then try to perform matching on the
remainder if a solution is at all possible. Most importantly, maps of
fully-concrete keys can now be handled, matching the contained values.
In addition, the case of matching a single unknown key out of a
singleton map (i.e., without opaque rest in the subject map) is now
possible.
Any ambiguous case is still rejected as `MatchIndeterminate` but some
cases can be decided as `MatchFailed` immediately.

## Selected hooks for `Map`
This change implements 3 crucial hooks for internalised `Map`s:

* `lookup`: partial function that looks up a value for a given key in a
map. Returns no result when the key is not present.
* `lookupOrDefault`: total function that looks up a value for a given
key in a map. If the key is not present, it returns a given default
value instead.
The implemented hook won't return any result when the presence of the
key cannot be decided.
* `in_keys`: predicate that checks whether a given key is present in a
map. The implemented hook won't return any result if the presence of the
key cannot be decided.

All three hooks are conservative, not returning any results when they
find unevaluated (parts of the) arguments.

These hooks, together with the enhanced `Map`-matching of #502, avoid a
fall-back to legacy `kore-rpc` in an issue reported in #498.
Alternatively, [more suitable rules for `in_keys` could be added to
`domains.md`, and the rules for `lookup` and `lookupOrDefault` could be
marked as
`preserves-definedness`](runtimeverification/k#3987)
so `booster` will use them.

Fixes #498
@jberthold
Copy link
Member Author

Obsolete after implementing the relevant hooks.

@jberthold jberthold closed this Feb 22, 2024
@jberthold jberthold deleted the jb/lookup-definedness-and-in_keys-rules branch February 22, 2024 04:41
jberthold added a commit to runtimeverification/haskell-backend that referenced this pull request Apr 10, 2024
## Stronger `Map` matching

Previously, only fully concrete maps (all keys and values identical)
would have matched, which is highly unlikely when matching
simplification rules.
Now we compare the key sets for (syntactic) equality after substituting
with the current substitution, and then try to perform matching on the
remainder if a solution is at all possible. Most importantly, maps of
fully-concrete keys can now be handled, matching the contained values.
In addition, the case of matching a single unknown key out of a
singleton map (i.e., without opaque rest in the subject map) is now
possible.
Any ambiguous case is still rejected as `MatchIndeterminate` but some
cases can be decided as `MatchFailed` immediately.

## Selected hooks for `Map`
This change implements 3 crucial hooks for internalised `Map`s:

* `lookup`: partial function that looks up a value for a given key in a
map. Returns no result when the key is not present.
* `lookupOrDefault`: total function that looks up a value for a given
key in a map. If the key is not present, it returns a given default
value instead.
The implemented hook won't return any result when the presence of the
key cannot be decided.
* `in_keys`: predicate that checks whether a given key is present in a
map. The implemented hook won't return any result if the presence of the
key cannot be decided.

All three hooks are conservative, not returning any results when they
find unevaluated (parts of the) arguments.

These hooks, together with the enhanced `Map`-matching of #502, avoid a
fall-back to legacy `kore-rpc` in an issue reported in #498.
Alternatively, [more suitable rules for `in_keys` could be added to
`domains.md`, and the rules for `lookup` and `lookupOrDefault` could be
marked as
`preserves-definedness`](runtimeverification/k#3987)
so `booster` will use them.

Fixes #498
jberthold added a commit to runtimeverification/haskell-backend that referenced this pull request Apr 10, 2024
## Stronger `Map` matching

Previously, only fully concrete maps (all keys and values identical)
would have matched, which is highly unlikely when matching
simplification rules.
Now we compare the key sets for (syntactic) equality after substituting
with the current substitution, and then try to perform matching on the
remainder if a solution is at all possible. Most importantly, maps of
fully-concrete keys can now be handled, matching the contained values.
In addition, the case of matching a single unknown key out of a
singleton map (i.e., without opaque rest in the subject map) is now
possible.
Any ambiguous case is still rejected as `MatchIndeterminate` but some
cases can be decided as `MatchFailed` immediately.

## Selected hooks for `Map`
This change implements 3 crucial hooks for internalised `Map`s:

* `lookup`: partial function that looks up a value for a given key in a
map. Returns no result when the key is not present.
* `lookupOrDefault`: total function that looks up a value for a given
key in a map. If the key is not present, it returns a given default
value instead.
The implemented hook won't return any result when the presence of the
key cannot be decided.
* `in_keys`: predicate that checks whether a given key is present in a
map. The implemented hook won't return any result if the presence of the
key cannot be decided.

All three hooks are conservative, not returning any results when they
find unevaluated (parts of the) arguments.

These hooks, together with the enhanced `Map`-matching of #502, avoid a
fall-back to legacy `kore-rpc` in an issue reported in #498.
Alternatively, [more suitable rules for `in_keys` could be added to
`domains.md`, and the rules for `lookup` and `lookupOrDefault` could be
marked as
`preserves-definedness`](runtimeverification/k#3987)
so `booster` will use them.

Fixes #498
jberthold added a commit to runtimeverification/haskell-backend that referenced this pull request Apr 10, 2024
## Stronger `Map` matching

Previously, only fully concrete maps (all keys and values identical)
would have matched, which is highly unlikely when matching
simplification rules.
Now we compare the key sets for (syntactic) equality after substituting
with the current substitution, and then try to perform matching on the
remainder if a solution is at all possible. Most importantly, maps of
fully-concrete keys can now be handled, matching the contained values.
In addition, the case of matching a single unknown key out of a
singleton map (i.e., without opaque rest in the subject map) is now
possible.
Any ambiguous case is still rejected as `MatchIndeterminate` but some
cases can be decided as `MatchFailed` immediately.

## Selected hooks for `Map`
This change implements 3 crucial hooks for internalised `Map`s:

* `lookup`: partial function that looks up a value for a given key in a
map. Returns no result when the key is not present.
* `lookupOrDefault`: total function that looks up a value for a given
key in a map. If the key is not present, it returns a given default
value instead.
The implemented hook won't return any result when the presence of the
key cannot be decided.
* `in_keys`: predicate that checks whether a given key is present in a
map. The implemented hook won't return any result if the presence of the
key cannot be decided.

All three hooks are conservative, not returning any results when they
find unevaluated (parts of the) arguments.

These hooks, together with the enhanced `Map`-matching of #502, avoid a
fall-back to legacy `kore-rpc` in an issue reported in #498.
Alternatively, [more suitable rules for `in_keys` could be added to
`domains.md`, and the rules for `lookup` and `lookupOrDefault` could be
marked as
`preserves-definedness`](runtimeverification/k#3987)
so `booster` will use them.

Fixes #498
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.

1 participant