Skip to content

More concise definition of absint_sound and absint_complete in AbstractInterpretation.v #37

Description

@mdempsky

I was reading AbstractInterpretation.v's definitions of absint_sound and absint_complete, and found them quite challenging to read because of the verbosity.

I thought I'd try rewriting it a bit to more closely match the book's statement of the algebraic laws, and I think it's a lot clearer:

Section absint_theorems.
  Variable A : absint.

  Infix "~" := A.(Represents) (at level 70, no associativity).
  Infix "⊔" := A.(Join) (at level 50).
  Notation "a ⊑ b" := (forall n, n ~ a -> n ~ b) (at level 70, no associativity).

  Infix "@+" := A.(Add) (at level 50).
  Infix "@-" := A.(Subtract) (at level 50).
  Infix "@*" := A.(Multiply) (at level 50).

  Record absint_sound : Prop := {
    TopSound   : forall n, n ~ A.(Top);
    ConstSound : forall n, n ~ A.(Constant) n;

    AddSound      : forall n m a b, n ~ a -> m ~ b -> (n + m) ~ (a @+ b);
    SubtractSound : forall n m a b, n ~ a -> m ~ b -> (n - m) ~ (a @- b);
    MultiplySound : forall n m a b, n ~ a -> m ~ b -> (n * m) ~ (a @* b);

    AddMonotone      : forall a b a' b', a ⊑ a' -> b ⊑ b' -> (a @+ b) ⊑ (a' @+ b');
    SubtractMonotone : forall a b a' b', a ⊑ a' -> b ⊑ b' -> (a @- b) ⊑ (a' @- b');
    MultiplyMonotone : forall a b a' b', a ⊑ a' -> b ⊑ b' -> (a @* b) ⊑ (a' @* b');

    JoinSoundLeft  : forall a b, a ⊑ (a ⊔ b);
    JoinSoundRight : forall a b, b ⊑ (a ⊔ b)
  }.

  (* Here's a "bonus" condition that we'll sometimes use and sometimes not:
   * [Join] gives a *least* upper bound of its two arguments, such that any other
   * upper bound is also at or above the join. *)
  Definition absint_complete := forall a b c, a ⊑ c -> b ⊑ c -> (a ⊔ b) ⊑ c.
End absint_theorems.

I wanted to use +^, -^, and *^ to more closely mimic the book's notation, but *^ is already used for transitive closures, and I couldn't figure out how to locally override that notation.

Notably, after rewriting it this way, I noticed that TopSound differs from the law stated on page 44 (forall a, a ⊑ A.(Top)). Though assuming ConstSound, the two statements are equivalent. That is, (forall n, n ~ A.(Constant) n) -> (forall n, n ~ A.(Top)) <-> (forall a, a ⊑ A.(Top)) is true. (Maybe this is obvious to others, but I found it at least worth formally proving.)

--

Of course, the statement could be further refactored; e.g., instead of adding helper notation for the operations, the soundness and monotone theorems could be abstracted like:

  Definition absop_sound natop absop := forall n m a b, n ~ a -> m ~ b -> (natop n m) ~ (absop a b).
  Definition absop_monotone absop := forall a b a' b', a ⊑ a' -> b ⊑ b' -> (absop a b) ⊑ (absop a' b').

--

Finally, I note that page 43 says 𝓒 and the abstract operations calculate the "most precise abstractions", but there's no formalization of this concept.

I believe the correct theorems are:

  Definition const_complete := forall n a, n ~ a -> A.(Constant) n ⊑ a.
  Definition absop_complete natop absop :=
    forall a b c, (forall n m, n ~ a -> m ~ b -> (natop n m) ~ c) -> (absop a b) ⊑ c.

None of the subsequent proofs actually rely on this, but for the purpose of proving an abstraction complete (e.g., #28), it might be worth including and then proving for at least parity_absint?

Edit: Also worth noting is that absop_sound and absop_complete together imply absop_monotone. (Again, probably expected, but I decided to formally verify.)

--

Happy to send a pull request for any of the above, but thought I'd file an issue first to check that it matches the intended direction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions