> The function needs to be total.  You seem to be using Haskell to execute
> a function to see if it terminates as a proof of totality.  Is that
> fair? This approach might work for some simple examples, but if the
> function doesn't terminate immediately then what?  I would assume that
> proof of
> totality would be an obligation of the person who constructed the
> function.

>> thm2 :: (Prop a -> Prop a) -> Prop a
>> thm2 f = Prop undefined

Prop is not total, but thm2 is (if I am not mistaken) total. Every non-_|_ f results in a non-bottom result (namely, Prop _|_).

My (still hesitant) assertion is that the totality must be transitive to all sub-expressions for the function to be considered a valid proof. The easiest way to get Haskell to do this work for you is to make everything strict and just evaluate the function.

Tim Newsham wrote:
I'm fairly new to this and struggling to follow along so I might
be a little off base here...

I assume you mean then that it is a valid proof because it halts for *some* argument? Suppose I have:

thm1 :: (a -> a) -> a
thm1 f = let x = f x in x

There is no f for which (thm1 f) halts (for the simple reason that _|_ is the only value in every type), so thm1 is not a valid theorem.

Now we reify our propositions (as the tutorial does) in a constructor:

data Prop a = Prop a

thm2 :: (Prop a -> Prop a) -> Prop a
thm2 f = Prop undefined

fix :: (p -> p) -> p
fix f = let x = f x in x

instance Show (Prop a) where
 show f = "(Prop <something>)"

*Prop> :t thm2
thm2 :: (Prop a -> Prop a) -> Prop a

*Prop> thm2 (fix id)
(Prop <something>)

Wow! thm2 halts. Valid proof. We have a "proof" (thm2 (fix id)) of a "theorem" (((Prop a) -> (Prop a)) -> (Prop a)), assuming that can somehow be mapped isomorphically to ((a -> a) -> a), thence to intuitionist logic as ((a => a) => a).

The function needs to be total. You seem to be using Haskell to execute a function to see if it terminates as a proof of totality. Is that fair? This approach might work for some simple examples, but if the function doesn't terminate immediately then what? I would assume that proof of
totality would be an obligation of the person who constructed the
function.  Using Haskell to prove termination for some simple cases might
be fair (in which case I see your point about avoiding a non-lazy
constructor), but it doesn't seem to be very general anyway.  If you're
relying on the programmer to provide proof of totality, then I don't
see the harm in using "Prop a" instead of "a".

That "somehow" in the tutorial seems to be an implied isomorphism from Prop a to a, so that proofs about (Prop a) can be interpreted as proofs about a. I hope to have shown that unless without constructors strict in their arguments that this is not valid.

My hypothesis was that

 data Prop a = Prop !a

justified this isomorphism. Or am I still just not getting it?

That would allow you to use the dynamic property (I observed termination)
to verify the static property (the function is total) in some situations,
right?  But the static property of totality shouldn't rely on evaluation
strategy, right?

Dan

Tim Newsham
http://www.thenewsh.com/~newsham/




_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to