Dafny: How can I quantify over the "contents" of a codatatype? - dafny

Background: I am trying to write parser combinators in Dafny. This requires working on very long lists which I do not want to fully compute unless they are needed, so I am using an IList instead of a seq in order to simulate lazy evaluation. The problem which I am having is that I cannot find a way to express an equivalent to forall x in sequence when working with ILists.
I'm defining IList in the same way as Dafny's documentation and tests:
codatatype IList<T> = Nil | Cons(head: T, tail: IList<T>)
I want to define an fmap function over ILists which allows partial functions. Here is my initial (incorrect) implementation:
function method fmap<S, T>(list: IList<S>, fn: S --> T): IList<T>
{
match list
case Nil => Nil
case Cons(s, rest) => Cons(fn(s), fmap(rest, fn))
}
This does not work, because the precondition to fn might not hold, and this is the root problem I'm trying to solve.
I tried to define a copredicate to express the concept of "forall" on infinite lists, and use that:
greatest predicate IListForall<T>(list: IList<T>, fn: T -> bool) {
match list
case Nil => true
case Cons(head, rest) => fn(head) && IListForall(rest, fn)
}
function method fmap<S, T>(list: IList<S>, fn: S --> T): IList<T>
requires IListForall(list, fn.requires)
{ /* body unchanged */ }
This makes fmap verify, but when I try to use fmap I can't find a way to make this precondition satisfied. It comes up when I try to define a mapping function which works on lists containing a certain type:
datatype Container<T> = Container(value: T)
function method fmapContainers<T, U>(cs: IList<Container<T>>, fn: T -> U):
IList<Container<U>>
{
fmap(cs, (container: Container) => Container(fn(container.value)))
}
The invocation of fmap here gives me the error possible violation of function precondition. This doesn't seem right to me. fn is total, and so is the lambda that I'm passing to fmap, so I don't think there should be any precondition in play? I've attempted to write fmapContainers a few different ways with no success, which makes me think that I messed up from the beginning when I tried to express forall as a copredicate.
Is there a better way to express forall than what I did?
footnote: fmapContainers might sound useless, but it's the simplest form of my actual problem. To explain my motivation, here's the full implementation that I'm trying to get working:
datatype OneParse<T> = OneParse(parsed: T, remainder: string)
datatype Result<T> = Failure | Success(forest: IList<OneParse>)
type parser<T> = string -> Result<T>
function method fmapSuccess<S, T>(result: Result<S>, fn: S --> T): Result<T>
requires result.Success?
{
Success(fmap(result.forest,
(one: OneParse<S>) => OneParse(fn(one.parsed), one.remainder)))
}
function method fmapParser<T, U>(p: parser<T>, fn: T --> U): parser<U> {
s => var result := p(s); match result
case Failure => Failure
case Success(forest) => fmapSuccess(result, fn)
}
I think I can figure out how to make the full solution work on my own if someone provides tips for implementing fmap and fmapContents, so this is just for context.

Problem here is greatest predicate (IListForall) is not proved for function (container: Container) => Container(fn(container.value)). This is trivial to prove
greatest lemma IListForallLemma<T, U>(cs: IList<T>, fn: T -> U)
ensures IListForall(cs, fn.requires)
{}
Now following code snippet verifies. I have made fmapContainers to method from function method to call above lemma.
codatatype IList<T> = Nil | Cons(head: T, tail: IList<T>)
greatest predicate IListForall<T>(list: IList<T>, fn: T -> bool)
{
match list
case Nil => true
case Cons(head, rest) => fn(head) && IListForall(rest, fn)
}
function method fmap<S, T>(list: IList<S>, fn: S --> T): IList<T>
requires IListForall(list, fn.requires)
{
match list
case Nil => Nil
case Cons(s, rest) => Cons(fn(s), fmap(rest, fn))
}
datatype Container<T> = Container(value: T)
greatest lemma IListForallLemma<T, U>(cs: IList<T>, fn: T -> U)
ensures IListForall(cs, fn.requires)
{}
method fmapContainers<T, U>(cs: IList<Container<T>>, fn: T -> U) returns (r: IList<Container<U>>)
{
IListForallLemma(cs, (container: Container) => Container(fn(container.value)));
r := fmap(cs, (container: Container) => Container(fn(container.value)));
}

Related

Why Dafny complains about this post condition "ensures ListMap(x => x + 1, Cons(1, Cons(2, Nil))) == Cons(2, Cons(3, Nil))", and how can it be fixed?

function method ListMap<T,X>(f : (T -> X), l : List<T>) : List<X>
ensures ListMap(x => x + 1, Cons(1, Cons(2, Nil))) == Cons(2, Cons(3, Nil))
{
match l {
case Nil => Nil
case Cons(n, l') => Cons(f(n), ListMap(f, l'))
}
}
Dafny raises two complaint here.
about "case Nil": A postcondition might not hold on this return path.
about "ensure...": This postcondition might not hold on a return path.
This snippet is from the book "Introducing Software Verification with Dafny Language: Proving Program Correctness", but I can't find the Errata for it.
There are two things here that you can solve at once:
The ensures won't terminate if computed (in an imaginary ghost environment) because you provide it as an intrinsic postcondition, so you will get into trouble.
Dafny is ok to ensure something about the output of the current function, but for everything other call to the function itself, it has to prove termination.
What you provide is an example of a postcondition, not a fact that ought to be known by every user of your ListMap function.
The solution is to refactor your ensures in a lemma:
datatype List<T> = Nil | Cons(t: T, tail: List<T>)
function method ListMap<T,X>(f : (T -> X), l : List<T>) : List<X>
{
match l {
case Nil => Nil
case Cons(n, l') => Cons(f(n), ListMap(f, l'))
}
}
lemma ListMapExample()
ensures ListMap(x => x + 1, Cons(1, Cons(2, Nil))) == Cons(2, Cons(3, Nil))
{
}

With closures as parameter and return values, is Fn or FnMut more idiomatic?

Continuing from How do I write combinators for my own parsers in Rust?, I stumbled into this question concerning bounds of functions that consume and/or yield functions/closures.
From these slides, I learned that to be convenient for consumers, you should try to take functions as FnOnce and return as Fn where possible. This gives the caller most freedom what to pass and what to do with the returned function.
In my example, FnOnce is not possible because I need to call that function multiple times. While trying to make it compile I arrived at two possibilities:
pub enum Parsed<'a, T> {
Some(T, &'a str),
None(&'a str),
}
impl<'a, T> Parsed<'a, T> {
pub fn unwrap(self) -> (T, &'a str) {
match self {
Parsed::Some(head, tail) => (head, &tail),
_ => panic!("Called unwrap on nothing."),
}
}
pub fn is_none(&self) -> bool {
match self {
Parsed::None(_) => true,
_ => false,
}
}
}
pub fn achar(character: char) -> impl Fn(&str) -> Parsed<char> {
move |input|
match input.chars().next() {
Some(c) if c == character => Parsed::Some(c, &input[1..]),
_ => Parsed::None(input),
}
}
pub fn some_v1<T>(parser: impl Fn(&str) -> Parsed<T>) -> impl Fn(&str) -> Parsed<Vec<T>> {
move |input| {
let mut re = Vec::new();
let mut pos = input;
loop {
match parser(pos) {
Parsed::Some(head, tail) => {
re.push(head);
pos = tail;
}
Parsed::None(_) => break,
}
}
Parsed::Some(re, pos)
}
}
pub fn some_v2<T>(mut parser: impl FnMut(&str) -> Parsed<T>) -> impl FnMut(&str) -> Parsed<Vec<T>> {
move |input| {
let mut re = Vec::new();
let mut pos = input;
loop {
match parser(pos) {
Parsed::Some(head, tail) => {
re.push(head);
pos = tail;
}
Parsed::None(_) => break,
}
}
Parsed::Some(re, pos)
}
}
#[test]
fn try_it() {
assert_eq!(some_v1(achar('#'))("##comment").unwrap(), (vec!['#', '#'], "comment"));
assert_eq!(some_v2(achar('#'))("##comment").unwrap(), (vec!['#', '#'], "comment"));
}
playground
Now I don't know which version is to be preferred. Version 1 takes Fn which is less general, but version 2 needs its parameter mutable.
Which one is more idiomatic/should be used and what is the rationale behind?
Update: Thanks jplatte for the suggestion on version one. I updated the code here, that case I find even more interesting.
Comparing some_v1 and some_v2 as you wrote them I would say version 2 should definitely be preferred because it is more general. I can't think of a good example for a parsing closure that would implement FnMut but not Fn, but there's really no disadvantage to parser being mut - as noted in the first comment on your question this doesn't constrain the caller in any way.
However, there is a way in which you can make version 1 more general (not strictly more general, just partially) than version 2, and that is by returning impl Fn(&str) -> … instead of impl FnMut(&str) -> …. By doing that, you get two functions that each are less constrained than the other in some way, so it might even make sense to keep both:
Version 1 with the return type change would be more restrictive in its argument (the callable can't mutate its associated data) but less restrictive in its return type (you guarantee that the returned callable doesn't mutate its associated data)
Version 2 would be less restrictive in its argument (the callable is allowed to mutate its associated data) but more restrictive in its return type (the returned callable might mutate its associated data)

Uncurrying curried Function in Swift

I have a function, which takes two arguments and returns a single value.
For example
func sum(x: Int, y: Int) -> Int {
return x + y
}
Next step is to use a currying to get a function which takes the only first argument and return a closure with an appropriate signature.
Also, I wrote a type alias to bring more clearness of the result type.
typealias EscapingClosure<A, B> = (A) -> B
func curry<A, B, C>(_ f: #escaping (A, B) -> C) -> EscapingClosure<A, (B) -> C> {
return { (a: A) -> ((_ b: B) -> C) in
return { (b: B) -> C in f(a, b) }
}
}
But then I remembered about uncurry function which should return a default sum function signature if I'll apply it on the curryied result.
So I tried to implement a variation of uncurry, and what I'll get at the result:
func uncarry<A, B, C>(_ f: #escaping EscapingClosure<A, (B) -> C>) -> (A, B) -> C {
return { (a: A, b: B) -> C in
return f(a)(b)
}
}
But here's a problem - I can't use this uncurry function with the result of currying on sum function, because uncurry requires only #escaping parameter where curryied function returns a non-escaping variation.
Here's a Swift compiler error:
Cannot convert value of type '((A) -> Void) -> ()' to expected argument type '(_) -> (_) -> _'
Does anyone know are there any ways to create uncurry function in Swift which would be applicable to the curryied function result.
Your uncurry function can do just that, uncurry curried functions:
let currableSum = curry(sum)
let uncurriedSum = uncurry(currableSum)
let add100 = currableSum(100)
print(add100(23)) // => 123
print(uncurriedSum(2, 2)) // => 4
The issue is that you're mistaking uncurrying for unapplying. Once you've partially or fully applied a curried function (or any function, for that matter), there's no mechanism to go back, to get the original function that produced the result.
uncurry(add100) // ❌ can't "unapply" a partially applied function
Imagine if that were the case. Every integer, string, and other value would have to remember a history of what functions caused it. I can't think of a single use case for that. For one, it would require dynamic typing (or forced compile-time casting in a static language like Swift), because you can't predict the signature of an arbitrary function that produces a given result.
As #Alexander write above, I can easily use uncurry function for curried result of the sum().
I just made an error when passed a result value of the curried function.

Erlang - Searching for tuples within tuples

Using Erlang, I have the following expression:
{add,{var,a},{mul,{num,2},{var,b}}}
and I am using lists:keymember to see whether the letter b is within the expression as such:
lists:keymember(b,2,[expr])
However, it doesn't look within the third tuple '{mul,{num,2},{var,b}' as that is a separate tuple. Is there a function that will search through the whole tuple and tuples within?
Thanks
As far I as I know there are no such functions. Probably you will have to implement some custom solution using recursion. Here is my example:
-module(test).
-compile(export_all).
find(_, []) -> false;
find(E, T) when is_tuple(T) ->
find(E, tuple_to_list(T));
find(E, [H|T]) ->
case find(E, H) of
false -> find(E, T);
true -> true
end;
find(V, E) -> V == E.
And usage:
1> test:find(b, {add,{var,a},{mul,{num,2},{var,b}}}).
true
2> test:find(b, {add,{var,a},{mul,{num,2},{var,c}}}).
false
Please review your code.
Line1: this is a tree, not a list.
Line2: expr is not a variable.
What you want to do is a visitor function, and you'll have to write it yourself.
A very good start would be to read this.

An element in a tuple or not in erlang?

I'd like to know if there is a function in Erlang can help me know whether an element is in a tuple or not. Like sets:is_element/2.
Tuple = {aaa,bbb,ccc}.
is_element_of_tuple(Tuple, aaa) % => true
is_element_of_tuple(Tuple, ddd) % => false
You can always transform the tuple to a list using tuple_to_list/1:
is_element_of_tuple(Tuple, Element) ->
lists:member(Element, tuple_to_list(Tuple)).
The simple answer is: no there is no function to do this. You have to write your own loop which traverses all the elements of a tuple until it either finds or does not find it. You an either convert the tuple to a list as above or write your own loop, something like:
is_element_of_tuple(E, Tuple) ->
is_element_of_tuple(E, Tuple, 1, tuple_size(Tuple)).
is_element_of_tuple(E, T, I, S) when I =< S ->
case element(I, T) of
E -> true;
_ -> is_element_of_tuple(E, T, I+1, S)
end;
is_element_of_tuple(_, _, _, _) -> false. %Done all the elements
Using a case and matching in this way means we check for exact equality, and it is probably a little faster than using =:= and checking if that returns true or false.

Resources