Paradygmaty programowania/Ćwiczenia 13: Programowanie w logice w Prologu I: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Linia 13: Linia 13:
 
Napisać program obliczający największy wspólny dzielnik dwóch dodatnich liczb całkowitych za pomocą algorytmu Euklidesa z odejmowaniem. Chodzi o taki algorytm:
 
Napisać program obliczający największy wspólny dzielnik dwóch dodatnich liczb całkowitych za pomocą algorytmu Euklidesa z odejmowaniem. Chodzi o taki algorytm:
  
   '''function''' ''nww(x, y)''
+
   '''function''' nww(x, y)
     '''while''' ''x ≠ y'' '''do'''
+
     '''while''' x ≠ y '''do'''
       '''if''' ''x > y'' '''then''' ''x := x – y''
+
       '''if''' x > y '''then''' x := x – y
       '''else''' ''y := y – x''
+
       '''else''' y := y – x
     '''return''' ''x''
+
     '''return''' x
  
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">'''Wskazówka:''' <div class="mw-collapsible-content" style="display:none"> Trudność tego zadania zasadza się na konieczności rozpatrzenia dwóch przypadków (x < y oraz x > y), czego w dotychczasowych wykładach poświęconych Prologowi nie omawialiśmy. Rzecz jest jednak prosta — piszemy dwie klauzule, każda dotycząca jednego przypadku (plus pierwsza „brzegowa”, obsługująca przypadek równych argumentów). Uzgodnienie powiedzie się w tylko jednej z nich. Program może więc wyglądać tak:
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">'''Wskazówka:''' <div class="mw-collapsible-content" style="display:none"> Trudność tego zadania zasadza się na konieczności rozpatrzenia dwóch przypadków (x < y oraz x > y), czego w dotychczasowych wykładach poświęconych Prologowi nie omawialiśmy. Rzecz jest jednak prosta — piszemy dwie klauzule, każda dotycząca jednego przypadku (plus pierwsza „brzegowa”, obsługująca przypadek równych argumentów). Uzgodnienie powiedzie się w tylko jednej z nich. Program może więc wyglądać tak:
  
   ''nww(X, X, X) :- X > 0.
+
   nww(X, X, X) :- X > 0.
 
   nww(X, Y, Z) :- X > Y, Y > 0, W is X - Y, nww(Y, W, Z).
 
   nww(X, Y, Z) :- X > Y, Y > 0, W is X - Y, nww(Y, W, Z).
   nww(X, Y, Z) :- X < Y, X > 0, W is Y - X, nww(X, W, Z).''
+
   nww(X, Y, Z) :- X < Y, X > 0, W is Y - X, nww(X, W, Z).
  
 
</div></div>
 
</div></div>
 +
 
===Zadanie 3===
 
===Zadanie 3===
 
Program z poprzedniego zadania można zastosować do wyliczenia największego wspólnego dzielnika dwóch liczb lub do sprawdzenia, że dzielnik równa się pewnej liczbie. Co się jednak stanie, jeśli wpiszemy cel postaci nww(X, 28, 4)?
 
Program z poprzedniego zadania można zastosować do wyliczenia największego wspólnego dzielnika dwóch liczb lub do sprawdzenia, że dzielnik równa się pewnej liczbie. Co się jednak stanie, jeśli wpiszemy cel postaci nww(X, 28, 4)?

Wersja z 19:59, 25 wrz 2006

Zadanie 1

Rozważmy program prologowy:

 p(X, Y, Y) :- X =< Y.
 p(X, Y, Z) :- X < Z, W is Z − 1, p(X, Y, W).

Co zostanie wypisane po wpisaniu celu p(5, X, 15)?

Wskazówka:

Zadanie 2*

Napisać program obliczający największy wspólny dzielnik dwóch dodatnich liczb całkowitych za pomocą algorytmu Euklidesa z odejmowaniem. Chodzi o taki algorytm:

 function nww(x, y)
   while x ≠ y do
     if x > y then x := x – y
     else y := y – x
   return x
Wskazówka:

Zadanie 3

Program z poprzedniego zadania można zastosować do wyliczenia największego wspólnego dzielnika dwóch liczb lub do sprawdzenia, że dzielnik równa się pewnej liczbie. Co się jednak stanie, jeśli wpiszemy cel postaci nww(X, 28, 4)?

Wskazówka:

Zadanie 4

Załóżmy, że mamy dwie relacje, P oraz Q, wyrażone dwuargumentowymi funktorami p i q. Jak zdefiniować relację R będącą złożeniem relacji P i Q? Chodzi o relację R taką, że xRy wtw xPz i zQy dla pewnego z.

Wskazówka:

Zadanie 5

Mamy relacje P i Q jak w poprzednim zadaniu. Jak zdefiniować ich przecięcie, czyli relację R taką, że xRy wtw xPy i xQy?

Wskazówka:

Zadanie 6

Tym razem mamy jedną relację dwuargumentową P. Jak zdefiniować jej domknięcie zwrotne i przechodnie, czyli relację R taką, że xRy wtw dla pewnych gdzie i .

Wskazówka:

Zadanie 7*

Fabryka produkuje kilka różnych produktów, nazwijmy je p1, p2 i p3. Produkty są produkowane ze składników, które nazwijmy s1, s2, s3 i s4. Zbudować prologową bazę danych, która będzie przechowywała następujące informacje:

  • Opis każdego produktu, wyszczególniający które składniki są potrzebne do jego produkcji (na ogół produkt nie wymaga użycia wszystkich składników).
  • Spis dostępnych w tej chwili składników.

Następnie zdefiniować dwie relacje:

  • możnaprodukować(X) — stwierdzająca, że fabryka posiada wszystkie składniki potrzebne do wyprodukowania produktu X.
  • potrzebuje(X, Y) — stwierdzająca, że produkt X potrzebuje składnika Y.

Całość należy zaprogramować nie używając bezpośrednio list (w tym sęk...).

Wskazówka:

Zadanie 8

Przyjrzyj się funktorowi należy z rozwiązania poprzedniego zadania. Zaobserwuj, co się dzieje, gdy użyjemy go z konkretnym pierwszym argumentem i zmienną w miejscu drugiego, np. należy(abc, X).

Wskazówka: