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

Allow more predictable type checking with totality assertions #3745

Open
nicolabotta opened this issue Apr 7, 2017 · 6 comments
Open

Allow more predictable type checking with totality assertions #3745

nicolabotta opened this issue Apr 7, 2017 · 6 comments

Comments

@nicolabotta
Copy link

The program

> %default total
> %auto_implicits off

> Foo : Type
> Bar : Foo -> Type
> foo : (x : Foo) -> Bar x -> Foo
> bar : (x : Foo) -> Bar x -> Foo -> Nat

> Pol : Type
> Pol = (x : Foo) -> Bar x

> val : Foo -> Pol -> Nat
> val = \ x => \ p => let y  = p x in
>                     let x' = foo x y in
>                     assert_total (bar x y x' `plus` val x' p)

> Opt : Pol -> Type
> Opt = \ p => (x : Foo) -> (p' : Pol) -> val x p' `LTE` val x p

> opt : Pol

> prf : Opt opt
> -- prf = \ x => \ p' => ?kika

type checks fine and almost immediately. But uncommenting the last line, type checking aborts after about 30 minutes.

I understand that this is due to the unjustified assert_total in val but still I am not sure that this is the expected behavior.

@edwinb
Copy link
Contributor

edwinb commented Apr 10, 2017

I think I would expect this, because you have a non terminating thing that you claim is total, so Idris has decided to trust you and evaluate it further. I guess it's aborting with some kind of fatal error?

@nicolabotta
Copy link
Author

nicolabotta commented Apr 10, 2017

Yes, idris --check gets killed by the OS after abot 30 minutes.

I agree that this can happen because of the unjustified assert_total, but I am wandering whether this should happen!

Here, there is no need to use the definition of val to deduce the type of the goal kika.

I have reported the issue because it is yet another facet of the issues that led to #3199: the type checker runs into a trouble because it tries to do more than it is actually needed.

You can see that this is the case by deferring the implementation of val. For instance

> %default total
> %auto_implicits off

> Foo : Type
> Bar : Foo -> Type
> foo : (x : Foo) -> Bar x -> Foo
> bar : (x : Foo) -> Bar x -> Foo -> Nat

> Pol : Type
> Pol = (x : Foo) -> Bar x

> val : Foo -> Pol -> Nat

> Opt : Pol -> Type
> Opt = \ p => (x : Foo) -> (p' : Pol) -> val x p' `LTE` val x p

> opt : Pol

> prf : Opt opt
> prf = \ x => \ p' => ?kika

> val = \ x => \ p => let y  = p x in
>                     let x' = foo x y in
>                     assert_total (bar x y x' `plus` val x' p)

type checks in a breeze and the goal kika is computed correctly.

@ahmadsalim
Copy link

@nicolabotta I certainly think that you are right in that this is a greyzone, and I can relate to the unpredictability in behaviour. If it is OK, I will close this as expected behaviour, since it is a result of an assertion and I am unsure whether there is a good way to account for them. If you or Edwin believe that the issue is important, please reopen it.

@nicolabotta
Copy link
Author

Ahmad, I believe that the issue should be re-opened. It is true that the behavior is triggered by an unjustified assertion, but this is not the point.

The point here is that the type checker gets stuck in performing operations that are not actually needed to type check the code. This can be demonstarted by deferring the point of definition of val as in my second example.

This is a fundamental deficiency of the type checker which was originally planned to be addressed with 1.0. Some weeks ago Edwin realized that type checking using whnf was not going to be a viable approach, see #3199.

The reported issue is just an instance of #3199 like #3246, #3358 and, I believe, #172!

@ahmadsalim ahmadsalim reopened this Apr 16, 2017
@ahmadsalim
Copy link

As you wish, I have reopened the issue. I unfortunately do not know enough about the intrinsics of the type checker to know how it should optimally be resolved.

@nicolabotta
Copy link
Author

@ahmadsalim Thanks Ahmad, I have of course no idea how the issue could be addressed but it seems counterintuitive that a code that type checks for every val : Foo -> Pol -> Nat does not type check for a specific value of val! Perhaps naively, I would expect that type checking is done in stages and that a stage in which definitions are used is only attempted after type checking based on type information alone has failed.

@ahmadsalim ahmadsalim changed the title Type checking aborts with unjustified assert_total directives Allow more predictable type checking with totality assertions May 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants