JĘZYKI PRZETWARZANIA SYMBOLICZNEGO



Podobne dokumenty
Paradygmaty programowania

Programowanie deklaratywne

Podstawy programowania. Wykład: 4. Instrukcje sterujące, operatory. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Podstawy informatyki. Elektrotechnika I rok. Język C++ Operacje na danych - wskaźniki Instrukcja do ćwiczenia

Programowanie w logice

Programowanie deklaratywne

Bloki anonimowe w PL/SQL

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

Podstawy programowania funkcjonalnego

REKURENCJA W JĘZYKU HASKELL. Autor: Walczak Michał

Instrukcje sterujące. wer. 11 z drobnymi modyfikacjami! Wojciech Myszka :53:

Podstawy programowania w języku C

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

PROLOG. Prolog. Programowanie, W.F. Clocksin, C.S. Mellish, HELION Prolog, język sztucznej inteligencji, Eugeniusz Gatnar, Katarzyna Stąpor, Wyd.

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania

Wstęp do programowania

Podstawy programowania Laboratorium. Ćwiczenie 2 Programowanie strukturalne podstawowe rodzaje instrukcji

PoniŜej znajdują się pytania z egzaminów zawodowych teoretycznych. Jest to materiał poglądowy.

Języki programowania deklaratywnego

Myśl w języku Python! : nauka programowania / Allen B. Downey. Gliwice, cop Spis treści

Analiza algorytmów zadania podstawowe

Projekt 4: Programowanie w logice

Podstawy programowania. Wykład: 8. Wskaźniki. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Podstawy programowania skrót z wykładów:

Przeciążanie operatorów

Prolog struktury danych oraz obliczenia. 1. Arytmetyka?- Y is 2+2. Y = 4. ?- 5 is 3+3. false. ?- Z is (3.9 / 2.1). Z =

Instrukcje sterujące. Programowanie Proceduralne 1

Opis zagadnieo 1-3. Iteracja, rekurencja i ich realizacja

Zapis algorytmów: schematy blokowe i pseudokod 1

Jerzy Nawrocki, Wprowadzenie do informatyki

Rekurencja (rekursja)

Sortowanie przez scalanie

Strategia "dziel i zwyciężaj"

Podstawy programowania. 1. Operacje arytmetyczne Operacja arytmetyczna jest opisywana za pomocą znaku operacji i jednego lub dwóch wyrażeń.

Nazwa implementacji: Nauka języka Python pętla for. Autor: Piotr Fiorek

Funkcja (podprogram) void

Języki programowania obiektowego Nieobiektowe elementy języka C++

Algorytmika i pseudoprogramowanie

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Programowanie w VB Proste algorytmy sortowania

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

/* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include <aduc834.h>

Język C, tablice i funkcje (laboratorium, EE1-DI)

Języki C i C++ Wykład: 2. Wstęp Instrukcje sterujące. dr Artur Bartoszewski - Języki C i C++, sem. 1I- WYKŁAD

4 Literatura. c Dr inż. Ignacy Pardyka (Inf.UJK) ASK MP.01 Rok akad. 2011/ / 24

Definicje. Algorytm to:

1 Podstawy c++ w pigułce.

Elementy języka C. ACprogramislikeafastdanceonanewlywaxeddancefloorbypeople carrying razors.

Podstawy programowania C. dr. Krystyna Łapin

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Podstawy Programowania Podstawowa składnia języka C++

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40

PARADYGMATY PROGRAMOWANIA Wykład 3

Zasada indukcji matematycznej

Podstawy programowania w języku C i C++

Komentarze w PHP (niewykonywane fragmenty tekstowe, będące informacją dla programisty)

Wstęp do programowania INP001213Wcl rok akademicki 2018/19 semestr zimowy. Wykład 4. Karol Tarnowski A-1 p.

Programowanie proceduralne INP001210WL rok akademicki 2017/18 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Tablice mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Wstęp do programowania

Programowanie obiektowe

Wykład IV PASCAL - łańcuch znaków, - procedury i funkcje, - sortowanie bąbelkowe

Ćwiczenie 1. Wprowadzenie do programu Octave

1 Wprowadzenie do algorytmiki

SQL, LIKE, IN, CASE, EXISTS. Marcin Orchel

Podstawowe algorytmy i ich implementacje w C. Wykład 9

Algorytm. a programowanie -

Programowanie. programowania. Klasa 3 Lekcja 9 PASCAL & C++

Jerzy Nawrocki, Wprowadzenie do informatyki

Programowanie i struktury danych. Wykład 4 Dr Piotr Cybula

Programowanie w logice

EGZAMIN MATURALNY 2012 INFORMATYKA

ALGORYTMY Algorytm poprawny jednoznaczny szczegółowy uniwersalny skończoność efektywność (sprawność) zmiennych liniowy warunkowy iteracyjny

Szablony funkcji i szablony klas

Algorytmy i Struktury Danych, 2. ćwiczenia

TOPIT Załącznik nr 3 Programowanie aplikacji internetowych

Spis treści WSTĘP CZĘŚĆ I. PASCAL WPROWADZENIE DO PROGRAMOWANIA STRUKTURALNEGO. Rozdział 1. Wybór i instalacja kompilatora języka Pascal

Programowanie w logice Prolog 2

Rozwiązanie. #include <cstdlib> #include <iostream> using namespace std;

Ćwiczenie 1. Wprowadzenie do programu Octave

Pętla for. Matematyka dla ciekawych świata -19- Scilab. for i=1:10... end. for k=4:-1:1... end. k=3 k=4. k=1. k=2

1 Podstawy c++ w pigułce.

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

Kontrola przebiegu programu

Wykład II PASCAL - podstawy składni i zmienne, - instrukcje wyboru, - iteracja, - liczby losowe

Matlab Składnia + podstawy programowania

Wprowadzenie do programowania

Optimizing Programs with Intended Semantics

Proste programy w C++ zadania

Języki programowania. Przetwarzanie tablic znaków. Część druga. Autorzy Tomasz Xięski Roman Simiński

Podstawy Informatyki. Sprawność algorytmów

LibreOffice Calc VBA

2. Klasy cz. 2 - Konstruktor kopiujący. Pola tworzone statycznie i dynamicznie - Funkcje zaprzyjaźnione - Składowe statyczne

Klasa 2 INFORMATYKA. dla szkół ponadgimnazjalnych zakres rozszerzony. Założone osiągnięcia ucznia wymagania edukacyjne na. poszczególne oceny

Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania

Wstęp do Programowania Lista 1

Wstęp do programowania

Visual Basic for Application (VBA)

Transkrypt:

Agata Gawlik G1-ISI Warszawa dn. 16.05.2008 r. JĘZYKI PRZETWARZANIA SYMBOLICZNEGO Opracowanie tematów z PROLOGu UZGADNIANIE Uzgadnianie jest najważniejszą operacją wykonywaną na obiektach w języku PROLOG. Jest ono analogiczne do porównywania w językach proceduralnych, jednakże jest operacją o wiele potężniejszą oferującą szerokie spektrum możliwości. Prosty przykład uzgadniania służący wyszukiwaniu bezpośrednich połączeo autobusowych: Rozpatrzmy związek kurs (start, stop, odjazd). Zdefiniujmy fakty: kurs(warszawa, radom, 8.00). kurs(warszawa, kraków, 9.00). kurs(warszawa, kraków, 10.00). kurs(warszawa, radom, 11.00). kurs(warszawa, kielce, 12.00). Następnie definiujemy związek połączenie: połączenie( Sta, Sto, Godz) :- kurs(sta, Sto, Godz). Wyszukując połączenia z Warszawy do Radomia wprowadzamy cel:?_połączenie(warszawa, radom, Godz). Przy tak sformułowanym celu następowad będzie uzgadnianie zmiennej Godz poprzez porównywanie celu z podanymi faktami następuje przeszukanie przestrzeni rozwiązao. Aby podobny problem rozwiązad w dowolnym języku strukturalnym należałoby porównywad łaocuchy znakowe, co w przypadku rozpatrywanego problemu sprowadziłoby się do stworzenia odpowiedniej pętli warunkowej, przy czym konieczne byłoby wykrywanie zakooczenia wyszukiwania. Cały ten mechanizm jest wbudowany w interpreter języka PROLOG. Pokazany przykład prostego wnioskowania nie obrazuje w całości wszechstronności mechanizmu uzgadniania. Bardziej zaawansowane operacje można wykonywad w przypadku przetwarzania struktur danych przy pomocy procedur PROLOGowych. W szczególności dotyczy to list, które są wbudowaną w ten język strukturą. Operowanie na listach w językach deklaratywnych jest o tyle prostsze od podobnych działao w językach proceduralnych, że uwalnia programistę od konieczności zarządzania pamięcią, czy przechowywania wskaźników.

Najprostszym przykładem przetwarzania list może byd wypisanie jej elementów. Odpowiedni predykat wygląda następująco: pisz_liste([]). pisz_liste([x R) :- print([x]), pisz_liste([r]). Ciekawszym przykładem może byd procedura dzieląca listę na dwie części: C1. dziel([ ], [ ], [ ]). C2. dziel([x], [X], [ ]). C3. dziel([x, Y L], [X L1], [Y L2]) :- dziel(l, L1, L2). W przykładzie tym następuje podział zadanej listy na dwie, gdzie jedna z nich zawiera elementy o indeksach parzystych a druga o nieparzystych. Załóżmy, że badaną listą jest : [1,2,3,4,5].?_ dziel([1,2,3,4,5], L1, L2). W przypadku C1 brak jest uzgodnienia ponieważ zadana lista jest niepusta. W przypadku C2 brak jest uzgodnienia ponieważ zadana lista ma więcej niż jeden element. Uzgodnienie z C3 daje następujące przypisanie zmiennych: X = 1, Y = 2, L = 3,4,5. Dodatkowo automatycznie do list wynikowych dołączane SA dwa pierwsze elementy listy zadanej. Następuje ponowne wywołanie procedury: dziel([3,4,5], L1, L2) Ponowne dopasowania dają taki sam rezultat uzgodnienie z C3, zatem następuje przypisanie X = 3, Y = 4 oraz L = 5 oraz dołączenie elementów do list wynikowych. W trzecim kroku uzgodnienie następuje dla C2, ponieważ L jest listą jednoelementową. Daje to pusta funkcję celu i kooczy proces wnioskowania. Istotnym jest fakt, że nie jest już konieczny powrót, ponieważ kolejne etapy wnioskowania automatycznie zapisywały wynik. Przeanalizujmy procedurę zapisaną w pseudokodzie, wykonującą tę samą operację: dziel (char * L, char * L1, char * L2) int k=0; for(i; i < length(l); i++) if(length(l) == 1) L1[0] = L.[0]; else L1[k] = L[i]; L2[k] = L[i++]; k++; Jak widad już tak proste zadanie jak podział listy daje zgoła odmienne pod względem objętości rozwiązania. Reguła zapisana w PROLOGU ogranicza się do trzech linii, procedura zapisana w pseudokodzie rośnie do

rozmiaru kilkunastu. Wynika to głównie z faktu nieprzystosowania języków proceduralnych do obsługi struktur listowych. Żonglowanie indeksami listy jest nie tylko uciążliwe, ale także może łatwo prowadzid do pomyłek. W szczególności różnica ta zauważalna może byd przy wszelkiego rodzaju sortowniach list. NAWROTY Mechanizm nawrotów został zastosowany w poprzednim przykładzie. Opisany teraz on zostanie dokładniej. W ogólności mechanizm nawrotów znajduje zastosowanie w przypadkach, kiedy cel złożony jest z kilku podcelów. W procesie wnioskowania dochodzi wtedy do prób uzgodnienia celu z kolejnymi podcelami. W przypadku braku uzgodnienia następuje nawrót i próba uzgodnienia z kolejnym podcelem. W celu zobrazowania mechanizmu nawrotów przytoczona zostanie reguła dzielenia całkowitego. Pomocniczo użyto reguły plus(x, Y, Z) która przypisuje do Z sumę X i Y. mod(x, Y, X) :- X < Y. mod( X, Y, Z) :- plus(x1, Y, X), mod(x1, Y, Z). Jak widad przy takim zapisie za każdym razem jako pierwsza podejmowana będzie próba uzgodnienia z podcelem pierwszym, sprawdzającym relację między zadanymi X i Y. Tak długo, jak X będzie miało większą wartośd uzgodnienie nie będzie możliwe, następowad będzie nawrót i próba uzgodnienia z podcelem drugim. Tu wartośd pierwszego argumentu wywołania dla procedury mod jest dekrementowana o wartośd Y. W ogólnym przypadku mechanizm podcelów w języku PROLOG odpowiada mechanizmowi pętli if then bądź switch case w językach proceduralnych. Sterowanie nawrotami możliwe jest dzięki operatorowi!, który wymusza nawrót. Poniżej przykład zastosowania wspomnianego operatora procedura swap oraz bubblesort. swap([x, Y R], [Y, X R]) :- X>Y,!. swap([x R1], [X R2]) :- swap(r1, R2). bsort(l, Sorted) :- swap(l, L1),!, bsort(l1, Sorted). bsort(sorted, Sorted). % lista posortowana W ogólności jeśli dwa przystające element listy są ułożone w kolejności malejącej należy zamienid je miejscami i powrócid do sortowania. W zaprezentowanym przypadku istnieje koniecznośd wymuszenia nawrotów ponieważ należy w każdym obiegu sprawdzid wszystkie elementy listy. Dla porównania przykładowa implementacja sortowania bąbelkowego:

int BubbleSort(int num[], int numel) int i, j, grade, moves = 0; for ( i = 0; i < (numel - 1); i++) for(j = 1; j < numel; j++) if (num[j] < num[j-1]) grade = num[j]; num[j] = num[j-1]; num[j-1] = grade; moves++; return moves; Język proceduralny (tutaj C++) zmusza nie tylko do uciążliwego operowania na indeksach listy ale również do stosowania dużej liczby zmiennych pomocniczych, co nie jest konieczne w PROLOGu dzięki mechanizmowi uzgadniania. PROCEDURY NIEDETERMINISTYCZNE Obecnośd procedur niedeterministycznych w PROLOGu jest konsekwencją dopuszczalności wariantowości reguł. W proceduralnych językach programowania nie jest możliwa obecnośd więcej niż jednej procedury o takim samym nagłówku. Przykład procedury PROLOGowej będącej niedeterministyczną znajduje się poniżej: delete(_, [ ], [ ]). delete(a, [A R], R). delete(a, [B R], B W]) :- delete (A, R, W). Tak przedstawiona procedura usuwa wystąpienia element A w zadanej liście. Pierwszy cel określony jest dla listy pustej, drugi dla przypadku, kiedy szykany element jest elementem pierwszym zadanej listy, a ostatni dla pozostałych przypadków. Niedeterminizm przedstawionej procedury polega na tym, że zawarte w podlecach warunki ni wykluczają się, zatem drzewo wnioskowania będzie posiadało rozgałęzienia. W takim przypadku możliwe jest otrzymanie wielu różnych wyników. Dla podanego przykładu w zależności od numeru wyniku będzie to lista pozbawiona iluś pierwszych wystąpieo elementu A. Kolejny przykład generuje nieskooczoną ilośd coraz dłuższych ciągów bitów: bit(0). bit(1).

bits([]). bits([b L]) :- bits(l), bit(b). Dla zapytania?- bits(x) generowane są ciągi bitów, począwszy od pustego. Warunkiem wypisania kolejnego wyniku przez interpreter jest użycie znaku ; każdorazowo po otrzymaniu wyniku. Procedury niedeterministyczne można zamienid na deterministyczne poprzez dodanie warunków wykluczających w podlecach bądź zastosowanie mechanizmu cut przedstawionego wyżej.