[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PVS-Help] TCC Question (Stack followup)



David Coppit wrote:
> Hello all,
> 
> This is a followup to my previous stack question. Suppose I defined a
> predicated subtype of Stack called Nonempty_Stack, in order to define
> the "top" operation on only nonempty stacks.
> 
> Now, later, I have a recursive function called multiple_push_pop:
> 
>   multiple_push_pop(s: Stack, values: list[Value]): RECURSIVE Stack =
>     IF (values = null) THEN
>       s
>     ELSE
>       LET (first_value, remaining_values) = (car(values), cdr(values)) IN
>         pop(multiple_push_pop(push(first_value,s), remaining_values))
>     ENDIF
>   MEASURE length(values)
> 
> I have a TCC now to prove that the result of the recursive call to
> multiple_push_pop(push(first_value,s), remaining_values) returns a
> nonempty stack:
> 
>   multiple_push_pop_TCC3 :
> 
>     |-------
>   {1}   FORALL (s: Stack, values: list[Value],
>                 v:
>                   [{z: [Stack, list[Value]] |
>                             length(z`2) < length(values)} ->
>                      Stack]):
>           NOT (values = null) IMPLIES
>            (FORALL (first_value: Value, remaining_values: list[Value]):
>               remaining_values = cdr(values) AND first_value = car(values)
>                IMPLIES
>                NOT is_empty?(v(push(first_value, s), remaining_values)))
> 
> How do I go about proving this?  Attached is the complete .pvs file.
> 

David,

You cannot prove this because it's not true. In the above TCC, v is
an arbitrary function of type [... -> Stack], so nothing guarantees
that v(push(first_value, s), remaining_values)) is non empty.

You have to change the type of multiple_push_pop so that
multiple_push_pop(s, value) is known to be non-empty when
s is non-empty. For example:

multiple_push_pop(s: Stack, values: list[Value]): RECURSIVE { u: Stack | equals(u, s) } =
    IF (values = null) THEN
       s
    ELSE
       LET (first_value, remaining_values) = (car(values), cdr(values)) IN
         pop(multiple_push_pop(push(first_value,s), remaining_values))
    ENDIF
  MEASURE length(values)

Then the TCCs should all be provable.

Bruno


> Thanks,
> David