Skip to content

Latest commit

 

History

History
38 lines (30 loc) · 1.42 KB

Relations.md

File metadata and controls

38 lines (30 loc) · 1.42 KB

The Relations module

The Relations module defines a number of properties on relations, where the relation is defined by a predicate that takes two values of the same type.

Example properties:

  • Reflexive: R(x,x) is true
  • Irreflexive: R(x,x) is false
  • AntiSymmetric: R(x,y) && R(y,x) ==> x==y
  • Transitive : R(x,y) && R(y,z) ==> R(x,z)
  • Connected : x != y ==> R(x,y) || R(y,x)
  • StronglyConnected : R(x,y) || R(y,x)
  • TotalOrdering : Reflexive, AntiSymmetric, Transitive, StronglyConnected (e.g., <= on integers)
  • StrictTotalOrdering : Irreflexive, AntiSymmetric, Transitive, Connected (e.g., < on integers)

These properties are sometimes required for other functions. For example, if one wants to sort a sequence by some relation R, one must establish that R is a Total Ordering or a Strict Total Ordering. In fact, that is part of the precondition of a sorting function.

As a simple example, you might define a predicate like this:

  const IntLT := ((i: int, j: int) => (i < j))

and then need to prove this lemma to use it in a sorting routine:

  import opened Std.Relations
  lemma IntLTisStrictTotalOrder()
    ensures StrictTotalOrdering(IntLT) {}

Fortunately, Dafny proves this without aid.

All these definitions are ghost predicates; they are used as part of proofs rather than in compiled code.