Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple theorem can't be proven #1430

Closed
arpj-rebola opened this issue Apr 17, 2018 · 4 comments
Closed

Simple theorem can't be proven #1430

arpj-rebola opened this issue Apr 17, 2018 · 4 comments

Comments

@arpj-rebola
Copy link

The following fails to be shown (couldn't prove post-condition):

abstract val foo :
	a : Type ->
	Tot Type0
let foo a = 
	let _ = () in
	exists (x : a). True

val bar :
	a : Type ->
	Lemma (ensures (
		(foo a) <==> (exists (x : a). True)
	))
let bar a = ()

The part with let _ = () in is a workaround for #638 .

@cpitclaudel
Copy link
Contributor

The problem is the workaround, it seems; this works:

let foo a =
	exists (x : a). True

val bar :
	a : Type ->
	Lemma (ensures (foo a  <==>  (exists (x : a). True)))
let bar a = ()

@arpj-rebola
Copy link
Author

arpj-rebola commented Apr 18, 2018

Thanks, this works. However, the following does not:

val foo :
	a : Type ->
	Tot Type0
let foo a = 
	exists (x : a). True

val bar :
	a : Type ->
	Lemma (ensures (
		(foo a) <==> (exists (x : a). True)
	))
let bar a = ()

So the problem seems to be provoked by the first val. In the case where I intend to use this, the situation is a bit more complex: (EDIT)

val rel_compose :
	#a : Type ->
	#b : Type ->
	#c : Type ->
	g : (b -> c -> Tot Type0) ->
	f : (a -> b -> Tot Type0) ->
	Tot (a -> c -> Tot Type0)
let rel_compose #a #b #c g f = fun x z -> exists (y : b). True

val def_rel_compose :
	#a : Type ->
	#b : Type ->
	#c : Type ->
	g : (b -> c -> Tot Type0) ->
	f : (a -> b -> Tot Type0) ->
	Lemma (ensures ( forall (x : a) (z : c).
		((rel_compose #a #b #c g f) x z) <==> (exists (y : b). True)
	))
let def_rel_compose #a #b #c g f = ()

This is not proven as it is, and eliminating the val declaration leads to inconsistent qualifier errors.

@nikswamy
Copy link
Collaborator

Sorry, all of this is really ugly ... we're working hard to remove the logic qualifier and make use of prop more systematically. If you're curious, you can read about this at #1048

Meanwhile, here are a few workarounds ... I hope that at least one of them is applicable in your real code.

module Bug1430

//Alternative 1:
logic    //explicitly mark it as 'logic' to trigger an optimized SMT encoding
val foo :
        a : Type ->
        Tot Type0
let foo a =
  let _ = () in //workaround the brittle syntactic "inference" of the 'logic' qualifier
  exists (x : a). True

val bar :
        a : Type ->
        Lemma (ensures (
                (foo a) <==> (exists (x : a). True)
        ))
let bar a = ()


//Alternative 2: Avoid the `val`
let foo2 (a:Type) : Type0 = exists (x:a). True

val bar2 :
        a : Type ->
        Lemma (ensures (
                (foo2 a) <==> (exists (x : a). True)
        ))
let bar2 a = ()


//Alternative 3: Avoid the val and add `logic` since the body
//               is not syntactically recognized as a logic term
logic
let rel_compose
        (#a : Type)
        (#b : Type)
        (#c : Type)
        (g : (b -> c -> Tot Type0))
        (f : (a -> b -> Tot Type0)) = fun (x:a) (z:c) -> exists (y : b). True

val def_rel_compose :
        #a : Type ->
        #b : Type ->
        #c : Type ->
        g : (b -> c -> Tot Type0) ->
        f : (a -> b -> Tot Type0) ->
        Lemma (ensures ( forall (x : a) (z : c).
                ((rel_compose #a #b #c g f) x z) <==> (exists (y : b). True)
        ))
let def_rel_compose #a #b #c g f = ()


//Alternative 4: Avoid the val and rewrite the body to make the
//               brittle syntactic inference of the 'logic' qualifier
//               work
let rel_compose2
        (#a : Type)
        (#b : Type)
        (#c : Type)
        (g : (b -> c -> Tot Type0))
        (f : (a -> b -> Tot Type0)) (x:a) (z:c) = exists (y : b). True

val def_rel_compose2 :
        #a : Type ->
        #b : Type ->
        #c : Type ->
        g : (b -> c -> Tot Type0) ->
        f : (a -> b -> Tot Type0) ->
        Lemma (ensures ( forall (x : a) (z : c).
                ((rel_compose2 #a #b #c g f) x z) <==> (exists (y : b). True)
        ))
let def_rel_compose2 #a #b #c g f = ()

@aseemr
Copy link
Collaborator

aseemr commented May 14, 2018

All these examples work in master with the new way of inferring the logic qualifier (which is now deprecated). Adding these to the regressions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants