1.1.5 Wybrane elementy teorii analizy tekstów Poprzednie

Transkrypt

1.1.5 Wybrane elementy teorii analizy tekstów Poprzednie
1.1.5 Wybrane elementy teorii analizy tekstów
Poprzednie podrozdziały przedstawiły dwie podstawowe metody
formalizacji: formalizację języka danej dziedziny wiedzy oraz formalizację
dziedziny wiedzy opisanej matematycznie jako wielosortowa struktura
relacyjna. Pokazane przykłady formalizacji ujawniły nam jednak, Ŝe
formalizacja dokonywana jest z wykorzystaniem innej wiedzy niŜ wiedza, którą
reprezentujemy – wykorzystujemy dodatkowo wiedzę o tym jak rozumieć
formalnie (logicznie) opisywane reprezentacje wiedzy z danej dziedziny
(obrazy, napisy, tabele decyzyjne itp.). ZauwaŜmy, Ŝe
w kaŜdym obiekcie reprezentującym wiedzę W moŜe być reprezentowana
takŜe wiedza o odniesieniach do wiedzy W, jak i wiedza o tworzeniu (produkcji,
konstruowaniu, budowie) tych reprezentacji; ta dodatkowa wiedza jest
niezbędna do tego, aby człowiek (agent) dysponując konkretną reprezentacją
wiedzy W mógł wiedzę W pozyskać i zrozumieć
(ogólnie, przetwarzać tę wiedzę) .
JeŜeli jakiś konkretny obiekt słuŜący do reprezentacji wiedzy obejmuje
wszystkie wyŜej opisane reprezentacje wiedzy: reprezentacje danej wiedzy,
reprezentacje wiedzy na jaką wskazują te reprezentacje oraz reprezentacje o
budowaniu reprezentacji wiedzy, to te reprezentacje będziemy nazywali
tekstami (obiekty zawierające wszystkie z wymienionych typów reprezentacji
nazywamy
znakami).
Przykładami
obiektów
zawierających
czy
udostępniających teksty są konkretne ksiąŜki, teksty dowodów twierdzeń czy
wyszukiwarki internetowe. W ramach nauki logika, systemy wiedzy o tekstach
(znakach) reprezentujących wiedzę i odnoszących się do wiedzy z danej
dziedziny wiedzy nazywane są systemami tekstowymi (systemami
znakowymi) lub systemami semiotycznymi w dziedzinie logiki zwanej
semiotyką. Np. systemami tekstowymi są: wcześniej określana w systemie
multimedialnym dowolna rzeczywistość wirtualna, a takŜe system znaków
drogowych ustawionych na ulicach miasta, system tekstów mowy pisanej,
reprezentującej słownictwo oraz zasady pisowni i zasady gramatyki, system
określający język w lingwistyce matematycznej czy teorii automatów, system
tekstów definiujących język programowania, systemy notacji języka formalnego
– sieci semantyczne, systemy BNF, drzew wyprowadzeń oraz drzew struktur
budowy formuł.
W 1981 r. została wydana ksiąŜka Witolda Marciszewskiego „Metody
analizy tekstu naukowego”. ChociaŜ praca ta była przygotowana dla
wydawnictwa jako poradnik, czy przewodnik po wskazanej w tytule ksiąŜki
dziedzinie wiedzy, poradnik przeznaczony dla nauczycieli akademickich i
studentów, to prezentowała ona takŜe nowatorskie idee oraz wytyczała nowe
kierunki badań. Zwłaszcza prekursorskie było zaproponowanie, jako głównego
celu logicznej analizy tekstu, badania logicznego związku pomiędzy tematem
(tekstem lub symbolem nieterminalnym) a rematem (tekstem lub symbolem
terminalnym), tj. pomiędzy tymi fragmentami tekstu, które reprezentują wiedzę
potrzebną do wyznaczenia i reprezentowania innej wiedzy, a tymi fragmentami
tekstu, które reprezentują wiedzę wyznaczoną na podstawie tematu (symbolu
nieterminalnego). W tym ujęciu, istotą logicznej poprawności jednostki tekstu
jest występowanie logicznego stosunku pomiędzy tematem (symbolem
nieterminalnym) i rematem (symbolem terminalnym). Ten związek logiczny
ustala się dokonując formalnego opisu relacji określających zwartość
tematyczną tekstów z danej dziedziny wiedzy, do której analizowany tekst
naleŜy. Analizowane relacje zwane są relacjami nawiązywania. Na podstawie
tych relacji jedne teksty są wyprowadzane z drugich, adekwatnie do
wyznaczania jednej wiedzy przez drugą. W sensie wyprowadzalności tekstów,
w dowolnym wyprowadzeniu jedne teksty są następnikami innych, w tym
teksty wyprowadzane (rematy) są następnikami tekstów (tematów), z którymi
pozostają w relacji nawiązywania. Relacja bycia następnikiem ustala pewien
porządek tekstów, umoŜliwiający wykorzystanie do badania struktury
tematycznej tekstu aparatu pojęciowego teorii krat. Ze względu na znaczenie
pojęć tematu i rematu dla analizy tekstu, postuluje się utworzenie teorii, którą
Autor omawianej pracy proponuje nazwać logiczną teorią tekstu. Standardowe
procedury logicznej analizy tekstu mogły być rozpoznane dzięki określaniu
języków programowania i zastosowaniom tych języków do implementacji
algorytmów rozwiązujących zadania informatyczne, np. w programowaniu
logicznym języka Prolog, czy bardziej dojrzałej postaci tego języka - języka
Turbo Prolog1. Języki programowania określa się uŜywając symboli
nieterminalnych (tematów) oznaczających operacje tworzące słowa języka z
symboli terminalnych (rematów). Działanie wyszukiwarki internetowej wiąŜe
podany prze uŜytkownika temat poszukiwań z z rematem – wynikiem tych
poszukiwań. Definicja tekstu w edytorze TEX jest tematem edycji, a rematem
jest wynik kompilacji tej definicji przez stosowny program edytora. W
informatyce sformułowanie zadania (problemu) zawiera: dane wejściowe,
stanowiące temat zadania oraz dane wyjściowe, stanowiące jego remat. W
zapisie programu, tematy są zaimplementowane jako ciągi instrukcji
przetwarzających dane wejściowe w dane wyjściowe, rematy są określone przez
instrukcji określające, które z uzyskanych danych są wyjściowe oraz instrukcje
ustalające zatrzymanie realizacji programu (instrukcje „stop”). Istotą
programowania logicznego jest, jak się zazwyczaj postuluje:
1) taka formalizacja tekstu zadania, wyraŜonego w języku jakiejś dziedziny
wiedzy, która reprezentuje (wyraŜa, przedstawia) wiedzę logiczną o danych i
faktach, do których odwołuje się (nawiązuje) tekst zadania, a więc
reprezentacja tego co jest dla tego tekstu i dla danej dziedziny wiedzy
1
Przystępne wprowadzenie do programowania w języku Turbo Prolog moŜna znaleźć w: J. Szajna, M.
Adamski, T. Kozłowski, Programowanie w języku logiki, Warszawa 1991.
tematem,
utoŜsamianym w programowaniu logicznym z siecią
semantyczną,
2) formalizacja relacji nawiązywania, ustalających sekwencje operacji
prowadzących od danych i faktów do innych danych i faktów lub do nowych
danych (szukanych) i ustaleń (tj. do rematu); w programowaniu logicznym
sekwencjom tych operacji odpowiada przestrzeń rozwiązań, a zbiorowi
relacji nawiązywania - baza wiedzy,
3) formalizacja wszystkich faktów określonych przez relacje nawiązywania
występujące w tekście zadania; w programowaniu logicznym reprezentacji
tych faktów odpowiada dynamiczna baza danych,
4) formalizacja zbioru danych, niekoniecznie występujących w tekście zadania,
do których trzeba się odwołać, aby uzyskać to co jest szukane; w
programowaniu logicznym odpowiada temu zewnętrzna baza danych,
formalizacja zapytań, określających to co szukane i co ma być ustalone, a więc
reprezentacja tego co jest dla danego tekstu zadania rematem.
Podsumowując rozwaŜania dotyczące formalizacji naszkicujemy aparat
pojęciowy umoŜliwiający sformułowanie logicznej teorii tekstu, podając
stosowne postulaty znaczeniowe w języku teorii mnogości. Przez wiedzę
będziemy rozumieć, jak poprzednio, informację przetwarzaną w umyśle
człowieka, a przez reprezentację wiedzy, przedstawianie (kodowanie) wiedzy za
pomocą róŜnorakich środków w ramach systemów komunikacji międzyludzkiej.
Reprezentacje wiedzy są więc tekstami. Zrelatywizowanie reprezentacji wiedzy
do dziedzin wiedzy prowadzi do wyodrębnienia tekstowych dziedzin wiedzy,
a wyraŜanie tych tekstów w jakimś języku, do wyodrębnienia języka dziedziny
wiedzy. Gdy wszystkie równokształtne teksty reprezentują tę samą wiedzę (w
szczególności są pusto spełnione), a równokształtność jest kongruencją w
tekstowej dziedzinie wiedzy, to tekstową dziedzinę wiedzy nazywamy
systemem reprezentacji wiedzy.
1.1.5.1 Analiza tekstu w tekstowej dziedzinie wiedzy
Strukturę relacyjną < U, U0, ε, R> nazywamy tekstową dziedziną wiedzy, gdy
U jest niepustym zbiorem wszystkich tekstów reprezentujących wiedzę z pewnej
dziedziny, U0 – wyróŜnionym niepustym podzbiorem zbioru U zwanym bazą
tekstową, ε jest relacją częściowego porządku określoną na zbiorze U zwaną
relacją bycia częścią tekstów, a R jest ustalonym zbiorem relacji określonych
w U zwanych relacjami nawiązywania tekstów.
Niech TDW = < U, U0, ε, R> jest tekstową dziedziną wiedzy.
(a) Dwa teksty α,β∈U są równokształtne, gdy dwie struktury relacyjne
powstałe przez ograniczenie uniwersum struktury TDW odpowiednio do
zbiorów {t∈U : t ε α}, {t∈U : t ε β}, są izomorficzne oraz części tekstu α
pozostają w tych samych relacjach w strukturze TDW co ich obrazy
izomorficzne będące częściami tekstu β.
(b) Tekst α jest wyprowadzalny ze zbioru tekstów X⊆U, co zapisujemy X |- R
α, gdy istnieje taki tekst β, zwany wyprowadzeniem tekstu α ze zbiory X, i
istnieje taki ciąg tekstów α1, α2, ..., αn ∈ U, Ŝe spełnione są warunki
(1) teksty α1, α2, ..., αn zawarte są w tekście β,
(2) αn = α,
(3) dla dowolnych i≤n: bądź αi ∈ X, bądź istnieją takie i1, i2, ..., ik < i oraz
istnieje taka relacja r ∈ R, Ŝe <αi1, αi2, ..., αik,, αi> ∈ r
(4) β jest najmniejszym tekstem w <U, ε > spełniającym warunki (1)-(3).
(c) Ramą zbioru tekstów X⊆U jest zbiór Fr(X) = {α∈U : X |- R α }
(d) Poprawnie zbudowanymi są teksty naleŜące do zbioru Fr(U0).
(e) Dla dowolnych tekstów α, β ∈U,
α ≥ β wttw istnieje taki zbiór X tekstów, Ŝe β ∈ X i X |- R α i nieprawdą jest
X\{β} |- R α, napis „α ≥ β” czytamy: α nawiązuje do β, lub α jest
następnikiem β,
(f) Dla dowolnego tekstu α∈U, zbiór Parts(α) = {t∈U : t ε α} zwany jest
budową tekstu α.
(g) Tekst β jest rematem tekstu α wttw β ∈ Fr(U0), α ≠ β, β ∈ Parts(α) oraz
nie istnieje taki tekst t∈ Parts(α), Ŝe t≥β; innymi słowy: tekst β jest
rematem tekstu α, gdy jest wyprowadzalny z tekstów bazowych (nawiązuje
do tych tekstów), jest częścią właściwą tekstu α oraz Ŝadna część tekstu α
nie jest jego następnikiem; intuicyjnie, remat danego tekstu jest tą jego
częścią, która nie słuŜy do zrozumienia innych części tego tekstu, a jedynie
sama moŜe być zrozumiana dzięki nawiązaniu do wcześniejszych tekstów,
(h) Tekst t jest tematem tekstu α wttw t ∈ Fr(U0), α ≠ t, t ∈ Parts(α) oraz
kaŜdy następnik t naleŜący do Parts(α) jest rematem α; innymi słowy: tekst t
jest tematem tekstu α, gdy jest jego częścią właściwą, której kaŜdy następnik
będący częścią α jest rematem; intuicyjnie, tematem danego tekstu jest kaŜda
jego właściwa część, która słuŜy do zrozumienia rematu tego tekstu, tak
więc, aby zrozumieć remat nawiązujemy najpierw do tematów, a następnie
do tekstów, z których tematy są wyprowadzone,
(i) Dowolny tekst jest jednostką tekstu, gdy posiada w swojej budowie
rematy i tematy oraz gdy ze zbioru wszystkich tematów tego tekstu
wyprowadzalny jest kaŜdy z rematów.
ZauwaŜmy, Ŝe dowolne wyprowadzenie tekstu poprawnie zbudowanego jest
jednostką tekstu.
1.1.5.2 Definicja systemu reprezentacji wiedzy
WaŜne jest takŜe stwierdzenie, Ŝe
dla dowolnej tekstowej dziedziny wiedzy TDW, w której wszystkie
równokształtne teksty reprezentują tę samą wiedzę, jeŜeli relacja
„~” równokształtności tekstów jest kongruencją w TDW (tj.
zachodzenie relacji pomiędzy danymi tekstami przechodzi na
zachodzenie
tych
samych
relacji
pomiędzy
tekstami
równokształtnymi do odpowiednich danych tekstów, np. jeśli
relacja(tekst1, tekst2) i tekst1~tekst1’ oraz tekst2~tekst2’, to
relacja(tekst1’, tekst2’)), to struktura ilorazowa TDW/~ jest takŜe
tekstową dziedziną wiedzy.
Uzasadnione jest więc sformułowanie następującej definicji:
Niech w tekstowej dziedzinie wiedzy TDW wszystkie równokształtne teksty
reprezentują tę samą wiedzę, a relacja „~” równokształtności tekstów jest
kongruencją w TDW. Wtedy strukturę ilorazową TDW/~ nazywamy systemem
reprezentacji wiedzy, relacje nawiązywania nazywamy relacjami
konkatenacji, a o wyprowadzeniu danego tekstu mówimy,
Ŝe jest
konkatenacją pewnego ciągu tekstów określonego przez definicję
wyprowadzenia tekstu. Tekstami są typy, tj. zbiory wszystkich tekstów
równokształtnych w TDW.
1.1.5.3 Definicja języka sformalizowanego
Przyjmijmy dalej, Ŝe wiedza logiczna jest informacją przetwarzaną w
umyśle identyfikującą ogólną budowę, cechy i przyporządkowania wszelkich
obiektów odnoszących się do danej dziedziny wiedzy oraz identyfikującą
relacje pomiędzy tymi obiektami.
Język, w którym przedstawiamy schematycznie, za pomocą schematów, tj.
formuł, wzorów, planów, diagramów itp., wiedzę logiczną nazywamy językiem
sformalizowanym. Język ten jest określony przez cztery zbiory symboli < Al,
Tr, Fm, W>, Al jest alfabetem, Tr – zbiorem termów, Fm – zbiorem formuł, a
W jest rodziną zbiorów formuł takich, Ŝe do kaŜdego z tych zbiorów naleŜą
formuły reprezentujące wiedzę o tej samej wartości logicznej. Alfabet składa
się ze stałych i zmiennych indywiduowych, będących zarazem termami,
symboli funkcyjnych – wiąŜących stałe i zmienne w termy, predykatów –
wiąŜących stałe i zmienne w formuły, spójników – wiąŜących formuły w inne
formuły, kwantyfikatorów – wiąŜących zmienne i formuły w inne formuły oraz
symboli pomocniczych (np. nawiasów, ramek, kropek, linii, strzałek itd.).
Przykładem języka sformalizowanego jest język będący wynikiem formalizacji
(schematyzacji) języka dowolnej dziedziny wiedzy.
1.1.5.4 Definicja systemu reprezentacji wiedzy
Systemem reprezentacji wiedzy logicznej nazywamy system reprezentacji
wiedzy, w którym zbiorem tekstów bazowych jest zbiór wszystkich symboli
języka sformalizowanego, a zbiór relacji konkatenacji pozwala
1) wyróŜnić wszystkie składniki języka sformalizowanego,
2) wyprowadzić formuły poprawnie zbudowane,
3) tworzyć teksty wywodów prowadzących od formuł o określonej wartości
logicznej do formuł o określonej wartości logicznej (niezmienniczość
wartości logicznych względem wywodów).
Systemy reprezentacji wiedzy logicznej są niekiedy nazywane logikami. W
podrozdziale 1.2 określimy system zwany logiką pierwszego rzędu.
1.1.6 Pojęcie języka w lingwistyce matematycznej
Najprostszymi przykładami systemów tekstowych w lingwistyce
matematycznej lub teorii automatów skończonych albo teorii obliczeń (takŜe
teorii algorytmów) są systemy dla których określamy pewne języki
sformalizowane zwane językami abstrakcyjnymi, krótko językami.
Niech V jest dającym się określić zbiorem, zwanym alfabetem, którego
elementy nazywane są literami, dowolne ciągi liter słowami. KaŜdą literę
moŜna utoŜsamiać ze słowem. Alfabet jest tak określony, Ŝe moŜna w nim
wyróŜnić jedną literę oznaczaną symbolem Λ. Słowo zbudowane tylko z litery Λ
nazywa się słowem pustym. Liczbę liter w słowie określa się jako liczbę liter
l(x) w ciągu x, ale dla słowa pustego przyjmuje się: l(Λ)=0. Dalej, określa się
relację dwuargumentową zwaną konkatenacją w taki sposób, Ŝe dla dwu
dowolnych słów x, y konkatenacją jest słowo będące sklejeniem tych słów
oznaczane xy lub x•y. Przyjmuje się dla dowolnego słowa x, Ŝe Λx = xΛ = x.
Posługując się słowem pustym moŜna w sposób prosty zdefiniować zawieranie
się słowa x w słowie y:
x zawiera się w y wtedy i tylko wtedy,
gdy istnieją takie słowa w1, w2, Ŝe y=w1xw2.
Zbiór V* zwany zbiorem słów nad alfabetem V moŜemy określić takŜe
rekurencyjnie:
S1.
Λ∈V*,
S2.
s∈V* ∧ x∈V ⇒ xs,
S3.
nic innego nie jest słowem.
Podobnie, długość l(x) słowa x moŜna określić rekurencyjnie:
L1.
l(Λ) = 0,
L2.
x∈V ∧ s∈V* ⇒ l(xs) = 1+l(s).
Dowolny podzbiór L zbioru słów V* nazywamy językiem abstrakcyjnym
lub krótko językiem.
Niech zbiór T⊆V jest zbiorem liter zwanych literami terminalnymi. Litery,
które nie są terminalne będziemy nazywać nieterminalnymi. WyróŜnijmy
jedno słowo nieterminalne S. Słowo to nazywamy wyjściowym. Określmy
funkcję częściową π przyporządkowującą pewnym słowom pewne litery
nieterminalne. Funkcję π nazywamy operacją przypisania słów literom
nieterminalnym. Przypisanie słowa s literze nieterminalnej M, jako słowu,
nazywamy regułą produkcji i oznaczamy: M::=s lub M→s.
Wprowadzamy następującą operację wyprowadzalności:
słowo s2 jest wyprowadzane ze słowa s1 wtedy i tylko wtedy, gdy dla
pewnej reguły produkcji M::=s jeśli M jest literą naleŜąca do słowa s1
i zastąpimy ją w kaŜdym miejscu, gdzie występuje w słowie s1 przez
słowo s, to w wyniku tego postawienia otrzymamy słowo s2.
JeŜeli dla słowa s1Ms2 zastosujemy regułę M::=s, to otrzymamy słowo s1ss2.
Układ G = <V, T, S, π> nazywamy gramatyką bezkontekstową.
PoniewaŜ, dla operacji przypisania, kaŜdemu słowu naleŜącemu do dziedziny
tej operacji, odpowiada litera nieterminalna, która moŜe teŜ być słowem
naleŜącym do dziedziny operacji przypisania, więc moŜna iterować
(wielokrotnie stosować) operację przypisania do danego słowa. Gdy po tych
iteracjach operacji przypisania, dla danego słowa przypisanego słowu
wyjściowemu S, moŜna przekształć to słowo w słowo będące konkatenacją tyko
symboli terminalnych, to takie słowo nazywać będziemy akceptowalnym lub
generowanym przez gramatykę G. Zbiór słów w tym sensie akceptowalnych
określa język bezkontekstowy L(G).
Przykład 1.1.6.1
Zbiór V = {Λ, S, A, B, 0, 1} , gdzie T = {0, 1} z regułami produkcji:
S::= SAB,
S::= Λ
A::= 0,
B::= 1
określa gramatykę bezkontekstową języka bezkontekstowego L⊆V*.
PokaŜemy, Ŝe słowo 0101 jest generowane przez tę gramatykę (akceptowalne).
1.
2.
S
SAB
słowo wyjściowe,
Reg. S::= SAB,
3.
4.
5.
6.
7.
8.
S0B
S01
SAB01
S0B01
S0101
Λ0101
0101
Reg. A::= 0,
Reg. B::= 0,
Reg. S::= SAB,
Reg. A::= 0,
Reg. B::= 0,
Reg. S::= Λ
z Λ0101=0101 na podstawie własności konkatenacji.
Przykład 1.1.6.2
Implementacja powyŜszego przykładu w języku Turbo Prolog
PREDICATES /*deklaracje predykatów */
litera_alfabetu(string)
/*predykat uznający litery w jednoelementowych łańcuchach za litery
budowanego języka */
litera_terminalna(string)
/*predykat ustalajacy, Ŝe litera w jednoelementowym łańcuchu jest literą
terminalną */
słowo(string)
/* predykat ustalający, Ŝe łańcuch liter jest słowem */
CLAUSES /*deklaracja formuł – klauzul – faktów i reguł */
/* deklaracja liter alfabetu */
litera_alfabetu(""). /* "" - słowo puste */
litera_alfabetu("S").
litera_alfabetu("A"). litera_alfabetu("B").
litera_alfabetu("0"). litera_alfabetu("1").
/* deklaracja liter terminalnych */
litera_terminalna("0"). litera_terminalna("1").
/* deklaracja słów */
słowo(X) :- litera_alfabetu(X).
słowo(Z) :- słowo(X), słowo(Y), concat(X,Y,Z).
/* concat(X,Y,Z) jest standardowym zapisem tworzącym dla łańcuchów słów X,
Y ich konkatenację Z=XY lub dla X,Z znajdujący Y, lub dla Y,Z znajdujący X */
Przykład 1.1.6.3
Relacje i operacje na tekstach (łańcuchach znaków, słowach języka)
PREDICATES
zawieranie(string,string)
/* zawieranie(T1,T2) – tekst T1 zawarty jest w tekście T2, np. tekst „bc”
zawarty jest w tekście „aabcd” */
podstawienie(string,string,string,string)
/* podstawienie(T1,T2,T3,T4) – tekst T4 jest wynikiem podstawienia
tekstu T1 za tekst T2 w tekście T3 na pierwszym miejscu, na którym tekst T2
występuje w tekście T3. Np. tekst „aabbc” jest wynikiem podstawienie tekstu
„a” za tekst „b” na pierwszym miejscu w tekście „abbbc” , gdzie tekst „b”
występuje */
poczatek(string,string,string)
/* poczatek(T1,T2,P) – tekst P jest częścią tekstu T2 poprzedzającą
występowanie w nim tekstu T1 */
koniec(string,string,string)
/* koniec(T1,T2,P) – tekst P jest częścią tekstu T2 następującą po
występowaniu w nim tekstu T1 */
podstawienie_globalne(string,string,string,string)
/* podstawienie_globalne(T1,T2,T3,T4) – tekst T4 jest wynikiem
podstawienia tekstu T1 za tekst T2 w tekście T3 w kaŜdym miejscu, na którym
tekst T2 występuje w tekście T3. Np. tekst „aaaac” jest wynikiem podstawienie
tekstu „a” za tekst „b” w kaŜdym miejscu w tekście „abbbc” , gdzie tekst „b”
występuje */
cyfra(string)
/* predykat cyfra(T)rozpoznaje wśród łańcuchów znaków cyfry: „0”, „1”,
...”9” */
ciag_cyfr(string)
/* predykat ciag_cyfr(T)rozpoznaje wśród łańcuchów znaków ciągi cyfr:
np. „019” */
ciag_cyfr_w_tekscie(string,string,string)
/* ciag_cyfr_w_tekscie(T,L,R) – L jest ciągiem cyfr na początku
tekstu T, a R jest pozostałą częścią tekstu T */
napis_liczby(string)
/* predykat napis_liczby(T) rozpoznaje wśród ciągów cyfr napisy liczb, tj.
ciągi cyfr nie zaczynające się od cyfry „0” */
napis_liczby_w_tekscie(string,string,string) /* - predykat
rozpoznaje na początku tekstu napis liczby oraz wyróŜnia pozostałą część takstu
*/
CLAUSES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
ZAWIERANIE TEKSTÓW
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
zawieranie("","").
zawieranie(T1,T2):T2<>"",concat(T1,_,T2);
T2<>"",frontStr(1,T2,_,N_T2),
zawieranie(T1,N_T2).
/* występowanie w argumencie formuły atomowej symbolu „_“ oznacza, Ŝe
istnieje jakaś wartość tego argumentu przy której formuła ta zachodzi;
wyraŜenie postaci frontStr(1,T2,_,N_T2)oznacza, Ŝe z tekstu T2
została pobrana pierwsza litera i reszta po pobraniu tej litery jest tekstem N_T2;
zawieranie tekstów zostało określone rekurencyjnie: 1) tekst pusty zawiera się w
tekście pustym, 2) zawieranie tekstu T1 w tekście T2 zachodzi, gdy istnieje jakiś
tekst taki, Ŝe konkatenacja T1 z tym tekstem daje tekst T2, jeśli tak nie jest, to
sprawdzamy ten warunek po popraniu a tekstu T2 pierwszej litery, a pobieranie
liter powtarzamy do momentu uzyskania zawierania, lub do momentu
otrzymania tekstu pustego, a wtedy zawieranie nie zachodzi */
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
koniec(T1,T2,K):T2<>"",concat(T1,K,T2),!;
T2<>"",frontStr(1,T2,_,N_T2),
koniec(T1,N_T2,K).
/* prosimy o wyjaśnienie powyŜszej reguły: określenie tekstu K, który przy
zawieraniu tekstu T1 w tekście T2 jest pozostałą częścią tekstu T2 występującą
po pierwszym zakończeniu tekstu T1 (tekst T1 moŜe wystąpić w róŜnych
miejscach tekstu T2) */
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
poczatek(T1,T2,P):koniec(T1,T2,K),concat(T,K,T2),concat(P,T1,T).
/* poczatek(T1,T2,P)- zachodzi przy zawieraniu tekstu T1 w tekście T2;
jeśli za pomocą predykatu konkatenacji i predykatu koniec pomniejszymy T2 o
koniec K, a tekst który pozostanie pomniejszymy o tekst T1, to otrzymamy
szukany początek P występujący w tekście T2 przed tekstem T1; P moŜe być
tekstem pustym */
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
PODSTAWIANIE TEKSTU ZA TEKST W TEKŚCIE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
podstawienie(T1,T2,T3,T4):T1<>T2, T3<>"",
poczatek(T2,T3,P),koniec(T2,T3,K),!,
concat(P,T1,T),concat(T,K,T4).
/* podstawienie(T1,T2,T3,T4) – pierwsze, jednokrotne, podstawienie
tekstu T1 za tekst T2 w tekście T3, w wyniku czego otrzymujemy tekst T4;
prosimy o wyjaśnienie podanej reguły */
podstawienie_globalne(T1,T2,T3,T4):podstawienie(T1,T2,T3,N_T3),!,
podstawienie_globalne(T1,T2,N_T3,T4);
T4=T3,!.
/* podstawienie_globalne(T1,T2,T3,T4) – kolejne podstawienia
tekstu T1 za tekst T2 w tekście T3 wszędzie tam gdzie tekst T2 występuje przy
pierwszym i po następnych podstawieniach, w wyniku czego otrzymujemy tekst
T4; prosimy o wyjaśnienie podanej reguły */
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
NAPIS LICZBY
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cyfra("0"). cyfra("1"). cyfra("2"). cyfra("3").
cyfra("4"). cyfra("5"). cyfra("6"). cyfra("7").
cyfra("8"). cyfra("9").
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
Rozpoznawanie napisu jako ciągu cyfr
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ciag_cyfr(X):X<>"", cyfra(X),!;
X<>"", cyfra(C), concat(C,N_X,X),cyfra(N_X),!;
X<>"", cyfra(C), concat(C,N_X,X),!, ciag_cyfr(N_X).
napis_liczby(X):X=”0”,!;
ciag_cyfr(X),frontStr(1,X,C,_),C<>"0",!.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
Rozpoznawanie ciągu cyfr na początku napisu
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ciag_cyfr_w_tekscie("","","").
ciag_cyfr_w_tekscie(T,L,R):T<>"",ciag_cyfr(T),L=T,R="",!;
T<>"", frontStr(1,T,L,R),cyfra(L),
frontStr(2,T,L1,_),not(ciag_cyfr(L1));
T<>"", frontStr(1,T,C,N_T), cyfra(C),
ciag_cyfr_w_tekscie(N_T,N_L,R),
concat(C,N_L,L).
napis_liczby_w_tekscie(T,L,R):ciag_cyfr_w_tekscie(T,L,R),
frontStr(1,L,C,_),C<>"0",!.
Problem 1.1.7.1
Wykorzystując podane implementacje dokonać implementacji definicji języka
niekontekstowego w języku Turbo Prolog.
1.1.7 Notacja Backusa-Naura (BNF)
KaŜdy język programowania trzeba poprawnie zdefiniować i opisać reguły
produkcji (tworzenia) napisów poprawnych i dopuszczalnych w tym języku.
Trzeba to uczynić nie tylko dla uczących się tego języka programistów, lecz
takŜe na uŜytek translatorów (kompilatorów), których przecieŜ podstawowym
zadaniem jest rozstrzyganie, czy dany ciąg symboli źródłowych jest programem.
Aby opis języka programowania był formalny, trzeba do tego celu uŜywać
pewnego „nadjęzyka”, czyli metajęzyka. Takim metajęzykiem jest właśnie
notacja zaproponowana pierwszy raz przez Backusa, a zastosowana na szeroką
skalę przez duńskiego informatyka Naura. Wprowadzona notacja jest wynikiem
prowadzenia specyficznej metody budowy języków bezkontekstowych, w
których symbole nieterminalne są pisanymi w nawiasach <,> symbolami
reprezentującymi nazwy składników metajęzyka słuŜącego do opisu budowy
języka formalnego, w tym najczęściej języka programowania. Do opisu ciągu
reguł produkcji słów uznanych za poprawnie zbudowane, ciągu postaci: N→x1,
N→x2, N→x3, N→x4,…, N→xk, stosuje się bardzo uŜyteczną umowę notacyjną,
ciąg tych reguł zapisuje się w postaci:
N::= x1| x2| x3| x4| ... | xk .
W notacji Backusa-Naura występują zmienne metajęzykowe (reprezentujące
nazwy składników języka formalnego) oznaczone przy pomocy dowolnych
napisów ujętych w nawiasy kątowe <, >, symbol ::= oraz kreska pionowa |
(rozumiana jako „albo”). Symbol ::= ma znaczenie „z definicji równa się”.
Przykładowo podamy określenie cyfry, litery i identyfikatora w języku Pascal:
<cyfra> ::= 0|1|2|3|4|5|6|7|8|9,
co czytamy – cyfrą w Pascalu z definicji jest 0 albo 1, albo 2, itd.
<litera> ::= a|b|c|...|x|y|z|A|B|C|...|X|Y|Z,
<identyfikator> ::= <litera>|<identyfikator><litera>|<identyfikator><cyfra>.
Tę ostatnią definicję czytamy – identyfikator jest literą albo ciągiem
identyfikatora i litery (ich konkatenacją, np. Aa), albo ciągiem identyfikatora i
cyfry (ich konkatenacją, np. A1).
Przykład 1.1.7.1
Rozpatrzmy język wyraŜeń algebraicznych. Symbolami nieterminalnymi są:
<zmienna>, <operacja>, <wyraŜenie>, zaś terminalnymi symbole liter: A, B, …,
Z, i symbole działań: +, -, ×, /, a ponadto symbole nawiasów: (,) oraz symolbol
równości: =. Symbolem wyjściowym (początkowym) jest <wyraŜenie>.
Określmy reguły produkcji języka wyraŜeń algebraicznych następująco:
<zmienna>::= A| B| … | Z
<operacja>::= +| -| ×| /| ^| √
<relacja>::= <| ≤| =| ≠| ≥| >
<nawiasy>::= <nawias lewy>| <nawias prawy>
<nawias lewy>::= (
<nawias prawy>::= )
<wyraŜenie>::=<zmienna>
|<nawias lewy><wyraŜenie><operacja><wyraŜenie><nawias prawy>
| <nawias lewy>-<wyraŜenie><nawias prawy>|
<nawias lewy> +<wyraŜenie><nawias prawy>| √<wyraŜenie>|
<wyraŜenie><relacja><wyraŜenie> .
Stosując zapis strzałkowy dla reguł produkcji moŜemy wywód wyraŜenia „(A(B×((A+C))/D))” napisać w postaci:
<wyraŜenie>→
<nawias lewy><wyraŜenie><operacja><wyraŜenie><nawias prawy>→
(A-<nawias lewy><wyraŜenie><operacja><wyraŜenie><nawias prawy>)→
(A-(B×<nawias lewy><wyraŜenie><operacja><wyraŜenie><nawias prawy>))→
(A-(B×(<wyraŜenie>/D)))→
(A-(B×(<nawias lewy><wyraŜenie><operacja><wyraŜenie>
<nawias prawy>/D)))→
(A-(B×((A+C)/D)))
JeŜeli zbiór reguł produkcji tekstu rozszerzymy o operacje pozwalające
podstawiać za dowolnie wybrane zmienne <wyraŜenie>, co np. dla zmiennej A
zapisujemy w skrócie
A := <wyraŜenie>,
zamiast zapisu reguły produkcji
<wyraŜenie>::= A:= <wyraŜenie>,
to tak określoną regułę produkcji będziemy nazywać regułą przypisania.
Reguła przypisania najczęściej jest uŜywana w językach programowania
do implementacji obliczeń liczbowych lub przetwarzania tekstów.
Przykład 1.1.7.2 Operacja przypisania dla wyraŜeń algebraicznych.
Niech w zaproponowanym języku wyraŜeń algebraicznych określone jest takŜe
tworzenie napisów liczbowych w notacji dziesiętnej dla symbolu
nieterminalnego <napis liczby>. Wykorzystując zaproponowaną notację reguły
przypisania zapisać tekst obliczenia wyraŜenia:
2 − 3,145 ,
wykorzystując w zapisie wyniku kaŜdej operacji tylko jedną zmienną X (tak
wykorzystywane zmienne reprezentują rejestry pamięci komputera; minimalna
ilość wykorzystanych zmiennych oznacza wykorzystanie minimalnego obszaru
pamięci komputera).
Obliczenie:
1.
X:=2
2.
X:=√X
3.
X:=(X – 3,415)
4.
X:=√X