В newLISP'е функции and и or принимают произвольное (включая ноль) число аргументов и работают в согласии со здравым смыслом, а именно:
- "ложью" считаются nil и/или пустой список, все остальное "истина",
- and ложна, если у нее хотя бы один ложный аргумент, иначе истинна;
- or истинна, если у нее хотя бы один истинный аргумент, иначе ложна.
Например:
> (and)
true
> (and nil)
nil
> (and 10)
10
> (and "veni" "vidi" "vici")
"vici"
> (and nil 15)
nil
> (or)
nil
> (or nil)
nil
> (or 10)
10
> (or "veni" "vidi" "vici")
"veni"
> (or nil 15)
15
И вот я задумался: а как в том же духе определить xor? Известно, что для двух аргументов
(xor a b) <==> (and (or a b) (not (and a b)))
и кажется разумным для произвольного числа аргументов написать что-то вроде
(define (xor)
(and (apply or $args)
(not (apply and $args))))
Результат работы так определенной xor:
> (xor)
nil
> (xor nil)
nil
> (xor "hello")
nil
> (xor "hello" nil)
true
> (xor 1 2 3 4 5)
nil
> (xor 1 2 3 4 nil)
true
> (xor 1 2 3 nil nil)
true
Т.е. значение функции "ложь", если все аргументы одновременно истинны или одновременно ложны, иначе "истина".
Это правильно? Или у товарищей логиков есть возражения?
Upd.: И чтобы уж действительно "в духе ньюЛИСПа". Если поменять местами внутренние "накатывания" nand и or, то в случае "истины" функция будет возращать значение "решающего" аргумента, а не банальную true:
> (define (xor)
(and (not (apply and $args))
(apply or $args)))
> (xor nil 25)
25
> (xor nil (date))
"Sat Oct 19 04:48:01 2013"
> (xor nil "yep" (date))
"yep"
Upd. 2: Разумеется, это НЕправильно! Правильно --
здесь.
[
original post ] [
comments ]