Мне трудно понять (точку) перчатку, которую нужно пройти, чтобы обойти условие единого наследования (UIC).
Интуитивно условие равномерного наследования говорит (примерно) «синтаксически возможно определить каждый аргумент функции принуждения только из типа исходного аргумента».
Разработчику, который добавил приведения, было проще (я полагаю) написать код, реализующий приведения, если предполагается условие равномерного наследования. Я уверен, что запрос на вытягивание ослабит это ограничение и правильно реализует более общие принуждение приветствуется!
При этом обратите внимание, что при объявлении приведения, нарушающего UIC, появляется предупреждающее сообщение (а не сообщение об ошибке). Он все равно добавит его в таблицу приведения. В зависимости от вашей версии Coq приведение может никогда не срабатывать, или вы можете получить сообщение об ошибке во время вывода типа, когда код, применяющий приведение, создает термин с неправильным типом, потому что он пытается применить приведение, предполагая, что UIC сохраняется, когда он на самом деле нет, или (в более старых версиях Coq) вы можете получить аномалии (см., например, отчеты об ошибках #4114, #4507, #4635, #3373 и #2828).
Тем не менее вот пример, когда Identity Coercion
полезны:
Require Import Coq.PArith.PArith. (* positive *)
Require Import Coq.FSets.FMapPositive.
Definition lookup {A} (map : PositiveMap.t A) (idx : positive) : option A
:= PositiveMap.find idx map.
(* allows us to apply maps as if they were functions *)
Coercion lookup : PositiveMap.t >-> Funclass.
Definition nat_tree := PositiveMap.t nat.
Axiom mymap1 : PositiveMap.t nat.
Axiom mymap2 : nat_tree.
Local Open Scope positive_scope. (* let 1 mean 1:positive *)
Check mymap1 1. (* mymap1 1 : option nat *)
Fail Check mymap2 1.
(* The command has indeed failed with message:
Illegal application (Non-functional construction):
The expression "mymap2" of type "nat_tree"
cannot be applied to the term
"1" : "positive" *)
Identity Coercion Id_nat_tree : nat_tree >-> PositiveMap.t.
Check mymap2 1. (* mymap2 1 : option nat *)
По сути, в очень ограниченном случае, когда у вас есть идентификатор, который будет распознан как источник существующего приведения, если вы немного развернете его тип, вы можете использовать Identity Coercion
для этого. (Вы также можете сделать это, определив копию вашего существующего приведения с другой сигнатурой типа и объявив, что это тоже приведение. Но тогда, если у вас есть несколько лемм, в которых упоминается одно приведение, и несколько лемм, в которых упоминается другое, rewrite
будет иметь вопросы.)
Существует еще один вариант использования Identity Coercion
s: когда ваш источник не является индуктивным типом, вы можете использовать их для свертывания, а не только для развертывания идентификаторов, играя трюки с Module
s и Module Type
s; в качестве примера см. этот комментарий к #3115.
В общем, я не знаю способа обойти условие равномерного наследования.
person
Jason Gross
schedule
10.05.2018