I was thinking of an hypothetical programming language with a kleenean
data type which would implement Kleene’s three-valued logic. To sum up, it’s an extension of the boolean data type with the three constants true
, false
and unknown
where unknown
means that the value is either true
or false
, but we don’t know which.
The truth tables for a kleenean type are well-known and the logic is quite easy to understand. However, I was wondering how one would design a conditional construct to take in account this unknown
value.
A basic if-then-else
conditional construct is almost always as follows:
if (boolean condition) then
condition is true, do something
else
condition is false, do some other thing
end
However, I have troubles seeing what a kleenean if
construct would look like. How could we interpret the unknown
constant? Technically speaking, it could satisfy the true
condition as well as the false
condition since it is one of these two. However, we can’t have it match any of those since it could be the other, it is not really true
nor false
.
Is there a well-known way to implement such a construct?
EDIT: To specify a little bit, I would prefere something different than the way boost::tribool
works, or from a simple switch
as if was an enum. Answers about quantum superposition and semantics are welcome.
9
However, I have troubles seeing what a kleenean
if
construct would look like.
It looks exactly like an ordinary if
. However, the semantics are slightly different. Instead of saying “if the condition is true, then this otherwise that”, it actually goes something like “if the condition is known to be true, then this otherwise that” (or perhaps “proven” instead of “known”, depending on which modality you prefer to use your kleenean logic to represent). This then means that you may want to have an operator for testing “is unknown/unproven” so that you can check for the third state, though that is not strictly necessary:
let boolvar = boolean condition
if (boolvar) then
# The true case...
elseif (not boolvar) then
# The false case...
else
# The unproven case...
fi
(Assuming that not unknown
is unknown
, of course.)
4
From what you said, unknown
represents represents true
or false
“at the same time”. You shouldn’t take it as another value, but as something special or exceptional.
If unknown
is passed into if
it becomes non deterministic which of the two code paths it should take. I think it is best to assume that passing unknown
into an if
should result in error.
But you should have way to detect if value is properly defined. Something like
if defined (boolean condition) then
condition is defined true or false, do something
else
condition is unknown, do some other thing
end
and there should be negated version of this, because you cannot use normal logic to invert the code paths to remove one of the branches for code clarity.
3
I’ve implemented this approach in the language I develop (then I removed this feature and switched to the boolean logic, as considered three-state logic not really useful).
A three-state logical could be converted to boolean transparently with the following rule:
The boolean value of the logical is
true
only when the logical value istrue
.
The unknown
and false
logical values correspond to the false
boolean.
To be able to work with three-state logicals, a set of unary operators could be used:
++
(is) – convert a logical operand to boolean value.
Just in a more verbose way than implicit conversion.--
(not) – result istrue
only when operand isfalse
.+-
(known) – result istrue
only when operand is eithertrue
orfalse
.-+
(unknown) – result istrue
only when operand isunknown
.
This way conditionals could be implemented to work with boolean conditions, as they use to. A logical could be used as boolean condition either transparently or explicitly. Different combinations of logical operators could be used to achieve the same goal, whatever suits best:
if (condition) {
// condition is true
} else if (--condition) {
// condition is false
} else {
// condition is unknown
}
if (-+condition) {
// condition is unknown
} else if (condition) {
// condition is true
} else {
// condition is false
}