Проблема заключается в том, что список имеет два минусы конструкторов, в то время как обычный механизм обозначения для рекурсивных обозначений требует, чтобы вы всегда использовать одни и те же конструкторы. Приведение может помочь вам преодолеть часть этой проблемы:.
Section ApplesAndPears.
Variable Apple Pear : Set.
Inductive FruitList : Set :=
| Nil
| ConsApple (a : Apple) (l : FruitList)
| ConsPear (p : Pear) (l : FruitList).
Inductive Fruit : Set :=
| IsApple (a : Apple)
| IsPear (p : Pear).
Coercion IsApple : Apple >-> Fruit.
Coercion IsPear : Pear >-> Fruit.
Definition ConsFruit (f : Fruit) (l : FruitList) : FruitList :=
match f with
| IsApple a => ConsApple a l
| IsPear p => ConsPear p l
end.
Notation "[ ]" := (Nil) (at level 0).
Notation "[ x ; .. ; y ]" := (ConsFruit x .. (ConsFruit y Nil) ..) (at level 0).
Variable a : Apple.
Variable p : Pear.
Definition a_fruitList := [ a ; p ].
End ApplesAndPears.
(Кстати, я предполагаю, что вы на самом деле имел в виду писать [ a ; p ]
, а не [ p ; a ]
Если ты хочешь написать [ p ; a ]
, то вы просто вместо этого использовать функцию SnocFruit
, которая добавит элемент в конец списка. Однако это еще раз ухудшит проблемы, описанные позже.)
Теперь мы определили новую функцию для замены конструкторов и может использовать эту функцию, объявив конструкторы Fruit
для принуждения.
Это решение не является полностью удовлетворительным, конечно, потому что термин вашего обозначения производит делает ссылку на ConsFruit
, в то время как в идеале было бы неплохо иметь что-то, что улавливает ConsApple
или ConsFruit
в зависимости от аргумента вы даете. Я подозреваю, что нет способа сделать это с помощью механизма обозначений, но я могу ошибаться.
Это одна из причин, почему я рекомендую вам использовать только list
типа и декларирую другой тип, такие как Fruit
провести Apple
и Pear
вместо двух минусов конструкторов, если у вас есть очень веские причины не делать этого.
Это не имеет ничего общего с вопросом, но обратите внимание, что 'Индуктивный Apple: Set:. =' Определяет 'Apple' как пустое множество , Таким образом, когда вы объявляете «Variable a: Apple», вы вводите несогласованность в своем развитии. Вместо этого вы должны использовать «Параметр Apple: Установить». – Virgile