Як логічно визначити "чи"


36

Нещодавно я зіткнувся з проблемою, яка вимагала від мене програмного визначення логічного оператора "АБО", але без використання самого оператора.

Що я придумав, це:

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: Для справедливості таблиця істинності перераховує результати для кожної комбінації вхідних даних, а стаття у Вікіпедії дає опис функції. Я думаю, що насправді задає ОП, як визначити логічну АБО програмно без використання самого оператора.
Blrfl

6
@ user3687688 Чи можете ви прояснити примітиви, якими ми можемо користуватися?
fredoverflow

4
це питання започаткувало колективний спазм мікрооптимізації;)
Роб

8
Ви можете скористатися потрійним операторомreturn arg1 ? arg1 : arg2;
Метью

4
Я повинен знати, чому вам потрібно було переосмислити orоператора.
Кайл Странд

Відповіді:


102

Я б сказав, що це правильно, але чи не могли б ви звести це до такого, як це?

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

    return false

Оскільки ви робите або порівняєте, я не думаю, що вам дійсно потрібно перевіряти комбінацію. Просто важливо, чи є один з них вірним, щоб повернути правду. Інакше ми хочемо повернути помилкові.

Якщо ви шукаєте більш коротку версію, яка є менш дослівною, це також спрацює:

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

6
Ви також можете видалити "else" у рядку 4 (залишаючи лише if arg2 == true).
Доусон Тот

1
@DawsonToth Існує багато різних способів, як це можна зробити, залежно від того, чи справді ви хочете бути багатослівним або стисненим. Я був би задоволений іншим, якщо це звучить так, як це питання псевдокоду, тому я, мабуть, залишу це для наочності. Дуже правда, хоча!
Елліот Блекберн

@BlueHat Мабуть, трохи невідповідним є використання іншого, якщо, а не іншого в кінці.
SBoss

1
@Mehrdad Дякую! Я знову включив стару відповідь лише тому, що вважаю, що це трохи більш багатослівно і пояснює рішення крихітно трохи чіткіше. Але ваше рішення набагато менше і виконує ту саму роботу.
Елліот Блекберн

1
ще краще (гірше):or(a, b): a ? a : b
сара

149

Ось рішення без порівняння чи, та, ні, порівнянь та булевих літералів:

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

Це, мабуть, не стає набагато більш фундаментальним, ніж це;)


32
+1 для трохи коротшої відповіді, ніж моя. Однак я б спокусився скинути "ще" просто для елегантності.
Елліот Блекберн

10
@BlueHat Але тоді два повернення будуть
відрізані по-

5
Я хотів би отримати євро щоразу, коли хтось порівнює щось проти trueабо false.
JensG

1
@JensG Ну звідки ви думаєте, звідки береться дохід Білла Гейтса?
Кролтан

1
||Оператор JavaScript в двох словах (коли реалізований динамічно набраною мовою).
носоріг

108

Один рядок коду:

return not (not arg1 and not arg2)

Ні розгалуження, ні АБО.

Мовою на основі С це буде:

return !(!arg1 && !arg2);

Це просто застосування законів Де Моргана :(A || B) == !(!A && !B)


6
Я думаю, що цей підхід є найкращим рішенням, оскільки (на мій погляд) if/elseконструкція така ж, як і для використання АБО, просто з іншою назвою.
Нік

2
@ Nick використання ifрівносильно рівності. Зазвичай в машинному коді an ifреалізується як арифметична з подальшим порівнянням до нуля зі стрибком.


1
Мені подобається такий підхід, оскільки він має коротке замикання IFF andкороткого замикання, забезпечуючи тим самим послідовність операторів.
Кайл Странд

1
@Snowman Це правда. Я мав на увазі, що if (a) return true; else if (b) return true;здається більш-менш морально рівнозначним if (a OR b) return true;, але ця думка цілком може бути відкритою для суперечок.
Нік

13

Якщо у вас є тільки andі notви можете використовувати закон де Моргана , щоб перевернути навколо 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

і т.д. і т.д. і т.д.

Оскільки більшість мов надають умовне, а шанси оператор "і" все одно має на увазі гілку.

...

Якщо у вас є все nand(див. Вікіпедію ):

повернути nand (nand (arg1, arg1), nand (arg2, arg2))


7
Спростіть:return not (not arg1 and not arg2)

@Snowman, ти справді повинен відповісти на цю відповідь, щоб я міг її схвалити. Ви (зараз) єдиний, хто не пішов з розгалуженням.
Lawtonfogle

4
Збирався додати рішення NAND, але ви мене побили. Все має бути реалізовано з точки зору NAND.
Енді

2
@Andy: Насправді все слід визначати з точки зору NOR. ;-)
Пітер Геркенс

1
Гарна робота з чистим nandрозчином.
AAT

13

Функції (ECMAScript)

Все, що вам потрібно, - це визначення функцій та виклики функцій. Вам не потрібні розгалуження, умовні умови, оператори чи вбудовані функції. Я продемонструю реалізацію за допомогою ECMAScript.

Спочатку визначимо дві функції, що називаються trueі false. Ми можемо визначити їх будь-яким способом, який ми хочемо, вони абсолютно довільні, але ми визначимо їх дуже особливим чином, який має деякі переваги, як ми побачимо далі:

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

tru це функція з двома параметрами, яка просто ігнорує свій другий аргумент і повертає перший. flsце також функція з двома параметрами, яка просто ігнорує перший аргумент і повертає другий.

Чому ми закодувати truі flsцей шлях? Ну, таким чином, обидві функції не тільки представляють два поняття, 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 branch і else branch! Чому?

Добре, він повертає повернене значення першого аргументу, але він оцінює обидва аргументи, оскільки ECMAScript суворий і завжди оцінює всі аргументи до функції перед викликом функції. IOW: він оцінює перший аргумент, який є console.log("then branch"), який просто повертається undefinedі має побічний ефект друку then branchна консолі, і він оцінює другий аргумент, який також повертається undefinedі друкується на консоль як побічний ефект. Потім він повертається першим undefined.

Для λ-числення, де було винайдено таке кодування, це не проблема: λ-числення чисте , а значить, не має жодних побічних ефектів; тому ви ніколи не помітите, що другий аргумент також оцінюється. Плюс, λ-числення ледаче (або, принаймні, його часто оцінюють у звичайному порядку), тобто, воно насправді не оцінює аргументи, які не потрібні. Отже, IOW: у λ-обчисленні другий аргумент ніколи не буде оцінений, і якби він був, ми не помітили б.

Однак, ECMAScript є суворим , тобто він завжди оцінює всі аргументи. Ну, власне, не завжди: if// then/ else, наприклад, оцінює thenгілку лише, якщо умова є, trueі оцінює elseгілку лише, якщо умова є false. І ми хочемо повторити цю поведінку з нашоюiff . На щастя, незважаючи на те, що ECMAScript не лінивий, у нього є спосіб затримати оцінку фрагмента коду, так само, як це робить і будь-яка інша мова: заверніть його у функцію, і якщо ви ніколи не зателефонуєте до цієї функції, код буде ніколи не бути страченим.

Отже, ми загортаємо обидва блоки у функції, а в кінці викликаємо функцію, яка повертається:

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);

Об'єкти (Scala)

Можливо , ви помітили що - щось особливе: truі flsграти подвійну роль, вони діють як в якості значень даних trueі false, але в той же час, вони також виступають в якості умовного виразу. Вони є даними та поведінкою , об'єднаними в один… ем… „річ”… або (смію сказати) об’єкт !

Дійсно, truі flsє об'єктами. І якщо ви коли-небудь використовували Smalltalk, Self, Newspeak або інші об'єктно-орієнтовані мови, ви помітите, що вони реалізують булеві точно таким же чином. Я продемонструю таку реалізацію тут у Scala:

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 є причиною того, що замінити Conditional на Polymorphism Refactoring завжди працює: ви завжди можете замінити будь-яку умовну програму на поліморфну ​​розсилку повідомлень, оскільки, як ми нещодавно показали, поліморфна розсилка повідомлень може замінити умовні умови, просто виконавши їх. Такі мови, як Smalltalk, Self та Newspeak, є підтвердженням існування, оскільки ці мови навіть не мають умов. (Вони також не мають циклів, BTW або дійсно будь-яких мов, вбудованих керуючих структур, за винятком поліморфної розсилки повідомлень, яка називається віртуальним методом.)


Узгодження шаблону (Haskell)

Ви також можете визначити, orвикористовуючи відповідність шаблонів або щось на зразок часткових визначень Haskell:

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

Звичайно, відповідність шаблону є формою умовного виконання, але знову ж таки, так само об'єктно-орієнтована відправка повідомлень.


2
Як щодо цього False ||| False = Falseі _ ||| _ = Trueнатомість? :)
fredoverflow

3
@FredOverflow: Для цього потрібно завжди оцінювати правильний операнд. Зазвичай булеві оператори, як очікується, не суворі у своєму правильному аргументі, так само "короткому замиканні".
Йорг W Міттаг

Ах, звичайно. Я знав, що там повинна бути глибша причина :)
fredoverflow

Перша частина відразу нагадала мені чудовий серіал Еріка Ліпперта про стиль продовження проходження . Чисто збіг, але все ж весело :)
Voo

1
@ JörgWMittag Визначення FredOverflow належним чином коротке замикання. Спробуйте True ||| undefinedсебе в ghci, щоб побачити!
Даніель Вагнер

3

Ось ще один спосіб визначити АБО, або взагалі будь-який логічний оператор, використовуючи найбільш традиційний спосіб його визначення: використовувати таблицю істинності.

Це, звичайно, досить тривіально робити в мовах вищого рівня, таких як 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 ] ]) { /* ... */ }

Я думаю, що це "найчистіший" підхід у певному математичному сенсі. АБО-оператор - це функція зрештою, і таблиця істинності - це справді суть цієї функції як відношення та множини. Звичайно, це може бути написано і в забавній формі OO:BinaryOperator or = new TruthTableBasedBinaryOperator(new TruthTable(false, true, true, true));
ВІД

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.
Кін

Мені подобається ваша методологія, але проста помилка полягає в тому, що сума обох аргументів повинна бути більшою, ніж ZERO, щоб бути правдивою, а не більше ONE.
Грантлі

1
return (arga+argb)>0
Грантлі

1
Я лише виправляв ваш текст. Ваш код ідеальний, але може бути в одному рядку: return (((arg1 ? 1 : 0)+(arg2 ? 1 : 0)) > 0); :)
Зіграно

1
@SenthuSivasambu Я не заперечую проти Вашого використання arg1 ? 1 : 0;. Це надійні вирази для перетворення булевого числа в число. Це лише твердження про повернення, яке може бути тривіально відремонтовано.
Кін

1

Дві форми:

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

АБО

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

Майте також перевагу коду, що нагадує гольф, бути трохи меншим, ніж інші пропозиції поки що, на одну меншу гілку. Навіть не дурний мікро-вибір, щоб зменшити кількість гілок, якщо ми розглядаємо питання про створення примітиву, який, отже, буде дуже активно використовуватися.

Визначення Javascript ||схоже з цим, що в поєднанні з його друкованим введенням означає, що вираз false || "abc"має значення "abc"і 42 || "abc"має значення42 .

Хоча якщо у вас вже є інші логічні оператори, то подібне nand(not(arg1), not(arg2))може мати перевагу взагалі без розгалуження.


який сенс повторювати попередню відповідь ( як ви зізналися )?
гнат

@gnat досить близько, що я б не переймався, якби я бачив цю відповідь, але все-таки щось там не знайдено в жодному з них, тому я залишаю її.
Джон Ханна

@gnat, насправді розглядаючи "Ми шукаємо довгі відповіді, які дають певне пояснення та контекст". Зараз я щасливіший з цією відповіддю.
Джон Ханна

1

На додаток до всіх запрограмованих рішень, що використовують конструкцію if, можна збудувати ІЛИ ворота, поєднавши три ворота NAND. Якщо ви хочете подивитися, як це робиться у вікіпедії, натисніть тут .

Звідси вираз,

НЕ [НЕ (А І А) І НЕ (В І В)]

який використовує НЕ та І дає таку ж відповідь, як АБО. Зауважте, що використання NOT і AND є лише незрозумілим способом вираження NAND.


НЕ (А І А) == НЕ (А)?
Чарлі

Так, саме. У цій же статті вікіпедії ви можете побачити, як вони зменшують ворота NOT до воріт NAND. Те саме для ворота AND. Я вирішив не редагувати формулу, яку вони подали для АБО.
Вальтер Мітті

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)

Це просто використовує закони DeMorgan і зловживає тим фактом, який *подібний до того, &&коли trueі до falseних поводиться як 1і 0відповідно. (Зачекайте, ви кажете, що це не код гольфу?)

Ось гідна відповідь:

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

Але це по суті ідентично з іншими вже даними відповідями.


3
Ці підходи принципово хибні. Розглянемо -1 + 1 для arg1+arg2, -1 і 0 для max(arg1,arg2)тощо
пухнасті

@fluffy Цей підхід передбачає булеві аргументи, і тоді просто трапляється правильно працювати з більшістю видів сміття. Добре з вас зазначити, що все ще є сміття, яке спричиняє проблеми. Саме така річ саме тому ми повинні прагнути максимально прямо моделювати фактичну проблематичну область (і уникати захоплення нашою власною кмітливістю) на практиці.
Кін

Якщо ви робите чисті 1-бітові булеві значення, то додавання все ще не працює, оскільки 1 + 1 = 0. :)
пухнастий

@fluffy Тут відбуваються явні перетворення. Потрібні вони чи ні, залежить від деталей реалізації (саме тому це дурна ідея).
Кін

0

Один із способів визначення or- через таблицю пошуку. Ми можемо зробити це явним:

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

ми створюємо масив зі значеннями, які має мати повернене значення залежно від того, що aє. Потім робимо пошук. У мовах, подібних до C ++, boolпідвищується до значення, яке може використовуватися як індекс масиву, з trueбуттям 1і falseбуттям0 .

Потім ми можемо поширити це на інші логічні операції:

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 і це працює.

Вищеописана методика вимагає мови, що підтримує пошук аргументів і шаблони. Можливо, ви могли це зробити мовою з генеричними та 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

Отже, "логіка" цілком справедлива в заяві про ОП, але, мабуть, вона є багатослівною. Обережно, це непогано. Це ідеально, якщо вам потрібна функція, яка діє як математичний оператор на основі, скажімо, свого роду матриці. Інші реалізують фактичний куб (наприклад, заява Quine-McCluskey):

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

І ви оціните або [a] [b]

Так, так, кожна логіка тут є дійсною (за винятком тієї, яка розміщена як використовується мовним АБО оператором xDDDDDDDD).

Але мій улюблений - закон ДеМоргана: !(!a && !b)


0

Подивіться на стандартну бібліотеку Swift і перевірте їх виконання ярлика АБО та операції ярлика AND, які не оцінюють другі операнди, якщо вони не потрібні / дозволені.


-2

Логіка цілком правильна, але її можна спростити:

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

І, мабуть, у вашій мові є оператор АБО, тому - якщо це не суперечить духу питання - чому б ні

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є зайвим.
Довал

4
Аскер спеціально зазначив, що їх вимога була "без використання самого оператора"
gnat

2
Гм, я нічого подібного не сказав. Я мав на увазі те, що я мав на увазі, але питання не говорило так, поки воно не було відредаговане, і вона відповіла на це як таке, так що я винен у цьому.
logicNoob
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.