LAB: Integracja z narzędziami systemowymi

6 WPROWADZENIE

6.1 Temat: Uruchamianie programów

Przy pomocy interpretera SWI można uruchomić program w trybie wsadowym (ang. batch).

swipl -s program.pl -g go -t halt

Powyższe wywołanie załaduje podany plik, zada cel go., a po jego zakończeniu cel halt.. Co jest równoważne wywołaniu:

swipl
[program].
go.
halt.

Program można też uruchomić w postaci skryptu.

  • w najprostszym przypadku można stworzyć skrypt Sh, np.:
#!/bin/sh
swipl -s program.pl -g go -t halt
  • lub też
#!/bin/sh
swipl -s $1 -g $2 -t halt

wtedy można go uruchomić poleceniem

./nazwa_skryptu program.pl go
  • ciekawsze jest stworzenie skryptu Prologowego
#!/usr/bin/swipl -q -t go -s
tresc programu w prologu
  • w obu przypadkach aby uruchomić skrypt należy wcześniej nadać mu odpowiednie atrybuty:
chmod u+rx skrypt

Więcej można przeczytać na:

6.2 Temat: Potoki i przekierowanie we/wy

Wstęp

W systemie typu Unix (POSIX) standardowe wejście, wyjście jak i wyjście błędów aplikacji można przekierować do pliku. Do przekierowania standardowego wyjścia należy posłużyć się >, dla standardowego wejścia: <.

Przykładowo:

  • Przekierowanie informacji o aktualnym czasie do pliku: date > dzisiaj.txt
  • Posortowanie zawartości pliku lista-osob.txt i umieszczenie rezultatu w pliku lista-osob-posortowana: sort < lista-osob.txt > lista-osob-posortowana.txt
  • Można również zlecić wykonanie aplikacji współbieżnie (w tle): sort < lista-osob.txt > lista-osob-posortowana.txt &

Standardowe wyjścia aplikacji można również połączyć ze standardowym wejściem innej aplikacji za pomocą potoków (ang. pipe). Typowe użyciem potoków jest np. wyświetlenie (ls) posortowanej (sort) listy plików w aktualnym katalogu z podziałem na strony (less). Standardowe wyjście ls jest przekierowane do standardowego wejścia sort, następnie wyjście sort jest przekierowane na wejście less. Aplikacje uruchamiane w potoku wykonywane są współbieżnie.

ls | sort | less

Więcej informacji w laboratorium z Unixa.

Potoki w Prologu

Do utworzenia potoku w Prologu można wykorzystać predykat open/3, oraz specjalny term pipe/1. W przykładzie poniżej open(pipe(sort)…) uruchamia aplikację systemową sort.

osoba(franek).
osoba(jurek).
osoba(ania).
 
wypisz_osoby(A) :-
        osoba(B),
        write(A, B),
        write(A, '\n'),
        fail.
 
wypisz_posortowane :-
        open(pipe(sort), write, A),
        \+ wypisz_osoby(A),
        close(A).

6.3 Temat: GraphViz i ImageMagick

Graphviz jest aplikacją służącą do wizualizacji grafów. Przetwarza plik wejściowy z symbolicznym tekstowym zapisem węzłów oraz krawędzi i generuje plik wyjściowy w jednym z wybranych formatów: JPG, PNG, EPS, SVG, PDF, PS…

Przykładowy plik wejściowy dla grafu skierowanegoprzyklad.dot:

digraph G {
   "wezel o dlugiej nazwie" -> B
   B -> inny
   inny -> wezelek
   wezelek -> B
   wezelek -> "wezel o dlugiej nazwie"
}

digraph jest słowem kluczowym określającym graf skierowany, G jest nazwą grafu (może to być dowolny ciąg znaków), pomiędzy {} należy umieścić zbiór krawędzi, zapisanych jako:

nazwa1 -> nazwa2

gdzie nazwa1 oraz nazwa2 to nazwy wierzchołków pomiędzy którymi znajduje się krawędź; jeżeli w nazwie wierzchołka znajdują się znaki białe (np. spacje) należy nazwę wierzchołka umieścić w cudzysłowiach np.

"wezel o dlugiej nazwie".

Wywołanie generujące graf jako obrazek PNG (Graphviz generuje graf na standardowym wyjściu):

dot -T png przyklad.dot > przyklad.png

Więcej informacji: man dot

Zamiast zachowywać graf jako obrazek, można go wyświetlić korzystając z aplikacji ImageMagick (display) oraz potoków:

dot -T png przyklad.dot | display

Czego rezultatem będzie okno z grafem:

6.4 Metaprogramowanie i Potoki

Metaprogramowanie można połączyć z możliwościami jakie daje tworzenie potoków do napisania uniwersalnego programu wyświetlającego graf skierowany na podstawie faktów przechowywanych przez wskazany predykat (patrz graph2.pl) będący argumentem wywołania predykatu dotegen/1, np.:

dotgen(mojUlubionyGraf/2).

wygeneruje graf na podstawie krawędzi zdefiniowanych przez dwuargumentowy predykat mojUlubionyGraf. Należy zwrócić uwagę, że dotgen/1 generuje graf pod warunkiem, że wskazany predykat reprezentujący graf ma 2 lub więcej argumentów; założono, że pierwsze dwa argumenty są nazwami wierzchołków tworzących krawędź.

Przykładowe wykorzystanie rysuj.pl:

graf(jeden,dwa).
graf(dwa,trzy).
graf(trzy,jeden).
graf(jeden,cztery).
 
:- [graph2].
rysuj :-
        open(pipe('dot -T png | display'), write, A),
        dotgen(A, graf/2),
        close(A).
 
rysuj_w :-
        open(pipe('dot -T png | display &'), write, A),
        dotgen(A, graf/2),
        close(A).

6.5 Temat: Uruchamianie Prologu w potoku

Program w Prologu można również uruchomić z poziomu systemu operacyjnego w potoku. Np. do wygenerowania grafu może służyć polecenie:

swipl -s rysuj.pl -q -t 'dotgen(graf/2).' | dot -Tpng | display

bądź też współbieżnie:

swipl -s rysuj.pl -q -t 'dotgen(graf/2).' | dot -Tpng | display &

6 ĆWICZENIA

6.1 Ćwiczenie: Tworzenie skryptów

Sprawdź działanie:

swipl -g help
swipl -g help -t halt

Uruchom w podobny sposób program rodzina z 1. zajęć (lub inny). Zadaj z linii poleceń różne pytania, np. „kto jest rodzicem piotra?”.

Uruchom program rodzina jako skrypt Sh, gdzie z linii poleceń można zadać pytanie jako 1. argument skryptu.

Uruchom program rodzina jako skrypt Prolog.

6.2 Ćwiczenie: Tworzenie potoków

Przeanalizuj działanie graph2.pl.

Przetestuj i porównaj działanie predykatów rysuj oraz rysuj_w z rysuj2.pl. Jaka jest różnica? dlaczego?

6.3 Ćwiczenie: Wizualizacja drzewa genealogicznego potomków

Korzystając z predykatów określających koligacje rodzinne z wprowadzenie oraz na podstawie graph2.pl napisz predykat generujący graf będący drzewem genealogicznym określającym potomków wskazanej osoby:

rysuj_potomek(+Kto)

gdzie Kto to osoba, dla której zostanie wygenerowane drzewo potomków, zakładając, że istnieją predykaty: rodzic/2, kobieta/1, mezczyzna/1. Przykładowe wywołanie:

rysuj_potomek(franek).

Wygeneruje drzewo genealogiczne potomków dla osoby franek.

Podpowiedź: najpierw napisz predykat znajdujący potomków, potem dodaj generację danych dla Graphviz, następnie wizualizację.

6.4 Ćwiczenie: Wizualizacja drzewa genealogicznego potomków, metaprogramowanie

Korzystając z predykatów określających koligacje rodzinne z laboratorium wprowadzenie oraz na podstawie graph.pl napisz predykat generujący graf będący drzewem genealogicznym określającym potomków wskazanej osoby:

rysuj_potomek(+Kto,+Rodzic,+Kobieta,+Mezczyzna)

gdzie Kto to osoba, dla której zostanie wygenerowane drzewo potomków, pozostałe argumenty są nazwami predykatów określającymi odpowiednio kto jest czyim rodzicem, kto jest kobietą, kto jest mężczyzną. Przykładowe wywołanie:

rysuj_potomek(franek,rodzic/2,kobieta/1,mezczyzna/1)

Wygeneruje drzewo genealogiczne potomków dla osoby franek, przy czym rodzic/2, kobieta/1, mezczyzna/1 są zdefiniowanymi predykatami, których klauzule przechowują informacje o koligacjach rodzinnych.

Podpowiedź: najpierw napisz predykat znajdujący potomków, potem dodaj generację danych dla Graphviz, następnie wizualizację.

Uwaga: Można pokolorować krawędzie i węzły grafu, zadając:

digraph G {
  "ala" [style=filled, fillcolor=yellow]
  "ala" ->"ma" [color=blue]
  "kota"->"ma" [color=red]
  "ma" -> "w ciapki"
}

Pokoloruj innymi kolorami węzły związane z kobietami i mężczyznami.

Dla Zainteresowanych

Ćwiczenie: Wizualizacja drzewa genealogicznego

Napisz predykat:

rysuj_drzewo(+Kto,+Rodzic,+Kobieta,+Meżczyzna)

rysujący kompletne drzewo dla wskazanej osoby; zarówno potomków jak i przodków.

Przykład drzewa genealogicznego: drzewo_gen_przyklad.dot

Uwagi, komentarze, propozycje

Tu studenci mogą wpisywać swoje uwagi.

Grzegorz J. Nalepa 2009/05/06 09:13

pl/prolog/prolog_lab/prolog_lab_system.txt · ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0