Pytanie jest dość ogólne. Aby odpowiedzieć na to pytanie w rozsądnej przestrzeni, dokonam wielu uproszczeń.
Uzgodnijmy terminologię. Program jest poprawny, jeśli sugeruje jego specyfikację. To niejasne stwierdzenie jest precyzyjne na wiele sposobów, poprzez określenie, czym dokładnie jest program, a co dokładnie specyfikacją. Na przykład podczas sprawdzania modelu program ma strukturę Kripke, a specyfikacja jest często formułą LTL . Lub, program może być listą instrukcji PowerPC, a specyfikacją może być zestaw twierdzeń Hoare-Floyda zapisanych, powiedzmy, w logice pierwszego rzędu. Istnieje bardzo wiele możliwych wariantów. Kuszące jest stwierdzenie, że w jednym przypadku (struktura Kripke) nie weryfikujemy rzeczywistego programu, podczas gdy w drugim przypadku (lista instrukcji PowerPC) to robimy. Jednak ważne jest, aby zdać sobie sprawę, że naprawdę przyglądamy się modelom matematycznym w obu przypadkach, i jest to całkowicie w porządku. (Sytuacja jest bardzo podobna do fizyki, gdzie na przykład mechanika klasyczna jest matematycznym modelem rzeczywistości).
Większość formalizacji rozróżnia składnię i semantykę programu; to znaczy, w jaki sposób jest reprezentowany i co to znaczy. Z punktu widzenia weryfikacji programu liczy się semantyka programu. Ale oczywiście ważne jest, aby mieć jasny sposób przypisywania znaczeń programom (składnie) programów. Dwa popularne sposoby to:
- (mały krok) semantyka operacyjna : Jest to bardzo podobne do definiowania języka programowania przez napisanie dla niego tłumacza. W tym celu musisz powiedzieć, jaki jest stan , na który wpływa każde zdanie w języku. (Możesz się zastanawiać, w jakim języku piszesz tłumacza, ale udam, że nie.)
- semantyka aksjomatyczna : tutaj każdy typ instrukcji ma schemat aksjomatyczny. Z grubsza, za każdym razem, gdy używane jest określone stwierdzenie tego typu, przekłada się to na możliwość używania pewnych aksjomatów. Na przykład przypisanie ma schemat { P [ x / e ] }x:=e ; dane przypisanie x : = x + 1 ma aksjomat { x + 1 = 1 }{P[x/e]}x:=e{P}x:=x+1 jeśli utworzymy instancję schematu za pomocą P = ( x = 1 ) .{x+1=1}x:=x+1{x=1}P=(x=1)
(Są inne. Szczególnie źle czuję się, gdy pomijam semantykę denotacyjną, ale ta odpowiedź jest już długa.) Kod maszynowy i semantyka operacyjna są bardzo zbliżone do tego, co większość ludzi nazwałaby „prawdziwym programem”. Oto kluczowy artykuł, który wykorzystuje semantykę operacyjną dla podzbioru kodu maszynowego DEC Alpha:
Dlaczego miałbyś kiedykolwiek używać semantyki wyższego poziomu, takiej jak aksjomatyczna? Gdy nie chcesz, aby Twój dowód poprawności był zależny od sprzętu, na którym działasz. Podejście polega zatem na udowodnieniu poprawności algorytmu w odniesieniu do pewnej wygodnej semantyki wysokiego poziomu, a następnie udowodnieniu, że semantyka brzmi w odniesieniu do semantyki niższego poziomu, które są bliższe rzeczywistym maszynom.
Podsumowując, mogę wymyślić trzy przyczyny, które doprowadziły do twojego pytania:
- Widziałeś tylko semantykę wysokiego poziomu, która nie wygląda tak, jak zwykłaś nazywać program, i zastanawiasz się, czy są semantyki niskiego poziomu. Odpowiedź brzmi tak.
- Zastanawiasz się, jak udowodnić, że model odpowiada rzeczywistości. Podobnie jak w fizyce, nie. Po prostu wymyślasz lepsze modele i porównujesz je z rzeczywistością.
- Nie widziałeś rozróżnienia między składnią i semantyką oraz różnymi sposobami przypisywania znaczenia programom. Dwa poprzednie pytania wymieniają niektóre książki.
Ta odpowiedź próbuje jedynie zidentyfikować trzy różne sposoby, w jakie zrozumiałem pytanie. Wchodzenie głęboko w którykolwiek z tych punktów wymagałoby dużo miejsca.