очень полезно для извлечения программыпоскольку она позволяет удалять части кода, которые бесполезны. Например, чтобы извлечь алгоритм сортировки, мы должны доказать утверждение «для каждого списка ℓ существует список k такой, что k упорядочено, а k является перестановкой ℓ ». Если мы запишем это в Coq и извлечем без использования P r o p , мы получим:PropℓkkkℓProp
- «для всех есть к » даст нам карту , которая принимает списки в списки,ℓk
sort
- «такой, что упорядочено» даст функцию, которая проходит через k и проверяет, что она отсортирована, иk
verify
k
- « перестановка л » даст перестановку , которая принимает л к к . Обратите внимание, что это не только отображение, но и обратное отображение вместе с программами, проверяющими, что две карты действительно являются обратными.kℓ
pi
ℓkpi
Хотя лишние вещи не являются абсолютно бесполезными, во многих приложениях мы хотим от них избавиться и сохранить справедливость sort
. Это может быть достигнуто, если мы используем чтобы указать, что « k упорядочено» и « k является перестановкой ℓ », но не «для всех ℓ существует k ».Propkkℓℓk
В общем, распространенным способом извлечения кода является рассмотрение оператора вида где x - вход, y - выход, а ϕ ( x , y ) объясняет, что означает, что y является правильным выводом. (В приведенном выше примере A и B являются типами списков, и ϕ ( ℓ , k ) - это « k упорядочено, а k - перестановка ℓ .») Если ϕ находится в P r o p, то извлечение дает отображение f :∀x:A.∃y:B.ϕ(x,y)xyϕ(x,y)yABϕ(ℓ,k)kkℓϕProp такойчто φ ( х , е ( х ) ) выполняется для всех х ∈ . Если ϕ находится в S e t, то мы также получаем функцию g такую, что g ( x ) является доказательством того, что ϕ ( x , f ( x ) ) выполняется для всех x ∈ Af:A→Bϕ(x,f(x))x∈AϕSetgg(x)ϕ(x,f(x))x∈A, Часто доказательство бесполезно в вычислительном отношении, и мы предпочитаем от него избавляться, особенно когда оно глубоко вложено в какое-то другое утверждение. дает нам возможность сделать это.Prop
Добавлено 2015-07-29: Существует вопрос , можно ли избежать в целом, автоматически оптимизируя прочь «бесполезный выделенный код». В некоторой степени мы можем сделать это, например, весь код, извлеченный из отрицательного фрагмента логики (материал, построенный из пустого типа, типа модуля, продуктов), бесполезен, поскольку он просто перемещается вокруг модуля. Но есть настоящие дизайнерские решения приходится делать при использовании Р г о р . Вот простой пример, где Σ означает, что мы находимся в T y p e, а ∃ означает, что мы находимся в P p o p . Если мы извлекаем из
PropPropΣType∃Prop
мы получим программу, которая разбивает n на младший бит b и оставшиеся биты k , т. е. вычисляет все. Если мы извлечем из
Π n : N Σ b : { 0 , 1 } ∃ k : N
Πn:NΣb:{0,1}Σk:Nn=2⋅k+b
nbk
тогда программа будет вычислять только младший бит
b . Машина не может сказать, какая из них правильная, пользователь должен сказать ей, что он хочет.
Πn:NΣb:{0,1}∃k:Nn=2⋅k+b
b