Вот небольшая теорема в математике:
Предположим, что u не является элементом A, а v не является элементом B, а f является инъективной функцией от A до B. Пусть A '= Aunion {u} и B '= B union {v}, и определим g: A' -> B 'с помощью g (x) = f (x), если x находится в A, и g (u) = v. Тогда gтакже инъективен.
Если бы я писал код, подобный OCaml, я бы представлял A и B как типы, а f как функцию A-> B, что-то вроде
module type Q =
sig
type 'a
type 'b
val f: 'a -> 'b
end
, а затем определял быfunctor
module Extend (M : Q) : Q =
struct
type a = OrdinaryA of M.a | ExoticA
type b = OrdinaryB of M.b | ExoticB
let f x = match x with
OrdinaryA t -> OrdinaryB ( M.f t)
| Exotic A -> ExoticB
end;;
, и моя теорема будет состоять в том, что если Q.f
инъективен, то и 1012 *, где я надеюсь, что синтаксис получился более или менее правильным.
Я бы хотел сделать то же самое в Изабель / Изаре.Обычно это означало бы написать что-то вроде
definition injective :: "('a ⇒ 'b) ⇒ bool"
where "injective f ⟷ ( ∀ P Q. (f(P) = f(Q)) ⟷ (P = Q))"
proposition: "injective f ⟹ injective (Q(f))"
и Q
- это что-то.Я не знаю, как сделать в Изабелле одну операцию, аналогичную функтору Q
в OCaml, которая создает два новых типа данных и функцию между ними.Доказательство инъективности выглядит так, как будто это было бы довольно просто - просто разделение на четыре случая.Но я хотел бы помочь определить новую функцию, которую я назвал Q f
, учитывая функцию f
.