Czy istnieje słowo kluczowe lub operator dla „nor”?

56

Czy istnieje operator równoważny ani ? Na przykład moim ulubionym kolorem nie jest ani zielony, ani niebieski.

A kod byłby równoważny z:

// example one
if (color!="green" && color!="blue") { 

}

// example two
if (x nor y) {
    // x is false and y is false
}
1,21 gigawata
źródło
12
Nie, ponieważ już je mamy ori !ponieważ podwójne negatywy są rzadko używane - większość ludzi uważa je za szczególnie trudne do odczytania.
Kilian Foth,
70
@KilianFoth ma rację. Niemniej jednak opinie negatywne powinny dotyczyć złych pytań, a nie pytań, których nie lubimy. Co więcej, są już trzy głosy, aby zamknąć pytanie, ponieważ byłoby „oparte na opinii”, mimo że pytanie było całkowicie neutralne i nie było kontrowersyjne (albo są tacy operatorzy w jakimś egzotycznym języku, albo nie ma).
Christophe
3
Czy jest na to jakaś nazwa? Tak: ani. Czy to jest operator? W jakim języku? Biorąc pod uwagę język, możesz to sprawdzić w specyfikacjach / dokumentach.
jonrsharpe
9
@Troyer Twój komentarz pokazuje problem: źle zrozumiałeś logikę. ;) To nie jest równoważne z nor.
jpmc26
3
W językach z większą liczbą operatorów byłoby to (na przykład w python)color not in ['green', 'blue']
Izkata

Odpowiedzi:

72

Chociaż języki głównego nurtu nie mają dedykowanych operatorów NOR i NAND, niektóre mniej znane języki (na przykład niektóre języki „golfa”). Na przykład, APL ma oraz dla NOR i NAND odpowiednio.

Inną klasę przykładów można znaleźć w językach projektowania sprzętu, takich jak VHDL , Verilog itp. Bramki NAND i NOR są dość przydatne w projektowaniu sprzętu, ponieważ zwykle są tańsze (wymagające mniejszej liczby tranzystorów) niż równoważny obwód wykonany z AND / OR / NOT gates, który jest jednym z powodów, dla których języki projektowania sprzętu zawierają je; innym powodem jest to, że mogą być przydatne w przypadku niektórych sztuczek związanych z bitem.

koczownik
źródło
40
APL nie jest językiem golfowym , ale językiem zorientowanym na tablice, który pozwala na interaktywne tworzenie wieloparadowych aplikacji o pełnym stosie o sile przemysłowej.
Adám
59
@ Adám: Bingo .
Eric Duminil
6
@EricDuminil :-) To wszystko prawda.
Adám
20
@EricDuminil Nie, naprawdę. APL nie jest językiem golfowym, to praktyczny język, który okazuje się dobry w golfie. Perl jest pod tym względem podobny, nie?
Pavel
13
OP w rzeczywistości nie powiedział, że APL jest językiem „golfowym”.
Will Crawford,
46

Nie, nie ma noroperatora w żadnym głównym języku programowania wysokiego poziomu.

Dlaczego ?

Głównie dlatego, że trudno jest odczytać:

  • wymaga mentalnej kombinacji kilku operatorów („ i nie ” lub w bardziej literackim stylu: dalsze negatywne ”, „ każdy nieprawdziwy )
  • implikuje domyślnie notpierwszy operand, ale czytelnik rozumie to dopiero później
  • różni się od języków ludzkich, które używają wyraźnej negacji pierwszego argumentu, takiego jak „ ani x ani y ”, „ ani x ani y ”. Czytelnik może więc pomylić (x nor y)z (x and not y)zamiast((not x) and (not y))
  • niektórzy czytelnicy są myleni z oczywistym orsemantycznym, który nie ma zastosowania

Ale to tak powszechne w sprzęcie ...

norjest elementarną bramą sprzętową, której można użyć do wykonania wszystkich innych bram logicznych. Można więc argumentować, że wszystkie pozostałe operatory logiczne są kombinacjami i norsą najprostszym elementarnym operatorem logicznym.

Jednak to, co jest prawdziwe dla sprzętu, niekoniecznie musi być prawdziwe dla ludzi. I pomimo popularności na poziomie sprzętowym, niektóre procesory głównego nurtu nawet nie oferują NORw zestawie instrukcji asemblera (np. X86 ).

Alternatywy

Czytelność ma znaczenie. A czasem można to poprawić za pomocą innych środków.

Wykorzystanie istniejących operatorów

Na przykład:

if x not in [1,2]    // use of 'in' or 'not in' operator instead of x!=1 and x!=2

Porządkowanie warunków

if x==1 or x==2 
     action A
else 
     action B  

zamiast

if x!=1 and x!=2 
    action B
else 
    action A

Użyj pętli do

Niektóre języki oferują również instrukcje pętli, które pozwalają wyrazić warunki za pomocą whilelub za pomocą until, co pozwala wybrać bardziej „pozytywny” sposób. Instrukcje te są na przykład until c do ...w rubinie , do until c ...w czasowniku lub repeat ... until cw Pascalu i jego potomkach.

Na przykład:

Until (x==1 or x==2) do
     ...

jest równa:

While (x!=1 and x!=2)
    ...

Zrób funkcję

Teraz, jeśli nadal wolisz norskładnię, możesz zdefiniować funkcję, ale tylko jeśli nie spodziewasz się skrótu:

If ( nor(x,y) )   // attention, x and y will always be evaluated
    ...  

Funkcja ma przewagę pod względem czytelności nad operatorem, ponieważ czytelnik natychmiast rozumie, że negacja dotyczy wszystkich argumentów. W niektórych językach możesz zdefiniować funkcję o zmiennej liczbie argumentów.

Christophe
źródło
5
Zabawne, zwykle piszę to, ponieważ while (not (x == 1 or x == 2))uważam x != 1 and x != 2wersję za trudną do odczytania i stwierdzam, że „x nie jest ani 1, ani 2”, dużo łatwiejsze do przetworzenia niż „x nie jest 1, a x nie jest 2”.
Mael
1
@Baldrickk czy możesz opracować?
Mam nadzieję, że będzie
4
@HopefullyHelpful Repeat... Untilzawsze wykonuje ciało pętli przynajmniej raz. Jeśli x wynosi 1, ciało pętli jest nadal wykonywane, ale nie jest powtarzane. W Whiletym przypadku pętla nie wykonuje ciała.
sina
2
@Baldrickk tak masz całkowitą rację. Kiedy piszę odpowiednik, mówiłem tylko o warunku pętli, ponieważ operatory boolowskie były przedmiotem pytania. Dziękuję, przeredaguję to, aby wyjaśnić
Christophe
3
Wether x i y nor(x,y)są zawsze oceniane, zależy od języka i sposobu nor()implementacji. Istnieją języki (D, Io,…), w których wywoływana funkcja może decydować, czy i kiedy należy oceniać argumenty.
BlackJack
18

@ Komentarz KilianFoth do pytania jest na miejscu.

Można syntetyzować norod nota or:

if (x nor y)

jest dokładnie taki sam jak

if (not (x or y))

Wprowadzenie norjako osobnego operatora wprowadziłoby nadmiarowość języka, który nie jest ani potrzebny, ani pożądany (lub - który nie jest potrzebny i nie jest potrzebny).

Podobnie, nie znam żadnego języka z nandoperatorem - prawdopodobnie dlatego, że można go zsyntetyzować noti andoperatory.

Teoretycznie możesz stworzyć język z tylko nandlub tylko noroperatorami. Wszystko and, ori notmoże następnie przez synthesied od nich. Jedynym problemem jest to, że byłoby to absurdalnie niewygodne. Na przykład zobacz logikę NOR i logikę NAND na Wikipedii.

Mael
źródło
4
Zwolnienia mogą być również niepotrzebne lub potrzebne :)
Dave
@Dave Ten kalambur był zamierzony, cieszę się, że zauważyłeś ;-)
Mael
5
Same zwolnienia tak naprawdę nie wyjaśniają, dlaczego nornie są uwzględnione. W przeciwnym razie, dlaczego języki mają andi or? Są zbędne dzięki De Morganowi. W rzeczywistości, można zastąpić wszystkie trzy konwencjonalne operatorów logicznych ( and, or, not) poprzez dostarczanie tylko nor , jak pan słusznie zauważył.
Konrad Rudolph
1
@KonradRudolph Technicznie wszystko, czego potrzebujesz, to operator lambda . Powodem, dla którego robimy więcej, jest dopasowanie modelu mentalnego, jaki ma większość programistów. Większość programistów myśleć w kategoriach logiki and, ori not- ponieważ to, co najbardziej ludzkie języki użyciu. Po dopasowaniu modelu mentalnego i / lub / nie, wtedy ani & nand nie stają się zbędne. Ich nadmiarowość jest nawet zakodowana w ich nazwach: „n (ot) i” oraz „n (ot) lub”. Gdybyśmy mieli dla nich wyraźne, istniejące wcześniej angielskie terminy, a nie tylko syntezowane, prawdopodobnie zobaczyłbyś je częściej.
RM
1
Re redundancji jako argumentu: Są to języki z więcej niż not, and, or. Na przykład niektóre dialekty BASIC (GW-BASIC, QuickBASIC,…) mają wyłączność lub XOR, implikację IMP (→ NOT (x XOR y)) i równoważność EQV (→ NOT (x) OR y) jako dodatkowe operatory.
BlackJack,
11

Tak, APL i niektóre z jego dialektów nie mają ani (i nand ). W APL nie jest oznaczona (ponieważ jest albo i ~to nie )

 resultExampleOne color
  :If (color'green')⍱(color'blue')
      result'warm'
  :Else
      result'cold'
  :EndIf


 resultExampleTwo(x y)
  :If xy
      result'x is false and y is false'
  :Else
      result'at least one of them is true'
  :EndIf

Wypróbuj online!

Adám
źródło
10

Ta odpowiedź pochodzi z języka asemblera dla komputera wyprodukowanego w połowie lat sześćdziesiątych. To dość niejasne, ale pod pewnymi względami odpowiada na twoje pytanie.

DEC (Digital Equipment Corporation) wprowadził komputer PDP-6 w połowie lat sześćdziesiątych. Ta maszyna miała w sumie 64 instrukcje, które były operacjami logicznymi na dwóch operandach (w tym niektórych zdegenerowanych przypadkach). Te 64 instrukcje były tak naprawdę 16 operatorami z 4 wariantami w każdym operatorze.

Dwaj operatorzy, ANDCB i ORCB, zaimplementowali odpowiednio NOR i NAND (chyba że jestem zamieszany w podwójną logikę ujemną). Możesz zobaczyć tabelę opcode . Tabela opcode jest w rzeczywistości dla komputera PDP-10, następcy PDP-6.

Jeśli spojrzysz na instrukcję numeryczną w formacie binarnym, staje się ona bardziej interesująca. Okazuje się, że dla wszystkich kodów w zakresie 400–477 (ósemkowe) cztery bity w samej instrukcji zapewniają czterobitową tabelę prawdy dla 16 możliwych operatorów boolowskich. Niektórzy z tych operatorów ignorują jedno lub oba dane wejściowe. Na przykład SETZ i SETO ignorują oba wejścia.

Projektanci PDP-6 wykorzystali ten fakt, aby zaimplementować wszystkie te instrukcje z mniejszą logiką niż w przypadku wdrożenia tylko niektórych z nich. Niektóre z tych instrukcji pojawiały się rzadko, jeśli w ogóle, w kodzie języka asemblera. Ale wszyscy tam byli.

Więc ANDCB jest odpowiednikiem NOR. (ponownie, chyba że mam logikę wstecz, w którym to przypadku ORCB jest równoważne).

Walter Mitty
źródło
3

Perl ma unlesssłowo kluczowe, które pozwala odwrócić warunki warunkowe:

unless ($color eq 'green' or $color eq 'blue') {
    # code
}

Nie będąc operatorem NOR, możesz wyrazić swoje zamiary w podobny sposób.

Rory Hunter
źródło
3

norOperator, jak opisano to nie będzie powtarzalny, co musi prowadzić do wielu trudnych do wykrycia błędów.

Twój „Przykład 2” jest zasadniczo taki:

if (false nor false) {
becomes
if (true) {

Ale spróbuj ponownie, używając trzech zmiennych i zobacz, co się stanie:

if (false nor false nor false) {
becomes
if ((false nor false) nor false) {
becomes
if (true nor false) {
becomes
if (false) {
Buh Buh
źródło