Szukaj…


Wprowadzenie

Listy różnic w Prologu oznaczają pojęcie znajomości struktury listy do pewnego momentu . Pozostałą część listy można pozostawić niezwiązaną do czasu pełnej oceny predykatu. Lista, której koniec jest nieznany, jest nazywana otwartą listą zakończoną dziurą . Ta technika jest szczególnie przydatna do sprawdzania poprawności złożonych składni lub gramatyk.

Dobrze znane gramatyki określonych klauzul (DCG) używają list różnic do działania pod maską.

Podstawowe użycie

Rozważmy predykat sumDif/2 , zweryfikowany, czy struktura listy odpowiada kilku ograniczeniom. Pierwszy termin reprezentuje listę do analizy, a drugi termin inną listę, która zawiera część pierwszej listy, która jest nieznana naszym ograniczeniom.

Dla celów demonstracyjnych sumDif/2 rozpoznaje wyrażenie arytmetyczne do sumowania n liczb całkowitych.

sumDif([X, +|OpenList], Hole) :-
    integer(X),
    sumDif(OpenList, Hole).

Wiemy, że pierwszym elementem listy do sprawdzenia poprawności jest liczba całkowita, tutaj zilustrowana przez X , po której następuje symbol dodania ( + ). Pozostała część listy, która musi zostać przetworzona później ( OpenList ), pozostaje nieważna na tym poziomie. Hole reprezentuje tę część listy, której nie musimy weryfikować.

sumDif/2 inną definicję predykatu sumDif/2 aby zakończyć sprawdzanie poprawności wyrażenia arytmetycznego:

sumDif([X|Hole], Hole) :-
    integer(X).

Oczekujemy liczby całkowitej o nazwie X bezpośrednio na początku otwartej listy. Co ciekawe, pozostała część listy Hole pozostaje nieznana i to jest cały cel list różnic: struktura listy jest znana do pewnego momentu.

Wreszcie brakujący element pojawia się podczas oceny listy:

?- sumDif([1,+,2,+,3], []).
true

To wtedy, gdy używany jest predykat, wspomniany jest koniec listy, tutaj [] oznacza, że lista nie zawiera dodatkowych elementów.

Oceń wyrażenie arytmetyczne

Zdefiniujmy gramatykę umożliwiającą dodawanie, mnożenie z użyciem nawiasów. Aby dodać więcej wartości do tego przykładu, obliczymy wynik wyrażenia arytmetycznego. Podsumowanie gramatyki:

wyrażenie → czasy
wyrażenie → razy wyrażenie „+”
razy → element
razy → element „*” razy
element → „liczba całkowita”
element → „(„ wyrażenie ”)”

Wszystkie predykaty mają arity 3, ponieważ muszą otworzyć listę, dziurę i wartość wyrażenia arytmetycznego.

expression(Value, OpenList, FinalHole) :-
    times(Value, OpenList, FinalHole).

expression(SumValue, OpenList, FinalHole) :-
    times(Value1, OpenList, ['+'|Hole1]),
    expression(Value2, Hole1, FinalHole),
    plus(Value1, Value2, SumValue).

times(Value, OpenList, FinalHole) :-
    element(Value, OpenList, FinalHole).

times(TimesValue, OpenList, FinalHole) :-
    element(Value1, OpenList, ['*'|Hole1]),
    times(Value2, Hole1, FinalHole),
    TimesValue is Value1 * Value2.

element(Value, [Value|FinalHole], FinalHole) :-
    integer(Value).

element(Value, ['('|OpenList], FinalHole) :-
    expression(Value, OpenList, [')'|FinalHole]).

Aby właściwie wyjaśnić zasadę otworów i sposób obliczania wartości, weźmy expression drugiego zdania:

expression(SumValue, OpenList, FinalHole) :-
    times(Value1, OpenList, ['+'|Hole1]),
    expression(Value2, Hole1, FinalHole),
    plus(Value1, Value2, SumValue).

Otwarta lista jest oznaczona predykatem OpenList . Pierwszym elementem do walidacji jest to, co występuje przed symbolem dodawania ( + ) . Po sprawdzeniu pierwszego elementu następuje bezpośrednio po nim symbol dodania i kontynuacja listy o nazwie Hole1 . Wiemy, że Hole1 jest kolejnym elementem do sprawdzenia poprawności i może być innym expression , dlatego Hole1 jest wówczas terminem nadanym dla expression predykatu.

Wartość jest zawsze reprezentowana w pierwszym terminie. W tej klauzuli jest on zdefiniowany przez sumę Value1 (wszystko przed symbolem dodawania) i Value2 (wszystko po symbolu dodawania).

Wreszcie wyrażenie może zostać ocenione.

?- expression(V, [1,+,3,*,'(',5,+,5,')'], []).
V = 31


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow