Hi Conor and Peter,

Thanks a lot for the replies. They saved the day! While they exposed two bugs for you, they also exposed one for me: another program which was giving yellow marks (naive string matcher) was in fact not (provably) total, so epigram rightfully gave me '?'. Which got me thinking how to make it appear total. Options:

1. (easy) <= rec (append s os)
make the function recursive over the concatenation of the string and the original string (which I have to pass around as there is no mutual recursion). The length of these two together does decrease in all recursive calls, so epigram should be happy. Unfortunately, <= rec (append s os) won't work as far as I remember because the arg must be a variable. Though some auxiliary functions might help. Will try.

2. accessibility predicates (Edwin's thesis) uhhh-uhhh. He says the difficulty is in the termination proof, which I am inclined to believe, and I haven't attempted it yet.

3. making the function structural (also Edwin's thesis). This looks promising, I'll have a go at it later.

4. any other options?

I think I will have to read up on termination analysis! Thanks again for the replies.

Laszlo


Conor McBride wrote:

Hi Laszlo

Laszlo Nemeth wrote:

Hi,

Could somebody please explain what to do about yellow question marks? How can they arise in the first place? If I convinced the typechecker that my program is total, what can go wrong? I'm trying to debug my dead simple program(s): everything is green and yet all I get is '?'.



This usually means that the recursion-checker doesn't see why your recursive call is ok. (Bug #1, the recursion checker should leave suspicious calls with a yellow background, but it doesn't at the moment; your program goes green after typechecking a dummy function for the recursive call, then the machine tries to replace the dummy with an appeal to an inductive hypothesis.)


------------------------------------------------------------------------------
     ( eq : all a : A => all b : A => Bool ;  as, bs : List A !
let  !--------------------------------------------------------!
     !                 eqList eq as bs : Bool                 )

     eqList eq as bs <= rec as
     { eqList eq as bs <= case as
       { eqList eq nil bs <= case bs
         { eqList eq nil nil => true
           eqList eq nil (cons b bs) => false
         }
         eqList eq (cons a as) bs <= rec bs
         { eqList eq (cons a as) bs <= case bs
           { eqList eq (cons a as) nil => false
             eqList eq (cons a as) (cons b bs)
               => eqListaux (eq a b) (eqList eq as bs) false
           }
         }
       }
     }


Am I making some stupid mistake? Why don't I get a value?



You're not making a stupid mistake, but you are unnecessarily triggering the bug which is doing the real damage. Bug #2, if the recursion checker is faced with a choice of inductive hypothesis, it can sometimes commit too early to one possibility (I forget the circumstances where this happens; it was a pretty hairy and hasty hack.). Your <= rec bs is introducing such a choice, and it's disappearing down this hole. I agree that it shouldn't, but that's what happens just now.

The workaround is just to delete the <= rec bs node from your program. In any case, it isn't needed: recursion on the first argument is already enough. I just tried and it sorts out the problem.

Epigram 1's recursion checker was fairly rapidly thrown together from not quite the right pieces. It was what I had lying around at the time. Not too hard to send the thing the wrong way. Given how little time I have available for hacking, I'm afraid I can't promise to fix this bug. I can promise not to make the same bug in Epigram 2.

Many apologies

Conor


Reply via email to