Earlier quoted context omitted.
That's the reason natural languages are not very well suited to formal logic, and one of the reasons programmers use programming languages. If we reframe it using C++ "std::all_of" function over an array of strings called "hats", and say that the following must be false (because he is a liar): std::all_of(hats.begin(), hats.end(), [](std::string hat) { return hat == "green"; }) Then we can answer the questions withou…
The question becomes why all_of returns true for an empty list. A better example would use std::accumulate and an 'and' function argument. The original STL documentation [1] described the function argument as having to model the Monoid[2] concept and have an identity value. The identity value for the 'and' Monoid is 'true'. [1] https://www.boost.org/sgi/stl/MonoidOperation.html [2] note: Monoid, not Monad, and yes, c…
Because it is, if you'll forgive my Haskell-ese, the only implementation that means that `all_of $ l1 ++ l2 == (all_of l1) && (all_of l2)` for all lists `l1` and `l2`, including empty ones.