> Date: Sun, 08 Dec 2002 19:10:30 +1100
> From: Damian Conway <[EMAIL PROTECTED]>
>
> There are actually four types of junction:
> 
>       conjunction:   all(@elements)
>       disjunction:   any(@elements)
>       abjunction:    one(@elements)
>       injunction:   none(@elements)

Oh yeah...
 
> > represent the set:
> > 
> >     { 1, 2, 3 }
> > 
> > Which we will call N. Performing some 
> 
> ....unary...

Sure.  Any n-ary operation can be turned to unary with currying
anyway, right?

> > If that was a comparison operation, say C<{ $^x > 2 }>, the resultant
> > set would be:
> > 
> >     { undef, undef, 1 }
> 
> Err, no. The result is:
> 
>       { 1 }
> 
> Comparison of a junction returns those states for which the comparison is true.
> Furthermore, the resulting junction has a truth property assigned, according to
> the truth of the comparison. Furtherurthermore, the type of the rsulting junction
> is the same as the type of the junctive operand.

Yes, but I was trying to unify all kinds of operations.  +'s junctive
semantics would be no different from >'s, except for the actual
function they performed.

And that would work with the "truth of the comparison" thing you just
said, except that 0 is false, so -2 + 2 would not be included in the
junction.

I guess a small distinction between comparison (or boolean, I suppose)
and non-comparison is okay.

> I'm not sure that any of the above semantic changes are required. All that is
> needed is the define that logical operations on junctions return a junction of
> the states of the leftmost junctive operand for which the operation was true.
> And that the resultant junction be ascribed a C<true> or C<false> property
> according to the overall truth/falsehood of the comparison.

Again, under the condition that operations can be classified logical
and non-logical.  Ok.

> No. At present, the proposal is that n arithmetic operation between
> junctions produces a junction whose states are the distinct results
> of the operation applied pairwise to all possible combinations of
> states from each operand, and whose junctive type is the same as
> the left-most operand.

I can make a strong case against this behavior, at least:

  (2 | 3) + (5 & 6) > 8

In English: Does either 2 or 3 (or both) have the property that when
you add it to _both_ 5 and 6 you achieve a result greater than 8.  The
answer, of course is no.  However,

  (2 | 3) + (5 & 6) > 8
  7 | 8 | 9         > 8          # True!!! Counterintuitive.

Another:

Same example, with operands swapped:

  (5 & 6) + (2 | 3) > 8
  7 & 8 & 9         > 8          # False!!!

Ok, not only can it provide counterintuitive results, but it makes
communitive operators not commute.  That's Just Not Right.

And Another:

  one(1, 40) + any(3, 4) > 42

In English: Does either 1 or 40 (but not both) have the property that
with you add it to either 3 or 4 (or both) you achieve a result
greater than the answer to life, the universe, and everything :)
This time, it's true.  40 has this property, but not 1.  But,

  one(1, 40) + any(3, 4) > 42
  one(4, 5, 43, 44) > 42         # False!! Again, counterintuitive

> Presumably, under Luke's model:
> 
>       $C = foo($A, $B);
> 
> would be the same as:
> 
>       $C = foo(1,4)&foo(1,5)&foo(1,6) |
>            foo(2,4)&foo(2,5)&foo(2,6) |
>            foo(3,4)&foo(3,5)&foo(3,6);

Right.  Since junctions distribute (they'd better, lest I go
absolutely mad), that's equivalent to:

    $C = (foo(1,4)|foo(2,4)|foo(3,4)) &
         (foo(1,5)|foo(2,5)|foo(3,5)) &
         (foo(1,6)|foo(2,6)|foo(3,6));

And whether you come up with this or the other depends on whether you
evaluate $A or $B first.  Semantically, it doesn't matter either way.

> The semantics Luke suggests seem to be richer, but rely on the fixed
> precedence relationships between the various junctive types. I'd really
> like to (see someone else) explore how that expands to include abjunctions
> and injunctions, before I contemplated so fundamental a change in the
> semantics.

Um, what?  The semantics I suggested have nothing to do with the
lexical representation of junctions at all.  It's a purely logical
semantic.  Unless I'm misunderstanding you...

I'll show you an example of abjunctions.  Take my example from
earlier:  

    one(1, 40) + any(3, 4) > 42

This expands to:

    one(any(1+3, 1+4), any(40+3, 40+4)) > 42

Which is true.  If you happened to evaluate the any() first:

    any(one(3+1, 3+40), one(4+1, 4+40)) > 42

Again, true.  For the same reason too.

One thing I'd like to know is what none() means.  Does it mean
"anything but" or "when tested against each argument, is false".  I
assume the latter, for computational reasons.  In which case I have
Yet Another example:

    any(2, 3) + none(7) > 8

English:  When seven is added to either 2 or 3 (or both), is the
result not greater than 8?  The answer: no.

Under Quantum::Superpositions semantics:

    any(2, 3) + none(7) > 8
    any(9, 10)          > 8    # True! Wrong again.

Under logic/nested semantics:

    any(2, 3) + none(7)  > 8
    any(none(9), none(10)) > 8 # False

Explored (partially).

My overall argument for the semantics I proposed would be that: when
things get complex, it's better to have logically correct semantics
than locally DWIMmy ones.  For instance, in those nice recursive
functions that were shown here (by Brent? Dan? I don't remember).

The only problem that I see with them is that their structure could
get very big, very fast.  For junctions $a, $b, and $c with
sufficiently many states:

    $d = $a + $b + $c;
    # ... and later
    if $d < 10 {...}

Who would think that the comparison would take Θ(abc) time.  The
Quantum::Superpositions's time would be only O(abc).

> And which null set you use will depend on what you intend to do with it.
> For example, if you're accumulating "seen" values, the empty set you need
> to start with depends on whether they're conjunctively or disjunctively
> being "seen". That is:
> 
>       my $seen = any();
>       for <> {
>           next when $seen;
>              do_something_with($_);
>           $seen |= $_;
>       }

But it doesn't really matter, does it?  As you have shown, nested
junctions are useful.  Nesting the empty set in any form with a
junction of another type would be the same as just using that other
type in the first place.


> One might also contemplate C<none()> as the universal set. ;-)

On second thought, the different empty sets might not actually be
equivalent:

    any() < 10   # False  (∃x: x ∈ ∅ ∧ ?x)
    all() < 10   # True   (∀x: x ∈ ∅ ⇒ ?x)

Oh, dear.

Luke

Reply via email to