1

Section 11.1.2 of the Dafny Reference Manual provides these examples of extreme predicates:

inductive predicate g(x: int) { x == 0 || g(x-2) }
copredicate G(x: int) { x == 0 || G(x-2) }

Section 11.1.3 then gives a few example proofs about them:

lemma EvenNat(x: int)
  requires g(x)
  ensures 0 <= x && x % 2 == 0
{
  var k: nat :| g#[k](x); EvenNatAux(k, x);
}

lemma EvenNatAux(k: nat, x: int)
  requires g#[k](x)
  ensures 0 <= x && x % 2 == 0
{
  if x == 0 {
  } else {
    EvenNatAux(k-1, x-2);
  }
}

lemma Always(x: int)
  ensures G(x)
{ forall k: nat { AlwaysAux(k, x); } }
lemma AlwaysAux(k: nat, x: int)
  ensures G#[k](x)
{ }

These lemmas don't type-check. The prefix-call notation g#[k](x) triggers this error:

type mismatch for argument 0 (function expects ORDINAL, got nat)

The corresponding inductive lemma and colemma examples in section 11.1.4 work fine. My question is about 11.1.3.

This must have changed. Why are the ordinals a better choice than the naturals? Is it possible for the two types to produce different fix points, and if so, is the one produced for the ordinals really the least fix point?

I'm a bit worried that I might define an inductive predicate for something like

inductive predicate isProvable(x) {
    isAxiom(x) || exists w :: isProvable(w) && implies(w, x)
}

and have it turn out to mean something preposterous, permitting infinite chains of implies because the index is an ordinal. Am I wrong to worry?

Jason Orendorff
  • 42,793
  • 6
  • 62
  • 96

0 Answers0