В чем разница между равенством и эквивалентностью?

Я прочитал несколько примеров в чтении математики и информатики, которые используют символ эквивалентности , (в основном '=' с тремя строками), и мне всегда имеет смысл читать это, как если бы это было равенство. В чем разница между этими двумя понятиями?

10 ответов

Решение

Википедия: Соотношение эквивалентности:

В математике отношение эквивалентности - это бинарное отношение между двумя элементами множества, которое группирует их как "эквивалентные" в некотором роде. Пусть a, b и c - произвольные элементы некоторого множества X. Тогда "a ~ b" или "a ≡ b" означает, что a эквивалентно b.

Отношение эквивалентности "~" рефлексивно, симметрично и транзитивно.

Другими словами, = это просто пример отношения эквивалентности.

Редактировать: Этот, казалось бы, простой критерий рефлексивности, симметрии и переходности не всегда тривиален. См. Эффективная Java Блоха, 2-е изд. 35 например,

public final class CaseInsensitiveString {
...
    // broken
    @Override public boolean equals(Object o) {
        if (o instance of CaseInsensitiveString)
            return s.equalsIgnoreCase(
                ((CaseInsensitiveString) o).s);
        if (o instanceof String) // One-way interoperability!
            return s.equalsIgnoreCase((String) o);
        return false;
    }
... 

}

Вышеуказанная равная реализация нарушает симметрию, потому что CaseInsensitiveString знает о String класс, но String класс не знает о CaseInsensitiveString,

Я принимаю ваш вопрос скорее о математической нотации, чем о программировании. Тройной знак равенства, на который вы ссылаетесь, можно записать ≡ в HTML или \equiv в латексе.

a ≡ b чаще всего означает "a определено как b" или "пусть a будет равно b".

Таким образом, 2+2=4, но φ ≡ (1+sqrt(5))/2.

Вот удобная таблица эквивалентности:

Mathematicians      Computer scientists
--------------      -------------------
      =                      ==
      ≡                      =

(Другие ответы об отношениях эквивалентности тоже верны, но я не думаю, что они такие же общие. Есть также ≡ b (mod m), который произносится как "a соответствует b, mod m", и на языке программиста будет выражаться как mod(a,m) == mod(b,m). Другими словами, a и b равны после mod'ing с помощью m.)

Многие языки различают равенство объектов и равенство значений этих объектов.

Например, в Ruby есть 3 различных способа проверки равенства. Первая, равная?, Сравнивает две переменные, чтобы увидеть, указывают ли они на один и тот же экземпляр. Это эквивалентно в языке C-стиля делать проверку, чтобы видеть, ссылаются ли 2 указателя на тот же адрес. Второй метод, ==, проверяет равенство значений. Так что 3 == 3,0 будет верно в этом случае. Третий, eql?, Сравнивает как значение, так и тип класса.

Лисп также имеет разные концепции равенства в зависимости от того, что вы пытаетесь проверить.

В языках, которые я видел, которые различают равенство и эквивалентность, равенство обычно означает, что тип и значение одинаковы, а эквивалентность означает, что только значения одинаковы. Например:

int i = 3;
double d = 3.0;

i и d будут иметь отношение эквивалентности, поскольку они представляют одно и то же значение, но не равенство, поскольку они имеют разные типы. Другие языки могут иметь разные представления об эквивалентности (например, представляют ли две переменные один и тот же объект).

Ответы выше правильные / частично правильные, но они не объясняют, в чем именно разница. В теоретической информатике (и, вероятно, в других разделах математики) это имеет отношение к количественной оценке по свободным переменным логического уравнения (то есть, когда мы используем две записи одновременно).

Для меня лучший способ понять разницу это:

  1. По определению
    A ≡ B
    средства
    Для всех возможных значений свободных переменных в A и B, A = B

    или же

    A ≡ B <=> [A = B]

  2. Примером
    х =2x
    если (на самом деле, если он такой же, как ≡)
    х =0

    х 2х
    если (потому что это не тот случай, когда x =2x для всех возможных значений x)
    Ложь

Я надеюсь, что это помогает

Редактировать:

Еще одна вещь, которая пришла мне в голову, это определения двух.

A = B определяется как A <= B и A>= B, где <= (меньше равно, не подразумевает) может быть любым отношением порядка

A ≡ B определяется как A <=> B (тогда и только тогда, когда подразумевает обе стороны), стоит отметить, что импликация также является отношением порядка, и поэтому возможно (но менее точно и часто запутанно) использовать = вместо ≡.

Я предполагаю, что вывод состоит в том, что когда вы видите =, тогда вы должны выяснить намерение авторов на основе контекста.

Разница заключается, прежде всего, в уровне, на котором вводятся две концепции. "≡" является символом формальной логики, где, учитывая два предложения a и b, a ≡ b означает (a => b AND b => a).

Вместо этого '=' является типичным примером отношения эквивалентности на множестве и предполагает, по крайней мере, теорию множеств. Когда кто-то определяет конкретный набор, обычно он дает ему подходящее понятие равенства, которое приходит в форме отношения эквивалентности и использует символ "=". Например, когда вы определяете множество Q рациональных чисел, вы определяете равенство a/b = c/d (где a / b и c / d рациональны) тогда и только тогда, когда ad = bc (где ad и bc являются целыми числами)., понятие равенства для целых чисел уже было определено в другом месте).

Иногда вы можете найти неформальное обозначение f(x) ≡ g(x), где f и g - функции: это означает, что f и g имеют одну и ту же область и что f(x) = g(x) для каждого x в такой домен (это опять-таки отношение эквивалентности). Наконец, иногда вы найдете ≡ (или ~) в качестве универсального символа для обозначения отношения эквивалентности.

Возьмите это за пределы сферы программирования.

  • (31) равный - (имеющий такое же количество, ценность или меру, как и другой; "на равных условиях"; "все люди равны перед законом")

  • эквивалентно, равнозначно - (будучи по существу равным чему-то; "это было так же хорошо, как золото"; "желание было эквивалентно команде"; "его утверждение равносильно признанию вины"

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

null == 0   # true , null is equivelant to 0 ( in php ) 
null === 0  # false, null is not equal to 0 ( in php )  

(Некоторые люди используют ≈ для представления неидентичных значений)

Вы можете иметь два утверждения, которые имеют одинаковое значение истинности (эквивалент), или два утверждения, которые одинаковы (равенство). Также "знак равенства с тремя столбцами" также может означать "определяется как".

Первая проблема заключается в том, что означают в данном случае равенство и эквивалентность ? По сути, контексты вполне свободны в определении этих терминов.

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

Самым грубым примером, нарушающим это ожидание, является C++: и говорят, что они равны , если x == yоценивает true, и называются эквивалентными , если !(x < y) && !(y < x). Даже помимо определяемых пользователем перегрузок этих операторов, для чисел с плавающей запятой ( float, double) это не одно и то же: все значения NaN эквивалентны друг другу (фактически эквивалентны всему), но не равны ничему, включая самих себя, а значения и сравниваются равны (и эквивалентны), хотя их можно различить, если умный.

Во многих случаях вам понадобятся лучшие термины, чтобы точно передать ваше намерение. Даны две переменные и ,

  • идентичность или одинаковость для выражения того, что существует только один объект и и относятся к нему. Любое изменение, выполненное через, непреднамеренно можно наблюдать через, и наоборот. В Java переменные ссылочного типа проверяются на идентичность с помощью , в C# с помощьюReferenceEqualsметод. В C++, если и являются ссылками, std::addressof(x) == std::addressof(y)будет делать (тогда как &x == &yбудет работать большую часть времени, но &могут быть настроены для пользовательских типов).
  • побитовое или структурное равенство для выражения того, что внутренние представления и совпадают. Обратите внимание, что побитовое равенство нарушается, когда объекты могут ссылаться (на части) самих себя внутри себя. Чтобы получить предполагаемое значение, понятие в таких случаях должно быть уточнено, чтобы сказать: структурировано одинаково. В D побитовое равенство проверяется через is. C имеетmemcmp. Я не знаю ни одного языка со встроенной проверкой равенства структур.
  • неразличимость или заменяемость для выражения того, что значения не могут быть различимы (через их открытый интерфейс): если функция принимает два параметра и xа также yнеразличимы, звонки f(x, y), f(x, x), а также f(y, y)всегда возвращать одно и то же значение, если только fпроверяет идентичность (см. пункт выше) напрямую или путем мутации. Примером могут быть два дерева поиска, которые содержат неразличимые элементы, но внутренние деревья расположены по-разному, что является деталью реализации, которую нельзя наблюдать с помощью его общедоступных методов.
  • эквивалентность для выражения того, что объекты представляют значения, считающиеся одинаковыми из некоторых абстрактных рассуждений. В качестве примера для различимых эквивалентных значений обратите внимание, что числа с плавающей запятой имеют отрицательный нуль, отличный от , и, например, sign(1/x)отличается для -0.0а также +0.0. Эквивалентность чисел с плавающей запятой проверяется с помощью ==на многих языках с синтаксисом Algol. Большинство объектно-ориентированных языков проверяют эквивалентность объектов с помощью метода (или метода с аналогичным названием). С# имеетIEquatable<T>интерфейс, который указывает, что класс имеет стандартное/каноническое/стандартное отношение эквивалентности, определенное для него. В Java один переопределяет equalsметод, от которого наследуется каждый класс Object.

Как видите, понятия становятся все более расплывчатыми. Проверка на идентичность — это то, что может выразить большинство языков. Программист обычно не может зацепить тождество и побитовое равенство, поскольку эти понятия не зависят от интерпретаций. Было предложение C++20, которое в конечном итоге было отклонено, которое вводило два последних понятия как сильное † и слабое равенство †. († Этот сайт выглядит как CppReference, но таковым не является; он не актуален.) Исходная статья находится здесь.

Все, что есть в C, также доступно для C++ и любого языка, который может использовать функциональность C. Все, что сказано о C#, верно для Visual Basic .NET и, возможно, для всех языков, построенных на платформе .NET. Аналогично Java представляет языки JRE.

Фактически, равенство - это особый вид отношения эквивалентности. Подумайте, что значит сказать:

0.9999999999999999... = 1

Это говорит о том, что равенство - это просто отношение эквивалентности на "строковых числах" (которые более формально определяются как функции из Z -> {0,...,9}). И мы видим из этого случая, что классы эквивалентности не являются даже синглетонами.

Другие вопросы по тегам