Re: [Haskell-cafe] Re: Proof question -- (==) over Bool

2010-05-24 Thread Daniel Fischer
On Monday 24 May 2010 15:48:14, Jonas Almström Duregård wrote:
> >Consider that calling
> >
> >> id undefined
> >
> >requires evaluating undefined before you can call id.  The program will
> > "crash" before you ever call id.  Of >course, the identity function
> > "should" have produced a value that crashed in exactly the same way. 
> > But we >never got there.
>
> In which sense does id need to evaluate its argument?

It doesn't need to, and it doesn't. It just returns its argument untouched.

> If evaluating
> the statement "id undefined" in ghci, then the print function (and
> ultimately the show function) evaluates the undefined. I suppose that
> if the show function does not evaluate its argument then there will be
> no error, right?

Right:

Prelude Text.Show.Functions> id undefined :: (Bool -> Bool)


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


Re: [Haskell-cafe] Re: Proof question -- (==) over Bool

2010-05-24 Thread Jonas Almström Duregård
>Consider that calling
>
>> id undefined
>
>requires evaluating undefined before you can call id.  The program will 
>"crash" before you ever call id.  Of >course, the identity function "should" 
>have produced a value that crashed in exactly the same way.  But we >never got 
>there.

In which sense does id need to evaluate its argument? If evaluating
the statement "id undefined" in ghci, then the print function (and
ultimately the show function) evaluates the undefined. I suppose that
if the show function does not evaluate its argument then there will be
no error, right?

/Jonas

On 24 May 2010 09:05, Alexander Solla  wrote:
>
> On May 23, 2010, at 2:53 AM, Lennart Augustsson wrote:
>
>> BTW, the id function works fine on bottom, both from a semantic and
>> implementation point of view.
>
> Yes, but only because it doesn't work at all.  Consider that calling
>
>> id undefined
>
> requires evaluating undefined before you can call id.  The program will
> "crash" before you ever call id.  Of course, the identity function "should"
> have produced a value that crashed in exactly the same way.  But we never
> got there.
>
> It works in same way (==) works on bottoms.  Vacuously.  Indeed, functions
> only work on values.  There is no value of type (forall a . a).  Ergo, id
> does not work on undefined, as a function applying to a value.  It is happy
> coincidence that the behavior of the runtime can be made mostly compatible
> with our familiar semantics.  But not entirely.
>
> Consider:
>
> *Main> let super_undefined = super_undefined
> *Main> undefined == super_undefined
> *** Exception: Prelude.undefined
> *Main> super_undefined == super_undefined
> (wait forever)
> *Main> id super_undefined
> (wait forever)
> *Main> id undefined
> *** Exception: Prelude.undefined
>
> From a mathematical perspective, super_undefined is Prelude.undefined.  But
> it takes some runtime level hackery to make undefined an exceptional
> "value".  Without it, super_undefined loops, despite the fact that their
> definitions are exactly the same  (The "value" defined by itself).
>
> I did not suggest those are the wrong semantics.  Only that the study of
> their semantics doesn't belong to the study of Haskell as a logic/language.
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Proof question -- (==) over Bool

2010-05-24 Thread Lennart Augustsson
That's totally false.  You don't evaluate 'undefined' before calling 'id'.
(Or if you, it's because you've made a transformation that is valid
because 'id' is strict.)


On Mon, May 24, 2010 at 9:05 AM, Alexander Solla  wrote:
> Yes, but only because it doesn't work at all.  Consider that calling
>
>> id undefined
>
> requires evaluating undefined before you can call id.  The program will
> "crash" before you ever call id.  Of course, the identity function "should"
> have produced a value that crashed in exactly the same way.  But we never
> got there.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Proof question -- (==) over Bool

2010-05-24 Thread Jon Fairbairn
Alexander Solla  writes:

> On May 23, 2010, at 1:35 AM, Jon Fairbairn wrote:
>
>> It seems to me relevant here, because one of the uses to which
>> one might put the symmetry rule is to replace an expression “e1
>> == e2” with “e2 == e1”, which can turn a programme that
>> terminates into a programme that does not.
>
> I don't see how that can be (but if you have a counter
> example, please show us). 

Oops! I was thinking of the symmetry rule in general. What I
said applies to “a && b” and not to “a == b”, but my point was
that surely you can’t be sure of that until after you’ve
finished a proof that does consider ⊥?

-- 
Jón Fairbairn jon.fairba...@cl.cam.ac.uk
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2009-01-31)

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


Re: [Haskell-cafe] Re: Proof question -- (==) over Bool

2010-05-24 Thread Alexander Solla


On May 23, 2010, at 2:53 AM, Lennart Augustsson wrote:


BTW, the id function works fine on bottom, both from a semantic and
implementation point of view.


Yes, but only because it doesn't work at all.  Consider that calling

> id undefined

requires evaluating undefined before you can call id.  The program  
will "crash" before you ever call id.  Of course, the identity  
function "should" have produced a value that crashed in exactly the  
same way.  But we never got there.


It works in same way (==) works on bottoms.  Vacuously.  Indeed,  
functions only work on values.  There is no value of type (forall a .  
a).  Ergo, id does not work on undefined, as a function applying to a  
value.  It is happy coincidence that the behavior of the runtime can  
be made mostly compatible with our familiar semantics.  But not  
entirely.


Consider:

*Main> let super_undefined = super_undefined
*Main> undefined == super_undefined
*** Exception: Prelude.undefined
*Main> super_undefined == super_undefined
(wait forever)
*Main> id super_undefined
(wait forever)
*Main> id undefined
*** Exception: Prelude.undefined

From a mathematical perspective, super_undefined is  
Prelude.undefined.  But it takes some runtime level hackery to make  
undefined an exceptional "value".  Without it, super_undefined loops,  
despite the fact that their definitions are exactly the same  (The  
"value" defined by itself).


I did not suggest those are the wrong semantics.  Only that the study  
of their semantics doesn't belong to the study of Haskell as a logic/ 
language.

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


Re: [Haskell-cafe] Re: Proof question -- (==) over Bool

2010-05-23 Thread Lennart Augustsson
For Bool, I'm not sure, but for, e.g., () it's certainly true.
Take this definition of ==
  () == _  =  True
Using case analysis of just the constructors, ignoring the value
bottom, you can easily prove symmetry.
But '() == undefined' terminates, whereas 'undefined == ()' does not.

Ignore bottom at your own peril.

BTW, the id function works fine on bottom, both from a semantic and
implementation point of view.

  -- Lennart

On Sun, May 23, 2010 at 11:23 AM, Alexander Solla  wrote:
>
> On May 23, 2010, at 1:35 AM, Jon Fairbairn wrote:
>
>> It seems to me relevant here, because one of the uses to which
>> one might put the symmetry rule is to replace an expression “e1
>> == e2” with “e2 == e1”, which can turn a programme that
>> terminates into a programme that does not.
>
> I don't see how that can be (but if you have a counter example, please show
> us).  Even if we extend == to apply to equivalence classes of bottom values,
> we would have to evaluate both e1 and e2 to determine the value of e1 == e2
> or e2 == e1.
>
> Prelude> undefined == True
> *** Exception: Prelude.undefined
> Prelude> True == undefined
> *** Exception: Prelude.undefined
> Prelude> undefined == undefined
> *** Exception: Prelude.undefined
>
> That is, if one case is exceptional, so is the other.
>
> You can't really even quantify over bottoms in Haskell, as a language.  The
> language runtime is able to do some evaluation and sometimes figure out that
> a bottom is undefined.  Sometimes.  But the runtime isn't a part of the
> language.  The runtime is an implementation of the language's interpetation
> function.  Bottoms are equivalent by conceptual fiat (in other words,
> vacuously) since not even the id :: a -> a function applies to
> them.___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Proof question -- (==) over Bool

2010-05-23 Thread Alexander Solla


On May 23, 2010, at 1:35 AM, Jon Fairbairn wrote:


It seems to me relevant here, because one of the uses to which
one might put the symmetry rule is to replace an expression “e1
== e2” with “e2 == e1”, which can turn a programme that
terminates into a programme that does not.


I don't see how that can be (but if you have a counter example, please  
show us).  Even if we extend == to apply to equivalence classes of  
bottom values, we would have to evaluate both e1 and e2 to determine  
the value of e1 == e2 or e2 == e1.


Prelude> undefined == True
*** Exception: Prelude.undefined
Prelude> True == undefined
*** Exception: Prelude.undefined
Prelude> undefined == undefined
*** Exception: Prelude.undefined

That is, if one case is exceptional, so is the other.

You can't really even quantify over bottoms in Haskell, as a  
language.  The language runtime is able to do some evaluation and  
sometimes figure out that a bottom is undefined.  Sometimes.  But the  
runtime isn't a part of the language.  The runtime is an  
implementation of the language's interpetation function.  Bottoms are  
equivalent by conceptual fiat (in other words, vacuously) since not  
even the id :: a -> a function applies to them.___

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


[Haskell-cafe] Re: Proof question -- (==) over Bool

2010-05-23 Thread Jon Fairbairn
Alexander Solla  writes:

> On May 22, 2010, at 1:32 AM, Jon Fairbairn wrote:
>
>> Since Bool is a type, and all Haskell types include ⊥, you need
>> to add conditions in your proofs to exclude it.
>
> Not really.  Bottom isn't a value, so much as an expression
> for computations that don't refer to "real" values.  It's
> close enough to  be treated as a value in many contexts, but
> this isn't one of them.

It seems to me relevant here, because one of the uses to which
one might put the symmetry rule is to replace an expression “e1
== e2” with “e2 == e1”, which can turn a programme that
terminates into a programme that does not.

-- 
Jón Fairbairn jon.fairba...@cl.cam.ac.uk
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2009-01-31)

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


Re: [Haskell-cafe] Re: Proof question -- (==) over Bool

2010-05-22 Thread Jonas Almström Duregård
Note that "all (True ==)" is logically equivalent to "all id" and to
the "and" function from the prelude.

A more general approach based on type classes, the function taut takes
a boolean function and determines (by exhaustive search) if it is a
tautology:

class BooleanFunction a where
 taut :: a -> Bool

instance BooleanFunction Bool where
 taut = id

instance (Bounded a,Enum a, BooleanFunction b)
 => BooleanFunction (a -> b) where
 taut f = and $ map (taut . f) $ enumFrom minBound

unifier = taut transitivity

On 22 May 2010 19:37, Alexander Solla  wrote:
>
> On May 22, 2010, at 1:32 AM, Jon Fairbairn wrote:
>
> Since Bool is a type, and all Haskell types include ⊥, you need
> to add conditions in your proofs to exclude it.
>
> Not really.  Bottom isn't a value, so much as an expression for computations
> that don't refer to "real" values.  It's close enough to be treated as a
> value in many contexts, but this isn't one of them.
> Proof by pattern matching (i.e., proof by truth table) is sufficient to
> ensure that bottom (as a value) isn't included.  After all, the Bool type is
> enumerable.  At least in principle.
> So perhaps the constructive Haskell proof would go something like:
> -- Claim to prove
> transitivity :: Bool -> Bool -> Bool -> Bool
> transitivity x y z = if (x == y) && (y && z) then x == z else True
> -- "The" proof
> unifier :: Bool
> unifier = all (True ==) $ [ transitivity x y z | x <- [ True, False ]
>                                                , y <- [ True, False ]
>                                                , z <- [ True, False ] ]
> This includes some syntactic sugar R J might not be "entitled" to, but the
> intent is pretty clear.  We are programmatically validating that every
> assignment of truth values to the sentence "if (x == y) && (y && z) then x
> == z" is true.  (The theorem is "vacuously true" for assignments where the
> antecedent of the conditional is false)
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Proof question -- (==) over Bool

2010-05-22 Thread Alexander Solla


On May 22, 2010, at 1:32 AM, Jon Fairbairn wrote:


Since Bool is a type, and all Haskell types include ⊥, you need
to add conditions in your proofs to exclude it.


Not really.  Bottom isn't a value, so much as an expression for  
computations that don't refer to "real" values.  It's close enough to  
be treated as a value in many contexts, but this isn't one of them.


Proof by pattern matching (i.e., proof by truth table) is sufficient  
to ensure that bottom (as a value) isn't included.  After all, the  
Bool type is enumerable.  At least in principle.


So perhaps the constructive Haskell proof would go something like:

-- Claim to prove
transitivity :: Bool -> Bool -> Bool -> Bool
transitivity x y z = if (x == y) && (y && z) then x == z else True

-- "The" proof
unifier :: Bool
unifier = all (True ==) $ [ transitivity x y z | x <- [ True, False ]
   , y <- [ True, False ]
   , z <- [ True, False ] ]

This includes some syntactic sugar R J might not be "entitled" to, but  
the intent is pretty clear.  We are programmatically validating that  
every assignment of truth values to the sentence "if (x == y) && (y &&  
z) then x == z" is true.  (The theorem is "vacuously true" for  
assignments where the antecedent of the conditional is false)___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Proof question -- (==) over Bool

2010-05-22 Thread Jon Fairbairn
R J  writes:

> I'm trying to prove that (==) is reflexive, symmetric, and
> transitive over the Bools, given this definition:

> (==):: Bool -> Bool -> Bool
> x == y =  (x && y) || (not x && not y)

Since Bool is a type, and all Haskell types include ⊥, you need
to add conditions in your proofs to exclude it.

-- 
Jón Fairbairn jon.fairba...@cl.cam.ac.uk

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


[Haskell-cafe] Re: Proof question -- (==) over Bool

2010-05-22 Thread Maciej Piechotka
On Sat, 2010-05-22 at 00:15 +, R J wrote:
> I'm trying to prove that (==) is reflexive, symmetric, and transitive
> over the Bools, given this definition:
> 
> 
> (==)   :: Bool -> Bool -> Bool
> x == y =  (x && y) || (not x && not y)
> 
> 
> My question is:  are the proofs below for reflexivity and symmetricity
> rigorous, and what is the proof of transitivity, which eludes me?
>  Thanks.
>  
> Theorem (reflexivity):  For all x `elem` Bool, x == x.
> 
> 
> Proof:
> 
> 
>   x == x
>   ={definition of "=="}
>   (x && x) || (not x && not x)
>   ={logic (law of the excluded middle)}
>   True
> 

I'd add additional step:

x == x <=> (x && x) || (not x && not x) <=> x || not x <=> T
   def  A && A = A   A || not A = T

However it depends on your level - the more advanced you are the more
step you can omit.

> 
> Theorem (symmetricity):  For all x, y `elem` Bool, if x == y, then y
> == x.
> 
> 
> Proof:
> 
> 
>   x == y
>   ={definition of "=="}
>   (x && y) || (not x && not y)
>   ={lemma:  "(&&)" is commutative}
>   (y && x) || (not x && not y)
>   ={lemma:  "(&&)" is commutative}
>   (y && x) || (not y && not x)
>   ={definition of "=="}
>   y == x
> 
> 
> Theorem (transitivity):  For all x, y, z `elem` Bool, if x == y, and y
> == z,
> then x == z.
> 
> 
> Proof: ?
> 

For example by cases in Y (assume Y is true and prove it correct and
then assume Y is false and prove it correct. As in logic where there is
law of excluded middle Y have to be true or false it holds). It took
around 7 lines.



Regards


signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe