Skip to content

nunchaku fails to find a counterexample for a simple list-based map implementation #29

Open
@samuelgruetter

Description

@samuelgruetter

Versions:

  • nunchaku 0.5.1 70e5101
  • CVC4 version 1.5 (shipped with Isabelle 2017)

The following example

val K : type.
val V : type.

data tuple := pair K V.

data list :=
  nil
| cons tuple list.

data option :=
  None
| Some V.

rec get : list -> K -> option :=
  forall k. get nil k = None;
  forall ki vi k rest. get (cons (pair ki vi) rest) k =
    (if (ki = k) then Some vi else get rest k).

rec filter : (tuple -> prop) -> list -> list :=
  forall f. filter f nil = nil;
  forall f h t. filter f (cons h t) =
    (if (f h) then (cons h (filter f t)) else (filter f t)).

rec remove : list -> K -> list :=
  forall l k. remove l k = filter (fun t.
     match t with
     | pair ki vi -> ki != k
     end)
     l.

rec put : list -> K -> V -> list :=
  put = (fun l k v. cons (pair k v) (remove l k)).

val l: list.
val k1: K.
val k2: K.
val v: V.

# Missing hypothesis:
# axiom k1 != k2.

goal ~ (get (put l k1 v) k2 = get l k2).

returns UNKNOWN, even though a simple counterexample exists, as shown by nitpick in Isabelle2017:

theory ListMapTests
  imports Main
begin

typedecl K
typedecl V

datatype tuple = pair K V

datatype list = nil | cons tuple list

datatype option = None | Some V

fun get :: "list ⇒ K ⇒ option" where
  "get nil k = None" |
  "get (cons (pair ki vi) rest) k = 
    (if (ki = k) then Some vi else get rest k)"

fun filter :: "(tuple ⇒ bool) ⇒ list ⇒ list" where
  "filter f nil = nil" |
  "filter f (cons h t) =
     (if (f h) then (cons h (filter f t)) else (filter f t))"

fun remove :: "list ⇒ K ⇒ list" where
  "remove l k = filter (λ t. case t of pair ki vi ⇒ ki ≠ k) l"

fun put :: "list ⇒ K ⇒ V ⇒ list" where
  "put l k v = cons (pair k v) (remove l k)"

lemma "get (put l k1 v) k2 = get l k2"
  nitpick

which returns

Nitpick found a counterexample for card K = 2 and card V = 2:

  Free variables:
    k1 = K⇩1
    k2 = K⇩1
    l = nil
    v = V⇩1

I understand that nunchaku has not yet received as much development time as nitpick and the tools powering it, but do you have an estimate of how far nunchaku is away from being able to solve examples like this one? Or is there a simple change I can make to the input file so that it works?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions