3 ms·
The sum of an empty set is, in fact, 0 (the identity for addition). The generalized conjuction (we have a function called "all" for that) of an empty set is Tr
by vpetrovykh 7y ago
The sum of an empty set is, in fact, 0 (the identity for addition).
The generalized conjuction (we have a function called "all" for that) of an empty set is True (the identity for conjunction).
The generalized disjuction (we have a function called "any" for that) of an empty set is False (the identity for disjunction).
All of the above "sum", "all", and "any" are basically aggregate functions that operate on sets as a whole.
There is no special logic that you wouldn't get from considering these operations generalized for a set.
- ldb 7y agoThanks, that was helpful. However, I still think that having "sum(1,1,{})" returning "2" and "1+1+{}" returning "{}" can be viewed as somewhat inconsistent.
- vpetrovykh 7y agoLet me make a tiny correction to the expression you wrote: "sum({1, 1, {}})" - the function sum takes only one argument and it's a set. Because we flatten all "nested" sets, the expression "{1, 1, {}}" is equivalent to "{1} UNION {1} UNION {}". The expression "1 + 1 + {}" albeit valid grammatically, can be equivalently re-written as "{1} + {1} +{}". At this point it should be far more obvious why "sum({1} UNION {1} UNION {})" is not the same as "{1} + {1} + {}". Literals may be a little confusing because they look like elements, but they are still sets, singleton sets, specifically. There's practical value in simply thinking about "a bunch of things: A, B, C", where each of the A, B and C can themselves be empty, a single thing, or a bunch of things while ignoring nesting. In our case we allow duplication in these bunches (which is not part of the bunch theory: http://www.cs.toronto.edu/~hehner/bunch.pdf http://www.cs.toronto.edu/~hehner/bunch.pdf). However, because most people are familiar with sets we find it easier to keep using the terms "set" and "multi-set" (and stipulate that they are flattened) in explanations. In general, the way the operator "+" works is this: A + B = {a + b : for all a in A, for all b in B}. Whereas the expression "{A, B}" is defined to be equivalent to "A UNION B".
- ldb 7y agoGood explanation! (which indicates why the handling of empty sets is sometimes a bit confusing) One more question: What was the motivation behind defining "sum({})" to be "0" rather then "{}" ?
- vpetrovykh 7y agoOh, that's simple: sum(A UNION B) should be the same as sum(A) + sum(B) for any two sets A and B (or else there would be very weird inconsistencies). sum(A UNION {}) = sum(A) + sum({}) sum(A) = sum(A) + sum({}) 0 = sum({}) Typically for any operation generalized for a set the result of op({}) should be equal to the identity for that operation (0 for sum, 1 for product, True for AND, False for OR, etc.). It's always such a value I that for any other value A, A op I = A.
- ldb 7y agoAgain, a very nice explanation. However, from a practical point, I see the following problem: Assume that "Select sum(amount) FROM Payments;" calculates the balance for a customer account, and assume further that for some reason (e.g. a programming error) the amount column for that customer has been filled with "{}", then the above query would still return the well defined result "0" which might indicate that everything is correct (while it is no). This would not happen if "sum({a, b})" was defined as "{a} + {b}" (which is what a user would intuitively assume). However, this definition is also not very practical as any one occurence of {} in the sum would render the whole thing to {} (which is not what a user would expect). I guess the handling of "{}" will always stay a bit tricky.
- vpetrovykh 7y agoThis type of error is better remedied by making the balance property be required (so that it cannot be set to {} and produce an exception at the time the error is introduced). This way you will know about the error early enough. The point is that if an empty value is NOT valid then forbidding it at schema level is the best solution. So required keyword is going to do that for you. Alternatively, if making the property required is not possible due to some workflow constraints, you could do "SELECT Payment{customer} FILTER NOT EXISTS .balance" to find all payments (and the associated customer), which don't have any balance set. Then once you know what they are you might use "UPDATE" to fix the problem. Empty sets have fairly well-defined and consistent behavior w.r.t. functions (and operators). You learn it once and it applies in all contexts - specifically that empty sets are just sets like any other.