논리적으로“또는”을 정의하는 방법


36

최근에 논리 "OR"연산자를 프로그래밍 방식으로 정의해야하지만 연산자 자체를 사용하지 않는 문제가 발생했습니다.

내가 생각해 낸 것은 이것입니다.

OR(arg1, arg2)
  if arg1 = True and arg2 = True
     return True

  else if arg1 = True and arg2 = False
     return True

  else if arg1 = False and arg2 = True
     return True

  else:
     return False

이 논리가 맞습니까, 아니면 뭔가 빠졌습니까?


10
@gnat : 공평하게, 진리표는 각 입력 조합에 대한 출력을 나열하고 Wikipedia 기사는 기능에 대한 설명을 제공합니다. OP가 실제로 요구하는 것은 연산자 자체를 사용하지 않고 프로그래밍 방식 으로 논리 OR을 정의하는 방법 입니다.
Blrfl

6
@ user3687688 우리가 사용할 수있는 프리미티브를 명확하게 설명해 주시겠습니까?
fredoverflow

4
이 질문은 미시 최적화의 집단적 경련을 시작했다;)
Rob

8
삼항 연산자를 사용할 수 있습니다return arg1 ? arg1 : arg2;
Matthew

4
or운영자 를 다시 정의해야하는 이유를 알고 있습니다 .
Kyle Strand

답변:


102

나는 그것이 맞다고 말하지만, 당신은 이것을 이와 같은 것으로 응축시킬 수 없습니까?

or(arg1, arg2)
    if arg1 == true
        return true
    if arg2 == true
        return true

    return false

당신이 또는 비교를하고 있기 때문에, 당신이 정말로 조합을 확인해야한다고 생각하지 않습니다. 그들 중 하나가 true를 반환하는 것이 사실이라면 그것은 중요합니다. 그렇지 않으면 우리는 거짓을 돌려주고 싶다.

덜 장황한 더 짧은 버전을 찾고 있다면 다음과 같이 작동합니다.

or(arg1, arg2)
    if arg1
        return arg1
    return arg2

6
라인 4에서 "else"를 제거 할 수도 있습니다 (단지 그대로두고 if arg2 == true).
도슨 토스

1
@DawsonToth 회전시킬 수있는 여러 가지 방법이 있습니다. 나는 다른 것에 만족할 것이지만 이것이 의사 코드 질문처럼 들리므로 명확성을 위해 이것을 이렇게 남겨 둘 것입니다. 그래도 사실입니다!
Elliot Blackburn

@BlueHat else를 사용하는 것이 약간 일치하지 않지만 마지막에는 else를 사용하지 않는 것 같습니다.
SBoss

1
@Mehrdad 감사합니다! 좀 더 장황하다고 느끼고 솔루션을 조금 더 명확하게 설명하기 때문에 이전 답변을 다시 포함 시켰습니다. 그러나 솔루션은 훨씬 작으며 동일한 작업을 수행합니다.
Elliot Blackburn

1
더 나은 (나쁜) :or(a, b): a ? a : b
사라

149

다음은 비교 및 ​​부울 리터럴이 있거나없는 솔루션입니다.

or(arg1, arg2)
  if arg1
    return arg1
  else
    return arg2

아마도 그보다 훨씬 더 근본적이지는 않을 것입니다.)


32
내 것보다 약간 더 짧은 답변은 +1입니다. 그러나 나는 우아함을 위해서도 "else"를 떨어 뜨리고 싶은 유혹을받습니다.
Elliot Blackburn

10
@BlueHat 그러나 두 수익은 다르게 들여 쓰기됩니다;)
fredoverflow

5
누군가가 true또는 에 대해 무언가를 비교할 때마다 EUR을 받고 싶습니다 false.
JensG

1
@JensG 글쎄, 빌 게이츠의 수입은 어디에서 나온 것 같아?
Kroltan

1
||간단히 말해서 JavaScript 연산자 (동적 형식 언어로 구현 된 경우).
rhino

108

한 줄의 코드 :

return not (not arg1 and not arg2)

분기가없고 OR이 없습니다.

C 기반 언어에서는 다음과 같습니다.

return !(!arg1 && !arg2);

이것은 단순히 De Morgan의 법칙을 적용한 것입니다 .(A || B) == !(!A && !B)


6
필자는이 접근 방식이 가장 좋은 해결책이라고 생각합니다. 제 생각에 if/else구성은 이름이 다른 OR을 사용하는 것과 동일하기 때문입니다.
Nick

2
@Nick 사용 if은 평등과 같습니다. 일반적으로 머신 코드에서 an if은 산술로 구현되고 점프와 함께 0과 비교됩니다.


1
나는 IFF and단락을 단락시켜 작업자들 사이에 일관성을 제공 하기 때문에이 접근법을 좋아합니다 .
Kyle Strand

1
@Snowman 사실입니다. 나는 if (a) return true; else if (b) return true;도덕적으로 어느 정도 도덕적으로 동등한 것으로 if (a OR b) return true;보이지만 그 견해는 논쟁의 여지가있을 수있다.
Nick

13

andand 만 가지고 있다면 notDeMorgan의 법칙을 사용하여 뒤집을 수 있습니다 and.

if not (arg1 = False and arg2 = False)
  return True
else
  return False

... 또는 (더 간단하게)

if arg1 = False and arg2 = False
  return false
else
  return true

...

그리고 우리는 거의 항상 기계 명령어로 거의 항상 사용할 수있는 것을 최적화하는 것에 고착되었으므로 다음과 같이 요약됩니다.

return not(not arg1 and not arg2)

return arg1 ? true : arg2

등 등등

대부분의 언어는 조건부 및 조건을 제공하므로 "and"연산자는 분기를 의미합니다.

...

모든 것이 있다면 nand( wikipedia 참조 )

반환 nand (nand (arg1, arg1), nand (arg2, arg2))


7
단순화 :return not (not arg1 and not arg2)

@ Snowman 당신은 정말로 그것을 대답해야합니다. 당신은 (현재) 분기와 가지 않은 유일한 사람입니다.
Lawtonfogle

4
NAND 솔루션을 추가하려고했지만 당신이 나를 이겼습니다. 모든 것은 NAND 측면에서 구현되어야합니다.
Andy

2
@Andy : 사실, 모든 것은 NOR로 정의되어야합니다. ;-)
Pieter Geerkens

1
순수한 nand솔루션으로 잘 작동 합니다.
AAT

13

기능 (ECMAScript)

함수 정의와 함수 호출 만 있으면됩니다. 분기, 조건부, 연산자 또는 내장 함수가 필요하지 않습니다. ECMAScript를 사용한 구현을 보여 드리겠습니다.

먼저 trueand 라는 두 함수를 정의 해 봅시다 false. 원하는 방식으로 정의 할 수 있지만 완전히 임의적이지만 나중에 볼 수있는 몇 가지 장점이있는 매우 특별한 방식으로 정의 할 것입니다.

const tru = (thn, _  ) => thn,
      fls = (_  , els) => els;

tru단순히 두 번째 인수를 무시하고 첫 번째를 반환하는 두 개의 매개 변수가있는 함수입니다. fls또한 첫 번째 인수를 무시하고 두 번째 매개 변수를 반환하는 두 개의 매개 변수가있는 함수입니다.

왜 우리는 인코딩 않았다 trufls이 방법은? 음, 이런 식으로, 두 함수는 두 개념을 나타내지 true하고 false즉, 아니, 같은 시간에, 그들은 또한 "선택"의 개념을 표현, 그들은 또한 있습니다 if/ then/ else표현! if조건을 평가하고 then블록과 else블록을 인수로 전달합니다. 조건이로 평가 tru되면 then블록 을 반환하고로 평가 fls하면 else블록 을 반환합니다 . 예를 들면 다음과 같습니다.

tru(23, 42);
// => 23

이 반환 23하고이 :

fls(23, 42);
// => 42

42예상 한대로를 반환합니다 .

그러나 주름이 있습니다.

tru(console.log("then branch"), console.log("else branch"));
// then branch
// else branch

이것은 인쇄 모두 then branchelse branch! 왜?

음, 반환 첫 번째 인수의 반환 값을하지만 평가 ECMAScript를가 엄격 항상 함수를 호출하기 전에 함수에 모든 인수를 평가하기 때문에, 두 인수를. IOW : 그것은 첫 번째 인자 평가 console.log("then branch")단순히 반환 undefined인쇄 및 부작용 갖는 then branch콘솔을, 그리고 는 번째 인자를 평가할 수도있는 복귀 undefined부작용 등 콘솔과 인쇄. 그런 다음 첫 번째를 반환합니다 undefined.

이 인코딩이 발명 된 λ- 미적분학에서는 문제가되지 않습니다 : λ- 미적분학은 순수합니다 . 즉, 부작용이 없습니다. 따라서 두 번째 인수도 평가됩니다. 또한 λ- 미적분은 게 으르 거나 (또는 ​​적어도 정상적인 순서로 평가되는 경우가 많음) 실제로 필요하지 않은 인수는 평가하지 않습니다. 그래서, IOW : λ- 미적분에서 두 번째 논증은 결코 평가되지 않을 것이며, 만약 그렇다면, 우리는 눈치 채지 못할 것입니다.

그러나 ECMAScript는 엄격합니다 . 즉, 항상 모든 인수를 평가합니다. 실제로 항상 그런 것은 아닙니다. 예를 들어, if/ then/ 는 조건이 조건 인 경우 에만 분기를 평가 하고 조건이 조건 인 경우 에만 분기를 평가합니다 . 그리고 우리는이 동작을로 복제하고 싶습니다 . 고맙게도 ECMAScript가 게으르지 않더라도 거의 모든 다른 언어와 마찬가지로 코드 조각의 평가를 지연시키는 방법이 있습니다. 함수로 감싸고 함수를 호출하지 않으면 코드는 절대로 처형되지 않습니다.elsethentrueelsefalseiff

따라서 함수에서 두 블록을 모두 래핑하고 마지막에 반환되는 함수를 호출합니다.

tru(() => console.log("then branch"), () => console.log("else branch"))();
// then branch

인쇄 then branch하고

fls(() => console.log("then branch"), () => console.log("else branch"))();
// else branch

인쇄합니다 else branch.

우리는 전통적인 구현할 수 if/ then/ else이런 식으로 :

const iff = (cnd, thn, els) => cnd(thn, els);

iff(tru, 23, 42);
// => 23

iff(fls, 23, 42);
// => 42

다시 말하지만, 위와 같은 이유로 iff의 정의에서 함수와 추가 함수 호출 괄호를 호출 할 때 추가 함수 랩핑이 필요합니다 iff.

const iff = (cnd, thn, els) => cnd(thn, els)();

iff(tru, () => console.log("then branch"), () => console.log("else branch"));
// then branch

iff(fls, () => console.log("then branch"), () => console.log("else branch"));
// else branch

이제이 두 가지 정의가 있으므로 구현할 수 있습니다 or. 첫 or번째 피연산자가 진실이면 표현식의 결과는 첫 번째 피연산자와 동일합니다. 그렇지 않으면 표현식의 결과는 두 번째 피연산자의 결과입니다. 간단히 말해 : 첫 번째 피연산자가 true이면 첫 번째 피연산자 를 반환하고, 그렇지 않으면 두 번째 피연산자를 반환합니다.

const orr = (a, b) => iff(a, () => a, () => b);

작동하는지 확인하십시오.

orr(tru,tru);
// => tru(thn, _) {}

orr(tru,fls);
// => tru(thn, _) {}

orr(fls,tru);
// => tru(thn, _) {}

orr(fls,fls);
// => fls(_, els) {}

큰! 그러나 그 정의는 약간 추악하게 보입니다. 기억, tru그리고 fls이미 그 자체로 조건부 모든처럼 행동 때문에 정말 필요가 없다 iff, 따라서 모든 기능 포장 모두에서 :

const orr = (a, b) => a(a, b);

거기에는 or함수 정의와 함수 호출만으로 몇 줄만 정의되어 있습니다 (다른 부울 연산자 포함).

const tru = (thn, _  ) => thn,
      fls = (_  , els) => els,
      orr = (a  , b  ) => a(a, b),
      nnd = (a  , b  ) => a(b, a),
      ntt = a          => a(fls, tru),
      xor = (a  , b  ) => a(ntt(b), b),
      iff = (cnd, thn, els) => cnd(thn, els)();

반환 인 ECMAScript에는 기능이나 운영자가없는 : 불행하게도,이 구현은 오히려 쓸모가 없다 tru거나 fls, 그들은 모두 반환 true또는 false우리는 우리의 기능을 사용할 수 있도록. 하지만 여전히 할 수있는 일이 많습니다. 예를 들어, 이것은 단일 연결 목록의 구현입니다.

const cons = (hd, tl) => which => which(hd, tl),
      car  = l => l(tru),
      cdr  = l => l(fls);

객체 (스칼라)

당신은 주목 뭔가 독특한이있을 수 있습니다 : trufls이중 역할을, 그들은 데이터 값 역할을 모두 true하고 false, 그러나 동시에, 그들은 또한 조건식 역할을합니다. 그들은있는 데이터행동 "일"... 하나 개 ... 음으로 번들 ... 나 (I는 말을 감히) 오브젝트를 !

사실, tru그리고 fls객체입니다. 그리고 Smalltalk, Self, Newspeak 또는 기타 객체 지향 언어를 사용한 적이 있다면, 동일한 방식으로 부울을 구현한다는 것을 알게 될 것입니다. 여기 스칼라에서 이러한 구현을 보여줄 것입니다.

sealed abstract trait Buul {
  def apply[T, U <: T, V <: T](thn: ⇒ U)(els: ⇒ V): T
  def &&&(other:Buul): Buul
  def |||(other:Buul): Buul
  def ntt: Buul
}

case object Tru extends Buul {
  override def apply[T, U <: T, V <: T](thn: ⇒ U)(els: ⇒ V): U = thn
  override def &&&(other:Buul) = other
  override def |||(other:Buul): this.type = this
  override def ntt = Fls
}

case object Fls extends Buul {
  override def apply[T, U <: T, V <: T](thn: ⇒ U)(els: ⇒ V): V = els
  override def &&&(other:Buul): this.type = this
  override def |||(other:Buul) = other
  override def ntt = Tru
}

object BuulExtension {
  import scala.language.implicitConversions
  implicit def boolean2Buul(b:Boolean) = if (b) Tru else Fls
}

import BuulExtension._

(2 < 3) { println("2 is less than 3") } { println("2 is greater than 3") }
// 2 is less than 3

이 BTW는 다형성 리팩토링으로 조건부 바꾸기가 항상 작동하는 이유입니다. 방금 보여 드렸듯이, 다형성 메시지 디스패치가 조건부를 간단히 구현하여 조건부를 대체 할 수 있기 때문에 프로그램의 모든 조건부를 다형성 메시지 디스패치로 항상 바꿀 수 있습니다. 스몰 토크, 셀프, 뉴스 피크와 같은 언어는 조건이 없기 때문에 존재 증거입니다. (또한 가상 메소드 호출이라고 불리는 다형성 메시지 디스패치를 ​​제외하고 루프, BTW 또는 실제로 어떤 종류의 언어 내장 제어 구조도 없습니다.)


패턴 매칭 (Haskell)

or패턴 일치 또는 Haskell의 부분 함수 정의와 같은 것을 사용하여 정의 할 수도 있습니다 .

True ||| _ = True
_    ||| b = b

물론 패턴 일치는 조건부 실행의 한 형태이지만 다시 객체 지향 메시지 디스패치입니다.


2
어떻게 약 False ||| False = False_ ||| _ = True대신? :)
fredoverflow

3
@FredOverflow : 항상 올바른 피연산자를 평가해야합니다. 일반적으로 부울 연산자는 "단락"이라는 올바른 인수로 엄격하지 않아야합니다.
Jörg W Mittag

아 물론 이죠 나는 더 깊은 이유가 있어야한다는 것을 알았습니다 :)
fredoverflow

첫 번째 부분은 연속 전달 스타일 에 대한 Eric Lippert의 위대한 시리즈를 즉시 상기시켜주었습니다 . 순전히 우연이지만 여전히 재미 :)
Voo

1
@ JörgWMittag FredOverflow의 정의는 적절하게 단락되었습니다. 시도 True ||| undefined볼 수 ghci에서 자신을!
Daniel Wagner

3

여기에 OR을 정의하는 가장 전통적인 방법을 사용하여 OR 또는 실제로 논리 연산자를 정의하는 다른 방법이 있습니다. 진리표를 사용하십시오.

물론 이것은 Javascript 또는 Perl과 같은 고급 언어에서는 매우 사소하지만 기술이 고급 언어 기능에 의존하지 않음을 보여주기 위해 C 로이 예제를 작성하고 있습니다.

#include <stdio.h>

int main (void) {
    // Define truth table for OR:
    int OR[2][2] = {
        {0,   // false, false
         1},  // false, true
        {1,   // true, false
         1}   // true, true
    }

    // Let's test the definition
    printf("false || false = %d\n",OR[1==2]['b'=='a']);
    printf("true || false = %d\n",OR[10==10]['b'=='a']);

    // Usage:
    if (OR[ 1==2 ][ 3==4 ]) {
        printf("at least one is true\n");
    }
    else {
        printf("both are false\n");
    }
}

AND, NOR, NAND, NOT 및 XOR로 동일한 작업을 수행 할 수 있습니다. 코드는 다음과 같은 작업을 수행 할 수 있도록 구문처럼 보일 정도로 깨끗합니다.

if (OR[ a ][ AND[ b ][ c ] ]) { /* ... */ }

나는 이것이 특정한 수학적 의미에서 "가장 순수한"접근법이라고 생각한다. OR 연산자는 결국 함수이며, 진리표는 실제로 관계 및 집합으로서 해당 함수의 본질입니다. 물론 이것은 재미있는 OO 방식으로도 작성 될 수 있습니다.BinaryOperator or = new TruthTableBasedBinaryOperator(new TruthTable(false, true, true, true));
COME FROM

3

논리 연산자를 정수 산술 표현식 (가능한 경우)으로 표현하는 또 다른 방법입니다. 이 방법은 많은 술어를 더 크게 표현하기 위해 많은 분기를 피할 수 있습니다.

True를 1로 설정 False를 0으로 설정

둘 다의 합이 1보다 크면 리턴되는 것이 참 또는 거짓입니다.

boolean isOR(boolean arg1, boolean arg2){

   int L = arg1 ? 1 : 0;
   int R = arg2 ? 1 : 0;

   return (L+R) > 0;

}

6
booleanExpression ? true : false사소하게 같습니다 booleanExpression.
Keen

나는 당신의 방법론을 좋아하지만 간단한 실수는 두 인수의 합이 1보다 크지 않고 ZERO보다 커야한다는 것입니다.
Grantly

1
return (arga+argb)>0
Grantly

1
난 당신의 텍스트를 수정했다. 코드는 완벽하지만 한 줄에있을 수 있습니다 : return (((arg1 ? 1 : 0)+(arg2 ? 1 : 0)) > 0); :)
Grantly

1
@SenthuSivasambu 나는 당신의 사용에 반대하지 않습니다 arg1 ? 1 : 0;. 부울을 숫자로 변환하기위한 신뢰할 수있는 표현식입니다. 사소하게 리팩터링 할 수있는 리턴 문 만 있습니다.
Keen

1

두 가지 형태 :

OR(arg1, arg2)
  if arg1
     return True
  else:
     return arg2

또는

OR(arg1, arg2)
  if arg1
     return arg1
  else:
     return arg2

지금까지의 다른 제안보다 약간 작은 코드 골프와 같은 장점이 있습니다. 따라서 매우 많이 사용되는 프리미티브의 생성을 고려하고 있다면 브랜치 수를 줄이는 것이 어리석은 선택조차 아닙니다.

자바 스크립트의 정의 ||식은 자사 낚아 입력 수단과 결합 된이, 가깝다 false || "abc"값을 보유 "abc"하고 42 || "abc"값을 갖는다 42.

다른 논리 연산자가 이미 있으면 nand(not(arg1), not(arg2))분기가 전혀 없다는 이점이 있습니다.


(응답 한대로) 이전 답변을 반복하는 요점은 무엇 입니까?
gnat

@ gnat 나는 그 대답을 보았을 때 귀찮게하지 않을 정도로 가깝지만 여전히 그들 중 어느 것도 발견 할 수없는 것을 가지고 있기 때문에 떠날 것입니다.
Jon Hanna

@gnat, 실제로 "우리는 설명과 맥락을 제공하는 긴 답변을 찾고 있습니다." 나는 지금이 대답에 더 행복하다.
Jon Hanna

1

if 구문을 사용하여 프로그래밍 된 모든 솔루션 외에도 3 개의 NAND 게이트를 결합하여 OR 게이트를 구성 할 수 있습니다. Wikipedia에서 어떻게 수행되는지 보려면 여기를 클릭하십시오 .

이것으로부터 표현은

NOT [NOT (A AND A) AND NOT (B AND B)]

NOT을 사용하고 AND는 OR과 동일한 대답을 제공합니다. NOT과 AND를 모두 사용하는 것은 NAND를 표현하는 모호한 방법 일뿐입니다.


NOT (A AND A) == NOT (A)?
Charlie

예, 정확히 동일한 Wikipedia 기사에서 NAND 게이트에 대한 NOT 게이트를 줄이는 방법을 볼 수 있습니다. AND 게이트에 대해서도 동일합니다. 나는 그들이 OR 게이트를 위해 제시 한 공식을 편집하지 않기로 선택했다.
Walter Mitty

1

모든 좋은 답변은 이미 주어졌습니다. 그러나 나는 그것을 멈추게하지 않을 것입니다.

// This will break when the arguments are additive inverses.
// It is "cleverness" like this that's behind all the most amazing program errors.
or(arg1, arg2)
    return arg1 + arg2
    // Or if you need explicit conversions:
    // return (bool)((short)arg1 + (short)arg2)

또는

// Since `0 > -1`, negative numbers will cause weirdness.
or(arg1, arg2)
    return max(arg1, arg2)

아무도 이와 같은 접근법을 실제로 사용하지 않기를 바랍니다. 그들은 대안에 대한 인식을 높이기 위해 여기에 있습니다.

최신 정보:

음수는 위의 두 가지 접근 방식을 모두 위반할 수 있으므로 여기에는 또 다른 끔찍한 제안이 있습니다.

or(arg1, arg2)
    return !(!arg1 * !arg2)

이것은 단순히 사용 드 모르 강의 법칙 과 학대 사실 *과 유사 &&할 때 truefalse같이 취급 1하고 0각각을. (잠깐, 이것이 코드 골프 가 아니라고 말하고 있습니까?)

여기에 알맞은 답변이 있습니다 :

or(arg1, arg2)
    return arg1 ? arg1 : arg2

그러나 그것은 이미 주어진 다른 답변과 본질적으로 동일합니다.


3
이러한 접근 방식은 근본적으로 결함이 있습니다. -1 + 1 arg1+arg2, -1 및 0 max(arg1,arg2)등 을 고려하십시오 .
fluffy

@fluffy이 접근법은 부울 인수를 가정 한 다음 대부분의 가비지 입력에서 올바르게 작동합니다. 여전히 문제가 발생하는 쓰레기가 있다는 것을 지적합니다. 이런 종류의 일이 실제로 우리가 실제 문제 영역을 가능한 한 직접적으로 (그리고 우리 자신의 영리함으로 인해 지워지지 않도록) 모델링해야하는 이유입니다.
Keen

순수한 1 비트 부울 값을 수행하는 경우 1 + 1 = 0이므로 더하기가 여전히 작동하지 않습니다. :)
fluffy

@fluffy 여기에서 명시적인 변환이 시작됩니다. 필요한지 여부는 구현의 세부 사항에 따라 다릅니다 (이것이 어리석은 생각 인 이유입니다).
Keen

0

정의하는 한 가지 방법 or은 조회 테이블을 이용하는 것입니다. 이를 명시 적으로 만들 수 있습니다.

bool Or( bool a, bool b } {
  bool retval[] = {b,true}; // or {b,a};
  return retval[a];
}

우리는 반환 값이 무엇인지에 따라 필요한 값으로 배열을 만듭니다 a. 그런 다음 조회를 수행합니다. C ++와 같은 언어에서, bool로 배열 인덱스로 사용할 수있는 값으로 촉진 true되고 1그리고 false0.

그런 다음이를 다른 논리 연산으로 확장 할 수 있습니다.

bool And( bool a, bool b } {
  bool retval[] = {false,b}; // or {a,b};
  return retval[a];
}
bool Xor( bool a, bool b } {
  bool retval[] = {b,!b};
  return retval[a];
}

이제이 모든 단점은 접두사 표기법이 필요하다는 것입니다.

namespace operators {
  namespace details {
    template<class T> struct is_operator {};
    template<class Lhs, Op> struct half_expression { Lhs&& lhs; };
    template<class Lhs, class Op>
    half_expression< Lhs, Op > operator*( Lhs&&lhs, is_operator<Op> ) {
      return {std::forward<Lhs>(lhs)};
    }
    template<class Lhs, class Op, class Rhs>
    auto operator*( half_expression<Lhs, Op>&& lhs, Rhs&& rhs ) {
    return invoke( std::forward<Lhs>(lhs.lhs), Op{}, std::forward<Rhs>(rhs) );
    }
  }
  using details::is_operator;
}

struct or_tag {};
static const operators::is_operator<or_tag> OR;

bool invoke( bool a, or_tag, bool b ) {
  bool retval[] = {b,true};
  return retval[a];
}

이제 입력 true *OR* false하면 작동합니다.

위의 기술에는 인수 종속 조회 및 템플릿을 지원하는 언어가 필요합니다. 당신은 아마 generics와 ADL을 가진 언어로 할 수 있습니다.

옆으로, *OR*세트로 작업 하도록 위를 확장 할 수 있습니다 . invoke다음과 같은 네임 스페이스에서 무료 함수 를 작성하십시오 or_tag.

template<class...Ts>
std::set<Ts...> invoke( std::set<Ts...> lhs, or_tag, std::set<Ts...> const& rhs ) {
  lhs.insert( rhs.begin(), rhs.end() );
  return lhs;
}

이제 set *OR* set둘의 합집합을 반환합니다.


0

이것은 저에게 특징적인 기능을 기억합니다.

or(a, b)
    return a + b - a*b

이것은 부울을 (1, 0)으로 취급 할 수있는 언어에만 적용됩니다. 부울은 클래스이므로 Smalltalk 또는 Python에는 적용되지 않습니다. 스몰 토크에서는 훨씬 더 나아갑니다 (의사 코드로 작성 됨).

False::or(a)
    return a

True::or(a)
    return self

그리고 두 가지 방법이 존재합니다.

False::and(a)
    return self

True::and(a)
    return a

따라서 "논리적"은 상세하지만 OP 문에서 완벽하게 유효합니다. 나쁘지 않습니다. 예를 들어 일종의 행렬을 기반으로 수학 연산자처럼 작동하는 함수가 필요한 경우에 적합합니다. 다른 사람들은 Quine-McCluskey 문과 같은 실제 큐브를 구현합니다.

or = array[2][2] {
    {0, 1},
    {1, 1}
}

그리고 당신은 평가하거나 [a] [b]

따라서 모든 논리가 유효합니다 (언어 OR 연산자 xDDDDDDDD를 사용하여 게시 된 것을 제외하고).

그러나 내가 가장 좋아하는 것은 DeMorgan의 법칙입니다. !(!a && !b)


0

Swift 표준 라이브러리를보고 바로 가기 OR 및 바로 가기 AND 연산의 구현을 확인하십시오 . 필요하지 않은 경우 두 번째 피연산자를 평가 하지 않습니다 .


-2

논리는 완벽하지만 간단 할 수 있습니다.

or(arg1, arg2)
  if arg1 = True
     return True
  else if arg2 = True
     return True
  else
     return False

아마도 귀하의 언어에는 OR 연산자가 있으므로 질문의 정신에 위배되지 않는 한 왜 안됩니까?

or(arg1, arg2)
  if arg1 = True or arg2 = True
     return True
  else
     return False

if arg1 = True or arg2 = True { return true } else { return false }더 나은 아직 return arg1 = True or arg2 = True. if condition then true else false중복됩니다.
Doval

4
asker는 그들의 요구 사항이 "운영자 자신을 사용하지 않고"라고 지적했다
gnat

2
음, 나는 아무 말도하지 않았습니다. 그것은 내가 의미 한 바 였지만 질문은 편집 될 때까지 그렇게 말하지 않았으며 그녀는 그와 같은 대답을했습니다.
logicNoob
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.