Почему Coq.Init.Logic определяет обозначение "A -> B"?
Файл Coq Standard Library Coq.Init.Logic, который можно найти здесь, содержит оператор
Notation "A -> B" := (forall (_ : A), B) : type_scope.
Я не понимаю, как это возможно, учитывая, что символ ->
уже имеет встроенное значение. Является ->
перезаписано этим?
Если я наберу в A -> B
как Кок узнает, имею ли я в виду A -> B
или же forall (x : A), B
?
Да, я знаю, что два предложения логически эквивалентны, но разве это не должно быть теоремой, а не обозначением?
Как вы можете сказать, у меня не было большого опыта работы с Coq, но я хочу понять детали.
1 ответ
->
Символ на самом деле определяется обозначением, которое вы нашли в Coq.Init.Logic
! В то время как forall
встроен, ->
определяется с помощью системы обозначений. Coq.Init.Logic
модуль автоматически загружается в Coq, потому что он экспортируется Coq.Init.Prelude, поэтому у вас сразу есть к нему доступ.
Когда ты пишешь A -> B
это интерпретируется с использованием нотации, которая forall (_:A), B
; это синтаксически похоже на forall (x:A), B
кроме того выражения B
не может зависеть от x
, Там нет двусмысленности - это единственное определение A -> B
и действительно, если вы загружаете Coq без прелюдии (например, передавая -noinit
флаг) A -> B
не буду разбирать.
Один аспект Coq, который делает ->
Кажется, встроенным является то, что нотация является двунаправленной - она применяется как для анализа, так и для печати. Вот почему вы видите ->
в ваших целях и когда вы используете Check
а также Search
, Здесь есть реальная двусмысленность; в этом случае, если forall (x:A), B
имеет B
это не зависит от x
Coq предпочитает печатать его, используя нотацию, а не встроенный синтаксис. Если вы отключите печать примечаний (Unset Printing Notation.
) вот увидишь forall (_:A), B
везде, где ты видел A -> B
, Конечно, если у вас есть тип функции с реальной зависимостью, то Coq нужно использовать forall (x:A), B
поскольку B
должен ссылаться на переменную x
,