Prop jest bardzo przydatny do ekstrakcji programu, ponieważ pozwala nam usuwać części kodu, które są bezużyteczne. Na przykład, aby wyodrębnić algorytm sortowania, udowodnilibyśmy zdanie „dla każdej listy istnieje lista taka, że jest uporządkowane, a jest permutatiom z ”. Jeśli zapiszemy to w Coq i wyodrębnimy bez użycia , otrzymamy:k k k ℓ P r o pℓkkkℓProp
- „dla wszystkich jest ” da nam mapę, która przenosi listy do list,kℓk
sort
- „takie, że jest uporządkowane” da funciton, który biegnie przez i sprawdza, czy jest posortowany, ikk
verify
k
- „ jest permutacją ” daje permutację, która prowadzi do . Zauważ, że to nie tylko mapowanie, ale także mapowanie odwrotne wraz z programami weryfikującymi, czy te dwie mapy są rzeczywiście odwrotne.ℓ ℓ kkℓ
pi
ℓkpi
Podczas gdy dodatkowe rzeczy nie są całkowicie bezużyteczne, w wielu aplikacjach chcemy się ich pozbyć i zachować sprawiedliwość sort
. Można to osiągnąć, jeśli użyjemy aby stwierdzić, że „ jest uporządkowane”, a „ jest permutacją ”, ale nie „dla wszystkich istnieje ”. k k ℓ ℓ kPropkkℓℓk
Ogólnie powszechnym sposobem na wyodrębnienie kodu jest rozważenie wyrażenia w postaci gdzie jest wprowadzane, jest wyjściem, a wyjaśnia, co to znaczy, że jest poprawnym wyjściem. (W powyższym przykładzie i to typy list, a to „ jest uporządkowane, a jest permutacją .”) Jeśli znajduje się w to wyodrębnij daje mapę taką, że dla wszystkichx y ϕ ( x , y ) y A B ϕ ( ℓ , k ) k k ℓ ϕ P r o p f : A → B ϕ ( x , f ( x ) ) x ∈ A ϕ S e t g g ( x ) ϕ ( x ,∀ x : A.. Y: B.ϕ ( x , y)xyϕ ( x , y)yZAbϕ ( ℓ , k )kkℓϕP r o pfa: A → Bϕ ( x , f(x))x∈A . Jeśli znajduje się w wtedy również uzyskać funkcję takie, że jest dowodem na to, że posiada, dla każdego . Często dowód jest bezużyteczny obliczeniowo i wolimy się go pozbyć, zwłaszcza gdy jest głęboko zagnieżdżony w innym wyrażeniu. daje nam taką możliwość.ϕSetgg(x)x ∈ A P r o pϕ(x,f(x))x∈AProp
Dodano 2015-07-29: Istnieje pytanie, czy moglibyśmy całkowicie uniknąć , automatycznie optymalizując „bezużyteczny wyodrębniony kod”. Do pewnego stopnia możemy to zrobić, na przykład cały kod wyodrębniony z negatywnego fragmentu logiki (rzeczy zbudowane z pustego typu, typu jednostki, produktów) jest bezużyteczny, ponieważ tylko tasuje wokół jednostki. Ale przy użyciu należy podjąć autentyczne decyzje projektowe . Oto prosty przykład, w którym oznacza, że jesteśmy w a oznacza, że jesteśmy w . Jeśli wyciągniemy z
P r o p Σ T y p e ∃ P r o p Π n : N Σ b : { 0 , 1 } Σ k : NPropPropΣType∃Propn b k Π n : N Σ b : { 0 , 1 } ∃ k : N
Πn:NΣb:{0,1}Σk:Nn=2⋅k+b
otrzymamy program, który rozkłada na najniższy bit a pozostałe bity , tzn. oblicza wszystko. Jeśli wyciągniemy z
wówczas program obliczy tylko najniższy bit . Maszyna nie może powiedzieć, który jest prawidłowy, użytkownik musi powiedzieć mu, czego chce.
nbkbΠn:NΣb:{0,1}∃k:Nn=2⋅k+b
b