Skip to content

Commit 13ef8ba

Browse files
committed
[ fix #1782 ] remove the case-specific code
I can't make sense of this code, it seems to try to convert the case function corresponding to `let (a, b) = f n in ...` into a different case function where `f n` and `(a, b)` have been unified. But if `f n` is a bona fide stuck computation, there's no chance of this happening. Just turning this off solves the #1782 and only breaks one function in the whole of the idris2 repo (I would have expected our current termination oracle to be too weak to detect it as valid anyway!) and one in frex (which, again, should not have been seen as terminating). Also fixes #1460
1 parent 207a604 commit 13ef8ba

File tree

8 files changed

+61
-16
lines changed

8 files changed

+61
-16
lines changed

libs/base/Data/List1.idr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,12 @@ snoc xs x = xs ++ (singleton x)
9494

9595
public export
9696
unsnoc : (xs : List1 a) -> (List a, a)
97-
unsnoc (h ::: Nil) = (Nil, h)
98-
unsnoc (h ::: (x :: xs)) =
99-
let (ini,lst) = unsnoc (x ::: xs)
100-
in (h :: ini, lst)
97+
unsnoc (x ::: xs) = go x xs where
98+
99+
go : (x : a) -> (xs : List a) -> (List a, a)
100+
go x [] = ([], x)
101+
go x (y :: ys) = let (ini,lst) = go y ys
102+
in (x :: ini, lst)
101103

102104
------------------------------------------------------------------------
103105
-- Reverse

src/Core/Termination.idr

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -383,13 +383,15 @@ mutual
383383
let fn = fullname gdef
384384
log "totality.termination.sizechange" 10 $ "Looking under " ++ show !(toFullNames fn)
385385
aSmaller <- resolved (gamma defs) (NS builtinNS (UN "assert_smaller"))
386-
cond [(fn == NS builtinNS (UN "assert_total"), pure []),
387-
(caseFn fn,
388-
do mps <- getCasePats defs fn pats args
389-
case mps of
390-
Nothing => pure Prelude.Nil
391-
Just ps => do scs <- traverse (findInCase defs g) ps
392-
pure (concat scs))]
386+
cond [(fn == NS builtinNS (UN "assert_total"), pure [])
387+
-- #1782: this breaks totality!
388+
-- ,(caseFn fn,
389+
-- do mps <- getCasePats defs fn pats args
390+
-- case mps of
391+
-- Nothing => pure Prelude.Nil
392+
-- Just ps => do scs <- traverse (findInCase defs g) ps
393+
-- pure (concat scs))
394+
]
393395
(do scs <- traverse (findSC defs env g pats) args
394396
pure ([MkSCCall fn
395397
(expandToArity arity

src/Libraries/Data/List1.idr

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ import Data.List1
66

77
-- TODO: Remove this, once Data.List1.unsnoc from base is available
88
-- to the compiler
9+
910
export
1011
unsnoc : (xs : List1 a) -> (List a, a)
11-
unsnoc (h ::: Nil) = (Nil, h)
12-
unsnoc (h ::: (x :: xs)) =
13-
let (ini,lst) = Libraries.Data.List1.unsnoc (x ::: xs)
14-
in (h :: ini, lst)
12+
unsnoc (x ::: xs) = go x xs where
13+
14+
go : (x : a) -> (xs : List a) -> (List a, a)
15+
go x [] = ([], x)
16+
go x (y :: ys) = let (ini,lst) = go y ys
17+
in (x :: ini, lst)

tests/Main.idr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ idrisTestsTotality = MkTestPool "Totality checking" [] Nothing
171171
["positivity001", "positivity002", "positivity003", "positivity004",
172172
-- Totality checking
173173
"total001", "total002", "total003", "total004", "total005",
174-
"total006", "total007", "total008", "total009", "total010"
174+
"total006", "total007", "total008", "total009", "total010",
175+
"total011"
175176
]
176177

177178
idrisTests : TestPool

tests/idris2/total011/Issue1460.idr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
%default total
2+
3+
nonproductive : Stream a -> (Stream a, ())
4+
nonproductive (x :: xs) =
5+
case nonproductive xs of
6+
(xs, ()) => (xs, ())

tests/idris2/total011/Issue1782.idr

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
total
2+
notHack : Nat -> (Nat, Nat)
3+
notHack Z = (Z, Z)
4+
notHack (S n) = let (baz1, baz2) = notHack n
5+
in (baz2, S baz1)
6+
7+
8+
total
9+
hack : Nat -> (Void, Void)
10+
hack n = let (baz1, baz2) = hack n
11+
in (baz1, baz2)

tests/idris2/total011/expected

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
1/1: Building Issue1782 (Issue1782.idr)
2+
Error: hack is not total, possibly not terminating due to recursive path Main.hack -> Main.hack
3+
4+
Issue1782:8:1--9:27
5+
8 | total
6+
9 | hack : Nat -> (Void, Void)
7+
8+
1/1: Building Issue1460 (Issue1460.idr)
9+
Error: nonproductive is not total, possibly not terminating due to recursive path Main.nonproductive -> Main.nonproductive -> Main.nonproductive
10+
11+
Issue1460:3:1--3:43
12+
1 | %default total
13+
2 |
14+
3 | nonproductive : Stream a -> (Stream a, ())
15+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16+

tests/idris2/total011/run

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
rm -rf build
2+
3+
$1 --no-color --console-width 0 Issue1782.idr --check
4+
$1 --no-color --console-width 0 Issue1460.idr --check

0 commit comments

Comments
 (0)