Отрицание и закон Де Моргана не являются частью частичного упорядочения C ++ 20 по ограничениям - PullRequest
4 голосов
/ 28 февраля 2020

Правила для частичного упорядочения по ограничениям относятся к AND и OR, но не относятся к NOT:

13.5.4 Partial ordering by constraints [temp.constr.order]
(1.2) ...
- The constraint A ∧ B subsumes A, but A does not subsume A ∧ B.
- The constraint A subsumes A ∨ B, but A ∨ B does not subsume A.

Эти правила основаны на определения атомы c ограничения и ограничения нормализация :

13.5.3 Constraint normalization [temp.constr.normal]
1 The normal form of an expression E is a constraint that is defined
  as follows:
(1.1) The normal form of an expression ( E ) is the normal form of E.
(1.2) The normal form of an expression E1 || E2 is the disjunction
      of the normal forms of E1 and E2.
(1.3) The normal form of an expression E1 && E2 is the conjunction
      of the normal forms of E1 and E2.

Отрицание (то есть! E1) специально НЕ обрабатывается.

Таким образом, следующий код правильно использует частичное упорядочение:

void foo(auto i) requires std::integral<decltype(i)> {
    std::cout << "integral 1" << std::endl;
}

void foo(auto i) requires std::integral<decltype(i)> && true {
    std::cout << "integral 2" << std::endl;
}

int main() {
    foo(0); // integral 2
}

, в то время как этот код не удается с неоднозначностью:

template<typename T>
concept not_integral = !std::integral<T>;

template<typename T>
concept not_not_integral = !not_integral<T>;

void foo(auto i) requires not_not_integral<decltype(i)> {
    std::cout << "integral 1" << std::endl;
}

void foo(auto i) requires std::integral<decltype(i)> && true {
    std::cout << "integral 2" << std::endl;
}

int main() {
    foo(0);
}

Код: https://godbolt.org/z/RYjqr2


Вышеуказанные причины, по которым закон де Моргана не работает для понятий:

template<class P>
concept has_field_moo_but_not_foo
     = has_field_moo<P> && !has_field_foo<P>;

не эквивалентны:

template<class P>
concept has_field_moo_but_not_foo
     = !(has_field_foo<P> || !has_field_moo<P>);

, первый будет участвовать в частичном заказ, в то время как последний не будет.

Код: https://godbolt.org/z/aRhmyy


Было решение не обрабатывать отрицание как часть нормализации ограничения , взятые для того, чтобы упростить реализацию для поставщиков компиляторов? или есть логический недостаток при попытке поддержать его?

1 Ответ

6 голосов
/ 28 февраля 2020

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

Да. Это обобщает требование наличия решателя SAT в компиляторе.

Был добавлен пример в [temp.constr.op] / 5 , чтобы продемонстрировать это, хотя он не дает обоснования для решения:

template <class T> concept sad = false;

template <class T> int f1(T) requires (!sad<T>);
template <class T> int f1(T) requires (!sad<T>) && true;
int i1 = f1(42);        // ambiguous, !sad<T> atomic constraint expressions ([temp.constr.atomic])
                        // are not formed from the same expression

template <class T> concept not_sad = !sad<T>;
template <class T> int f2(T) requires not_sad<T>;
template <class T> int f2(T) requires not_sad<T> && true;
int i2 = f2(42);        // OK, !sad<T> atomic constraint expressions both come from not_­sad

template <class T> int f3(T) requires (!sad<typename T::type>);
int i3 = f3(42);        // error: associated constraints not satisfied due to substitution failure

template <class T> concept sad_nested_type = sad<typename T::type>;
template <class T> int f4(T) requires (!sad_nested_type<T>);
int i4 = f4(42);        // OK, substitution failure contained within sad_­nested_­type

В частности, обратите внимание на разницу между f3 и f4. Означает ли requires !sad<typename T::type>, что не существует вложенного типа sad или что существует вложенный тип, который не является sad? На самом деле это означает последнее, в то время как ограничение на f4 означает первое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...