Предположим, у меня есть набор A ⊆ nat
. Я хочу смоделировать в Изабель функцию f : A ⇒ Y
. Я мог бы использовать либо:
- частичная функция, то есть функция типа
nat ⇒ Y option
или - общая функция, т. е. функция типа
nat ⇒ Y
, которая не указана для входных данных, не входящих вA
.
Интересно, какой вариант "лучше". Я вижу пару факторов:
Подход «частичной функции» лучше, потому что проще сравнивать частичные функции на равенство. То есть, если я хочу посмотреть, равна ли
f
другой функции,g : A ⇒ Y
, я просто говорюf = g
. Чтобы сравнить неполные общие функцииf
иg
, я должен был бы сказать∀x ∈ A. f x = g x
.Подход с «недостаточной общей функцией» лучше, потому что мне не нужно постоянно возиться с конструированием/деконструкцией
option
типов. Например, еслиf
является недоопределенной общей функцией, аx ∈ A
, то я могу просто сказатьf x
, но еслиf
является частичной функцией, я должен сказать(the ∘ f) x
. С другой стороны, сложнее выполнять композицию функций на частичных функциях, чем на общих функциях.
В качестве конкретного примера, относящегося к этому вопросу, рассмотрим следующую попытку формализации простых графов.
type_synonym node = nat
record 'a graph =
V :: "node set"
E :: "(node × node) set"
label :: "node ⇒ 'a"
Граф состоит из набора узлов, отношения ребер между ними и label
для каждого узла. Нас интересует только метка узлов, находящихся в V
. Итак, должно ли label
быть частичной функцией node ⇒ 'a option
с dom label = V
, или это должна быть просто общая функция, которая не указана вне V
?