Mailing List Archive

Newbie: Truth values (three-valued logic)
Hi everybody!

I am just starting to use python seriously. Currently, I am porting a
small class library from C++ to python, which is kind of fun. Everything's
much more simple and elegant now.

There's one thing I could do in C++, though, which doesn't seem to work in
python: some methods need to return truth values, which can be 1 for
'true', 0 for 'false' and x for 'frankly I don't know'. Now this x,
when used in an if-clause, should evaluate to false, which is easy:

class uncertain:
def __nonzero__(self):
return 0
def __repr__(self):
return 'dunno'

So the following works fine:

>>> maybe = uncertain()
>>> maybe
dunno
>>> if maybe: print 't' # prints nothing
...
>>>

Unfortunately:

>>> if not maybe: print 'f'
...
f
>>>

This behaviour is completely consistent in a two-valued logic, but not
what I actually want, because maybe should neither be true nor false, nor
should its negation. As far as I know, the logical negation operator can
not be overloaded, so I have no chance to change this, right? No big deal,
really, but I'd like to know if I missed something here. So, is there some
magical trickery to achieve the behaviour I want?

certainly-uncertain'ly yours, Olaf

--
//// Olaf Delgado Friedrichs, Uni Bielefeld, Mathematik
Olaf Postfach 100131 (room: V4-109)
`=' D-33501 Bielefeld, Germany (phone: +49 521 106-4765)
http://www.mathematik.uni-bielefeld.de/~delgado
Newbie: Truth values (three-valued logic) [ In reply to ]
Not exactly what you want I know. But None is close.

>>> not 0
1
>>> not None
1
>>>
... def myNot(x):
... if x != None:
... return not x
... return x
...
>>>
Newbie: Truth values (three-valued logic) [ In reply to ]
On Tue, 15 Jun 1999, Olaf Delgado wrote:

> This behaviour is completely consistent in a two-valued logic, but not
> what I actually want, because maybe should neither be true nor false, nor
> should its negation. As far as I know, the logical negation operator can
> not be overloaded, so I have no chance to change this, right? No big deal,
> really, but I'd like to know if I missed something here. So, is there some
> magical trickery to achieve the behaviour I want?

I don't believe so, due to the following bit in ceval.c:cmp_outcome:

case IS:
case IS_NOT:
res = (v == w);
if (op == (int) IS_NOT)
res = !res;
break;


In other words, the behavior of 'not' is based on the operation of C's !
operator on an int.

Of course, it could be changed (e.g. by adding a __not__ special hook),
but the added code complexity and speed hit would have to be justified.

Actually, after looking at the documentation for the operator module, I
think that there's a documentation problem -- reading it, one would think
that there is a __not__ special method, but it is not supported by the
core. I think a special comment should be added to the doc to that
effect.

--david ascher
Newbie: Truth values (three-valued logic) [ In reply to ]
David Ascher writes:
> Actually, after looking at the documentation for the operator module, I
> think that there's a documentation problem -- reading it, one would think
> that there is a __not__ special method, but it is not supported by the
> core. I think a special comment should be added to the doc to that

Done.


-Fred

--
Fred L. Drake, Jr. <fdrake@acm.org>
Corporation for National Research Initiatives
Newbie: Truth values (three-valued logic) [ In reply to ]
[Olaf Delgado]
> I am just starting to use python seriously. Currently, I am porting a
> small class library from C++ to python, which is kind of fun. Everything's
> much more simple and elegant now.

Except for C++ <wink>.

> There's one thing I could do in C++, though, which doesn't seem to work in
> python: some methods need to return truth values, which can be 1 for
> 'true', 0 for 'false' and x for 'frankly I don't know'.
> ... [but 'not' only delivers true or false] ...
> As far as I know, the logical negation operator can not be overloaded,
> so I have no chance to change this, right?

Right. I'd try overloading "~" instead (the unary prefix "complement"
operator, special method name __invert__):

>>> class uncertain:
def __nonzero__(self):
return 0
def __repr__(self):
return 'dunno'
def __invert__(self):
return self

>>> maybe = uncertain()
>>> if maybe or ~maybe:
print "maybe or not maybe!"
else:
print "we don't need no stinking excluded middle!"

we don't need no stinking excluded middle!
>>>

Under this hack, may work best if you use 0 to represent false and -1 to
represent true:

>>> ~0
-1
>>> ~-1
0
>>>

OTOH, overloading sucks when you have to fight the language -- and 90% of
the time even when you don't <0.9 wink>.

functions-spelled-as-functions-rarely-confuse-ly y'rs - tim
Newbie: Truth values (three-valued logic) [ In reply to ]
Hi again!

Thanks to everyone for giving hints.

On Wed, 16 Jun 1999, Tim Peters wrote:

> [Olaf Delgado]
> > I am just starting to use python seriously. Currently, I am porting a
> > small class library from C++ to python, which is kind of fun. Everything's
> > much more simple and elegant now.
>
> Except for C++ <wink>.

Right! C++ looks even more stupid.

> > As far as I know, the logical negation operator can not be overloaded,
> > so I have no chance to change this, right?
>
> Right. I'd try overloading "~" instead (the unary prefix "complement"
> operator, special method name __invert__):

I'll consider this. It came to my mind, though, that redefining negation
alone will not help. Next time I'll want to redefine 'and' and 'or'. So,
unless python 2 implements three-valued logic <hint, hint :)>, I'll have
to come up with a routine for myself to handle these truth values
consistently.

> OTOH, overloading sucks when you have to fight the language -- and 90% of
> the time even when you don't <0.9 wink>.

I agree. On the first hand, again, having to use function calls to
evaluate simple expressions increases the risk that I'll just do it the
usual (infix) way when I think it's save.

lisp-would-save-me-from-infix-temptation-ly your's, Olaf

--
//// Olaf Delgado Friedrichs, Uni Bielefeld, Mathematik
Olaf Postfach 100131 (room: V4-109)
`=' D-33501 Bielefeld, Germany (phone: +49 521 106-4765)
http://www.mathematik.uni-bielefeld.de/~delgado
Newbie: Truth values (three-valued logic) [ In reply to ]
On Wed, 16 Jun 1999 01:21:57 -0400, "Tim Peters"
<tim_one@email.msn.com> wrote:

>we don't need no stinking excluded middle!

Cool! Not cool! You're so right. That's completely wrong.

John
Newbie: Truth values (three-valued logic) [ In reply to ]
> Actually, after looking at the documentation for the operator module,
I
> think that there's a documentation problem -- reading it, one would
think
> that there is a __not__ special method, but it is not supported by the
> core. I think a special comment should be added to the doc to that
> effect.

Ah but should this change? This is not all that different
from rich comparisons! Shouldn't

not A<B

give the same result as

A>=B

(at least for appropriate A, B)? Of course then

A>B or A==B

should also give the same result.

Hey, if we're gonna get rich comparisons, let's go all
the way. But, as you say, you can't do it *now*.

-- Aaron Watters http://www.chordate.com

===

no plan.



Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
Newbie: Truth values (three-valued logic) [ In reply to ]
Olaf Delgado wrote:
>
> Next time I'll want to redefine 'and' and 'or'.

You could use '*' and '+', if you always know
when you're dealing with a 3-valued boolean
(troolean? trillian?).

By the way, I think Python 2.0 should let you define
new infix operators -- and design new characters to
represent them! We all have bitmapped screens now --
there's no reason why we should be restricted to a
fixed character set any more...

Greg
Newbie: Truth values (three-valued logic) [ In reply to ]
[Olaf Delgado]
> ...
> It came to my mind, though, that redefining negation alone will not
> help. Next time I'll want to redefine 'and' and 'or'. So, unless
> python 2 implements three-valued logic <hint, hint :)>, I'll have
> to come up with a routine for myself to handle these truth values
> consistently.

Well, "and" and "or" do short-ciruit evaluation (i.e., they don't evaluate
their right-hand operand at all if the value of their left-hand operand
suffices to determine the result). For that reason, they're more properly
viewed as control structures than operators, and so unlikely to get "opened
up" to user intervention.

But in the spirit of overloading "~" instead of "not", consider overloading
"&" and "|" instead of "and" and "or". Then you can do whatever you want.
If I were you I'd consider not overloading anything, and using ~ & |
directly with a naming trick, like so:

f, t, m = 0, -1, 42
name = {0: 'false', -1: 'true', 42: 'maybe', ~42: 'maybe'}

for x in f, t, m:
print "not", name[x], "=", name[~x]

for x in f, t, m:
for y in f, t, m:
print name[x], "and", name[y], "=", name[x & y]

for x in f, t, m:
for y in f, t, m:
print name[x], "or", name[y], "=", name[x | y]

This hacks around assigning two values to "maybe", just so that it's closed
under negation.

Or use false=0, true=1, maybe=0.5; map __invert_(x)=1-x;
__and__(x,y)=min(x,y); and __or__(x,y)=max(x,y). Then you get a nice little
MV logic with a whole bunch of possible "maybe" values. Once you go beyond
the first distinction (true/false), I don't know why you'd ever want to stop
<wink>.

the-notion-that-something-is-true-is-as-silly-as-the-notion-that-
something-is-false-ly y'rs - tim
Newbie: Truth values (three-valued logic) [ In reply to ]
On Fri, 18 Jun 1999, Tim Peters wrote:

> [Olaf Delgado]
> > ...
> > It came to my mind, though, that redefining negation alone will not
> > help. Next time I'll want to redefine 'and' and 'or'. So, unless
> > python 2 implements three-valued logic <hint, hint :)>, I'll have
> > to come up with a routine for myself to handle these truth values
> > consistently.
>
> Well, "and" and "or" do short-ciruit evaluation (i.e., they don't evaluate
> their right-hand operand at all if the value of their left-hand operand
> suffices to determine the result). For that reason, they're more properly
> viewed as control structures than operators, and so unlikely to get "opened
> up" to user intervention.

I understand that. A new meaning for "and" and "or" would have to be built
into the language, but I don't think the merits would justify the efforts.
The simplest way I see would be to introduce a new type with a single
value "Maybe", similar to "None", which would have to be handled specially
by "if", "not", "and" and "or". It should be relatively simple to
implement this, as far as I can see, but of course it would slow down
things by having to consider all those special cases.

> But in the spirit of overloading "~" instead of "not", consider overloading
> "&" and "|" instead of "and" and "or". Then you can do whatever you want.

Yes, I was thinking about something like this.


> If I were you I'd consider not overloading anything, and using ~ & |
> directly with a naming trick, like so:
>
> f, t, m = 0, -1, 42
> name = {0: 'false', -1: 'true', 42: 'maybe', ~42: 'maybe'}
[...]
> This hacks around assigning two values to "maybe", just so that it's closed
> under negation.

That's neat! It's quite intuitive, also. But let's say not overloading
anything but "__nonzero__()", which will return "1" only if there's not
a single bit of doubt. :)

> Or use false=0, true=1, maybe=0.5; map __invert_(x)=1-x;
> __and__(x,y)=min(x,y); and __or__(x,y)=max(x,y). Then you get a nice little
> MV logic with a whole bunch of possible "maybe" values. Once you go beyond
> the first distinction (true/false), I don't know why you'd ever want to stop
> <wink>.

Or I could set __and__(x,y)=x*y and __or__(x,y)=x+y-x*y. Then I only would
have to invent a way to partially execute a block of code. :)

Thanks for all the suggestions!

Truely (or maybe falsely?) yours,
Olaf

--
//// Olaf Delgado Friedrichs, Uni Bielefeld, Mathematik
Olaf Postfach 100131 (room: V4-109)
`=' D-33501 Bielefeld, Germany (phone: +49 521 106-4765)
http://www.mathematik.uni-bielefeld.de/~delgado
Newbie: Truth values (three-valued logic) [ In reply to ]
In article <000201beb946$b9c99e00$969e2299@tim>,
"Tim Peters" <tim_one@email.msn.com> wrote:
> [Olaf Delgado]
> > ...
> > It came to my mind, though, that redefining negation alone will not
> > help. Next time I'll want to redefine 'and' and 'or'. So, unless
> > python 2 implements three-valued logic <hint, hint :)>, I'll have
> > to come up with a routine for myself to handle these truth values
> > consistently.
>
> Well, "and" and "or" do short-ciruit evaluation (i.e., they don't
evaluate
> their right-hand operand at all if the value of their left-hand
operand
> suffices to determine the result). For that reason, they're more
properly
> viewed as control structures than operators, and so unlikely to get
"opened
> up" to user intervention.
>
> But in the spirit of overloading "~" instead of "not", consider
overloading
> "&" and "|" instead of "and" and "or". Then you can do whatever you
want.
> If I were you I'd consider not overloading anything, and using ~ & |
> directly with a naming trick, like so:
>
> f, t, m = 0, -1, 42
> name = {0: 'false', -1: 'true', 42: 'maybe', ~42: 'maybe'}

"Not maybe" equals to "not".
Imagine this case:
Maybe, I'll go to the cinema tomorrow.
If you say, not "maybe, I'll go to the cinema tomorrow", then you are
saying not to go the cinema. Imagine:
Johan: Maybe, we could go to the cinema tomorrow.
Anthony: No
Johan : ok, let's go to the zoo, to see that python.

I'd propose another solution, if we currently have:

class a:
def __init__():
pass
def __add__(c,d):
pass

e=a(); f=a()
h = e + f

why not :
class a:
....
def __or__(c,d):
pass
def __and__(e,f):
pass

you could even include three logic behaviour in the operator,
so if c = true d= true then __or__ returns true if it has certain
probability.
if c = true d= false returns true if a random value is greater than
0.34 ,...
...

Regards
Manolo


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
Newbie: Truth values (three-valued logic) [ In reply to ]
On Fri, 18 Jun 1999 mgutierrez@dss.es wrote:

> "Not maybe" equals to "not".
> Imagine this case:
> Maybe, I'll go to the cinema tomorrow.
> If you say, not "maybe, I'll go to the cinema tomorrow", then you are
> saying not to go the cinema. Imagine:
> Johan: Maybe, we could go to the cinema tomorrow.
> Anthony: No
> Johan : ok, let's go to the zoo, to see that python.

Okay, but this kind of intuitive semantics is not what I need here. The
negation of "Maybe, I'll go to the cinema tomorrow." should be "Maybe, I
wan't go to the cinema tomorrow.". By the way, this is IMO another,
stronger argument against hardwiring multi-valued logics into a
programming language. There may be different, equally justified views on
what the natural behaviour would be.

Undecidably yours,
Olaf

--
//// Olaf Delgado Friedrichs, Uni Bielefeld, Mathematik
Olaf Postfach 100131 (room: V4-109)
`=' D-33501 Bielefeld, Germany (phone: +49 521 106-4765)
http://www.mathematik.uni-bielefeld.de/~delgado
Newbie: Truth values (three-valued logic) [ In reply to ]
Olaf Delgado writes:

[three valued logic: one interpretation of "not maybe"]

> Okay, but this kind of intuitive semantics is not what I need here.
> The negation of "Maybe, I'll go to the cinema tomorrow." should be
> "Maybe, I wan't go to the cinema tomorrow.". By the way, this is IMO
> another, stronger argument against hardwiring multi-valued logics
> into a programming language. There may be different, equally
> justified views on what the natural behaviour would be.

Note that, if you want to retain DeMorgan's Laws, you don't have
much choice. ANSI SQL defines a three valued logic which meets these
conditions, and comes up with
NOT maybe == maybe
(well, NOT unknown == unknown), which makes sense as long as you
rmember that NOT is an operator, and the result of a non-trivial
operation on an unknown operand is probably unknown.

Which is why most DBA's won't allow NULL values in any column that
might be used in a WHERE clause - three valued logic is often
non-obvious.

Then there's fuzzy logic, where MAYBE is a whole range of values, and
the rules are different.

- Gordon
Newbie: Truth values (three-valued logic) [ In reply to ]
Hi All--

Greg Ewing wrote:
>
> Olaf Delgado wrote:
> >
> > Next time I'll want to redefine 'and' and 'or'.
>
> You could use '*' and '+', if you always know
> when you're dealing with a 3-valued boolean
> (troolean? trillian?).
>

Triskelion!

> By the way, I think Python 2.0 should let you define
> new infix operators -- and design new characters to
> represent them! We all have bitmapped screens now --
> there's no reason why we should be restricted to a
> fixed character set any more...
>

Ah, yes. I can see it now. Little Mayan glyphs peppering everyone's
screens. ``The "'Ahaw" operator is logically equivalent to the 'doit'
command in GNUScript.'' World domination is close!

<pop-goes-the-ahaw>-ly y'rs,
Ivan
----------------------------------------------
Ivan Van Laningham
Callware Technologies, Inc.
ivanlan@callware.com
http://www.pauahtun.org
See also:
http://www.foretec.com/python/workshops/1998-11/proceedings.html
Army Signal Corps: Cu Chi, Class of '70
----------------------------------------------
Newbie: Truth values (three-valued logic) [ In reply to ]
On Fri, 18 Jun 1999, Gordon McMillan wrote:

> Note that, if you want to retain DeMorgan's Laws, you don't have
> much choice. ANSI SQL defines a three valued logic which meets these
> conditions, and comes up with
> NOT maybe == maybe
> (well, NOT unknown == unknown), which makes sense as long as you
> rmember that NOT is an operator, and the result of a non-trivial
> operation on an unknown operand is probably unknown.
>
> Which is why most DBA's won't allow NULL values in any column that
> might be used in a WHERE clause - three valued logic is often
> non-obvious.

Well, NOT unknown == unknown seem perfectly obvious to me, but then I'm a
Mathematician and everyone knows we're strange guys.

Obviously yours,
Olaf

--
//// Olaf Delgado Friedrichs, Uni Bielefeld, Mathematik
Olaf Postfach 100131 (room: V4-109)
`=' D-33501 Bielefeld, Germany (phone: +49 521 106-4765)
http://www.mathematik.uni-bielefeld.de/~delgado
Newbie: Truth values (three-valued logic) [ In reply to ]
On Fri, 18 Jun 1999, Olaf Delgado wrote:
>On Fri, 18 Jun 1999, Tim Peters wrote:
>> [Olaf Delgado]
>I understand that. A new meaning for "and" and "or" would have to be
>built into the language, but I don't think the merits would justify the
>efforts. The simplest way I see would be to introduce a new type with
>a single value "Maybe", similar to "None", which would have to be
>handled specially by "if", "not", "and" and "or". It should be
>relatively simple to implement this, as far as I can see, but of course
>it would slow down things by having to consider all those special
>cases.

[snip]

>Or I could set __and__(x,y)=x*y and __or__(x,y)=x+y-x*y. Then I only
>would have to invent a way to partially execute a block of code. :)

Wasn't it Intercal which first had something like this?

if Maybe:
# do this some of the time
else:
# do this other times
# or is that do part of this, and part of that?

I think the first is fairly easy to hack up, but the second would
probably require some ByteCodeHacks (tm). Now I'm starting to be
interested in one-value logic. I'm just not sure whether I want the
value to be "True", "False", or "Maybe".

Later,
Blake.

--
One Will. One Dream. One Truth. One Destiny. One Love.
Newbie: Truth values (three-valued logic) [ In reply to ]
Tim Peters wrote:
>
> Well, "and" and "or" do short-ciruit evaluation (i.e., they don't evaluate
> their right-hand operand at all if the value of their left-hand operand
> suffices to determine the result). For that reason, they're more properly
> viewed as control structures than operators, and so unlikely to get "opened
> up" to user intervention.

It could be done if Python 2.0 gets lexical closures.
The __and__ and __or__ methods would get the value of
the left argument and a function for evaluating the
right argument. Then they could be lazy or not as
they pleased.

Greg