Закон Де Моргана ?

 

В ветке для новичков подымался вопрос. Я услышал интересный и противоречивый ответ... Вот второй пост на данной странице:

https://www.mql5.com/ru/forum/142582/page176

Ситуация неоднозначная. Почему так не сделать сразу ИЛИ в вместе И ? Просьба к опытным программистах объяснить. Зачем данный Закон Де Моргана вообще? Выходит путанница. 

 
hoz:

В ветке для новичков подымался вопрос. Я услышал интересный и противоречивый ответ... Вот второй пост на данной странице:

https://www.mql5.com/ru/forum/142582/page176

Ситуация неоднозначная. Почему так не сделать сразу ИЛИ в вместе И ? Просьба к опытным программистах объяснить. Зачем данный Закон Де Моргана вообще? Выходит путанница. 


Поясню свой же ответ. Если вы внимательно читали ветку, то могли заметить, что речь шла о сокращении времени вычислений для проверки условий вида if (A || B) {Action()}. То есть, стоит такая проблема: есть два выражения, А и В, причем на проверку каждого затрачивается значительное время. Можно ли как-то свести по возможности все это к проверке только одного условия? Так вот дело в том, что в MQL логические выражения не вычисляются в заведомо определенном порядке, то есть "написали  А||B, значит сначала проверится А, потом В" - это утверждение не есть факт. Но, вспомнив, что можно явно задавать порядок вычисления условий И с помощью фигурных скобок, мы с применением закона ДеМоргана преобразуем исходное выражение A||B = !(!A&&!B), после чего имеем возможность записать:


bool otvet=true;

if(!A)
{
   if(!B)
   {
      otvet = false;
   }
}

if(otvet) Action();

после чего переменная otvet будет равна true если хотя бы одно из условий A, B истинно. Причем, взяв по возможности в качестве А то условие, вероятность выполнения которого больше, мы снизим количество проверок до минимума (т.к. если A==true, то B уже проверять не надо.

Абсолютно тот же принцип распространяется на любое количество условий, их тольк надо расположить в порядке убывания показателя X = (вероятность_true*время_вычисления).

 
alsu: Поясню свой же ответ.

Спасибо, не знал о таких тонкостях MQL4. Кстати, вообще-то, оказывается, это еще Оккам открыл (статья в Вики):

«Противоречащая противоположность дизъюнктивного суждения — конъюнктивное суждение, составленное из противоречащих противоположностей частей дизъюнктивного суждения (The contradictory opposite of a disjunctive proposition is a conjunctive proposition composed of the contradictories of the parts of the disjunctive proposition)» (Уильям Оккам, Summa Logicae).
Ну слово "противоречащий" из перевода я бы вообще убрал, оно тут лишнее.
 
Mathemat:

Спасибо, не знал о таких тонкостях MQL4. Кстати, вообще-то, оказывается, это еще Оккам открыл (статья в Вики):

Ну слово "противоречащий" из перевода я бы вообще убрал, оно тут лишнее.

"Бритва Оккама".
 
grell: "Бритва Оккама".

Не сказал бы, что это и есть его Бритва. Вот она.

Мягко говоря, это неформализуемый принцип - в отличие от законов Де Моргана, являющихся частью формализуемой булевой логики.

 
Mathemat:

Мягко говоря, это неформализуемый принцип - в отличие от законов Де Моргана, являющихся частью формализуемой булевой логики.

Вполне формализуемый, имхенько. Называется - принцип максимальной свободы выбора (обратная задача, понятное дело). Успешно реализован автором (Г. Крон, австриец, 30-е годы) в теории и практике аналитического конструирования электрических машин. 

http://www.twirpx.com/file/701352/ 

 
tara:

Вполне формализуемый, имхенько. Называется - принцип максимальной свободы выбора (обратная задача, понятное дело). Успешно реализован автором (Г. Крон, австриец, 30-е годы) в теории и практике аналитического конструирования электрических машин. 

http://www.twirpx.com/file/701352/ 

Это очень узкий вариант решения проблемы Бритвы Оккама. Тезка, неужто ты считаешь, что тензорный анализ - это панацея от всего?

Конечно, разные варианты ее решения в разных областях обязательно уже существуют. Но ведь никто не гарантирует, что те же методы будут оптимально работать и в других областях.

 
Mathemat:
Это очень узкий вариант решения проблемы Бритвы Оккама. Тезка, неужто ты считаешь, что тензорный анализ - это панацея от всего?

Дело не в тензорах, а в принципе максимальной свободы выбора при аналитическом конструировании (синтезе) чего-нибудь. 
 
Кстати, проблемы Бритвы Оккама не существует, имхенько, и решения она не требует. Бритва есть (дельная идея), а решать - нечего, можно лишь опровергать, либо подтверждать (доказывать). 
 
alsu:

Поясню свой же ответ. Если вы внимательно читали ветку, то могли заметить, что речь шла о сокращении времени вычислений для проверки условий вида if (A || B) {Action()}. То есть, стоит такая проблема: есть два выражения, А и В, причем на проверку каждого затрачивается значительное время. Можно ли как-то свести по возможности все это к проверке только одного условия? Так вот дело в том, что в MQL логические выражения не вычисляются в заведомо определенном порядке, то есть "написали  А||B, значит сначала проверится А, потом В" - это утверждение не есть факт. Но, вспомнив, что можно явно задавать порядок вычисления условий И с помощью фигурных скобок, мы с применением закона ДеМоргана преобразуем исходное выражение A||B = !(!A&&!B), после чего имеем возможность записать:

bool otvet=true;

if(!A)
{
   if(!B)
   {
      otvet = false;
   }
}

if(otvet) Action();

после чего переменная otvet будет равна true если хотя бы одно из условий A, B истинно. Причем, взяв по возможности в качестве А то условие, вероятность выполнения которого больше, мы снизим количество проверок до минимума (т.к. если A==true, то B уже проверять не надо.

Абсолютно тот же принцип распространяется на любое количество условий, их тольк надо расположить в порядке убывания показателя X = (вероятность_true*время_вычисления).

Код с otvet' ом мне, конечно, понятен. Понятно также, что данный вариант выражения, если он относится к булевой логике и подпадает под Закон Де моргана, это для сокращения времени рассчёта выражения. Тут всё понятно. Идём дальше..

Алексей, Вы писал в предыдущий раз:

ИЛИ. Потому что условие И не выполняется, когда хотя бы один из операндов равен false (первый ИЛИ второй) - в булевой логике это называется "закон Де Моргана" 

А откуда тогда компилятор знает, что тут применим данный закон? По идее, если стоит && и одно из условий ложно, то условие не выполняется. Это если посмотреть исходя из нормальной логики. Откуда тут компилятор знает, т.е. почему вдруг, тут он прочитает код именно так, как Вы описали?

 alsu:

 Но, вспомнив, что можно явно задавать порядок вычисления условий И с помощью фигурных скобок, мы с применением закона ДеМоргана преобразуем исходное выражение A||B = !(!A&&!B), после чего имеем возможность записать:

  У нас ведь выражение записано не так !A&&!B ?! Не хотел спешно отвечать, но что-то не очень то и просто всё это доходит.

 
hoz:

А откуда тогда компилятор знает,

Он не знает, это мы его заставляем делать то,что надо. Просто у выражения A||B результат всегда такой же, как у !(!A&&!B). Посмотрите внимательно, если хотя бы одно из условий А, В истинно, то скобка равна false, следовательно все выражение равно true. А это нам и нужно. Вложенные If'ы как раз означают &&, если оба блока выполнились (то есть И А, И В не выполняются), то мы присваиваем в ответ false, в пртивном случае оставляем true.


Необходимость в законе ДМ возникает, еще раз, из-за того, что || мы не можем средствами языка преобразовать к вложенным конструкциям, а && - можем.