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

Chopper: More fine grained dependency analysis for domain axioms #776

Merged
merged 7 commits into from
Mar 11, 2024

Conversation

Felalolf
Copy link
Contributor

This PR makes two changes to the chopper that I explain below:

Changes the dependency analysis for domain axioms

The PR changes how dependencies for domain axioms are defined. Before, for an axiom A, we added dependencies from all uses in A to A and from A to all uses in A. These dependencies have two issues:

  1. If the uses of A include the domain that A is defined in, then A and all its uses are always included when the domain is included.
  2. A is always included if any expression in A is required, even if that expression is guarded by a trigger that is not included, i.e. never triggered.

The PR does the following changes:

  1. Dependencies that have A's domain as source are removed from axiom dependencies.
  2. As before, the axiom has a dependency to all uses in its body. Conversely, all uses outside of quantified expressions and uses in triggers have a dependency to the axiom.

Consider the following domain:

domain D {
  func foo(x: Int): Int
  func bar(x: Int): Int
  func baz(x: Int): Int
  axiom A { forall x: Int :: {bar(x)} bar(x) > baz(x) }
}

Previously, the dependencies were (omitting dependencies to D): A -> bar, A -> baz, bar -> A, baz -> A
With the PR the dependencies are instead: A -> bar, A -> baz, bar -> A

Makes the chopper extendable

In short, the PR changes all objects to traits. To avoid polluting the namespace, I moved the chopper into a separate package.

Changes to the code

Unfortunately, Github does not recognize that the new Chopper file is based on the previous one.
Below, I give a list of all code changes without changes to signatures (to replace objects with traits):

  1. I introduce a Edges.directUsages method. The method is a non-transitive version of Edges.usages.
  2. I changed the ast.Domain case of the Edges.dependencies method. This case implements the change to the logic as described above.

@marcoeilers
Copy link
Contributor

I have a question about the axiom dependencies based on triggers: If an axiom has any trigger that does not require a specific domain function to be used, then... what are the dependencies?
E.g. in your example
axiom A { forall x: Int :: {bar(x)} { Seq(x) } bar(x) > baz(x) }

@Felalolf
Copy link
Contributor Author

Felalolf commented Mar 4, 2024

@marcoeilers I assume you meant the axiom axiom A { forall x: Int :: { Seq(x) } bar(x) > baz(x) }. At the time of your review, the dependencies would have been A -> bar, A -> baz and indeed the axiom would have never been included in the final Viper program. I changed the logic such that all usages occurring in a quantified expression are included if there is no use in one trigger. With my change, the dependencies for the example are A -> bar, A -> baz, bar -> A, baz -> A.

For the axiom axiom A { forall x: Int :: {bar(x) }{ Seq(x) } bar(x) > baz(x) } the dependencies were A -> bar, A -> baz, bar -> A before my change and are now A -> bar, A -> baz, bar -> A, baz -> A.

@Felalolf Felalolf merged commit 637723b into master Mar 11, 2024
5 checks passed
@Felalolf Felalolf deleted the fewolf_finer_chopper branch March 11, 2024 15:31
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.

3 participants