Both sides previous revision
Poprzednia wersja
Nowa wersja
|
Poprzednia wersja
|
pl:prolog:prolog_lab:prolog_lab_system [2008/11/03 09:22] root Document moved from pl:prolog:prolog_lab:prolog_lab_7 |
pl:prolog:prolog_lab:prolog_lab_system [2019/06/27 15:50] (aktualna) |
====== 7 LAB: Integracja z narzędziami systemowymi ====== | ====== LAB: Integracja z narzędziami systemowymi ====== |
| {{header>2}} |
| ===== - #6 WPROWADZENIE ===== |
| ==== - Temat: Uruchamianie programów ==== |
| |
===== WPROWADZENIE ===== | Przy pomocy interpretera SWI można uruchomić program w trybie wsadowym (ang. //batch//). |
| |
==== Temat: Potoki i przekierowanie we/wy ==== | swipl -s program.pl -g go -t halt |
| |
Standardowe wejście jak i wyjście aplikacji można przekierować do pliku. | Powyższe wywołanie załaduje podany plik, zada cel ''go.'', a po jego zakończeniu cel ''halt.''. |
Do przekierowania standardowego wyjścia należy posłużyć się >, dla standardowego wejścia: <. | Co jest równoważne wywołaniu: |
Przykładowo: | swipl |
| [program]. |
| go. |
| halt. |
| |
Przekierowanie informacji o aktualnym czasie do pliku: | Program można też uruchomić w postaci skryptu. |
date > dzisiaj.txt | * w najprostszym przypadku można stworzyć skrypt //Sh//, np.: |
| |
Posortowanie zawartości pliku ''lista-osob.txt'' i umieszczenie rezultatu w pliku ''lista-osob-posortowana'': | #!/bin/sh |
sort < lista-osob.txt > lista-osob-posortowana.txt | swipl -s program.pl -g go -t halt |
| |
Można również zlecić wykonanie aplikacji współbieżnie (w tle): | * lub też |
sort < lista-osob.txt > lista-osob-posortowana.txt & | |
| |
| #!/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: |
| * [[http://www.swi-prolog.org/pldoc/doc_for?object=section%282%2c%20%272.3%27%2c%20swi%28%27%2fdoc%2fManual%2finitgoal.html%27%29%29|Initialisation files and goals]] |
| * [[http://www.swi-prolog.org/pldoc/doc_for?object=section%282%2c%20%272.10%27%2c%20swi%28%27%2fdoc%2fManual%2fcompilation.html%27%29%29|Compilation]] |
| * [[http://www.swi-prolog.org/pldoc/doc_for?object=section%281%2c%20%2710%27%2c%20swi%28%27%2fdoc%2fManual%2fruntime.html%27%29%29|Generating Runtime Applications]] |
| |
| ==== - 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). | 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). | 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''. | 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. | Aplikacje uruchamiane w potoku wykonywane są współbieżnie. |
ls | sort | less | ls | sort | less |
| |
==== Temat: Potoki w Prologu ==== | Więcej informacji w [[http://home.agh.edu.pl/~gjn/wiki/dydaktyka:unix:lab_zadania_i_procesy|laboratorium z Unixa]]. |
| |
Do utworzenia potoku można wykorzystać predykaty tell/1, told/0, oraz pipe/1. | |
pipe/1 tworzy potok, przekierowuje standardowe wyjście do wskazanej aplikacji lub potoku. | === Potoki w Prologu === |
W przykładzie poniżej pipe/1 uruchamia aplikację systemową ''sort''. | |
| Do utworzenia potoku w Prologu można wykorzystać predykat ''open/3'', [[http://gollem.science.uva.nl/SWI-Prolog/Manual/IO.html#sec:edinburghIO|oraz specjalny term pipe/1]]. |
| W przykładzie poniżej ''open(pipe(sort)...)'' uruchamia aplikację systemową ''sort''. |
| |
<code prolog> | <code prolog> |
| |
osoba(franek). | osoba(franek). |
osoba(jurek). | osoba(jurek). |
osoba(ania). | osoba(ania). |
| |
wypisz_osoby :- | wypisz_osoby(A) :- |
osoba(X), write(X), nl, fail. | osoba(B), |
wypisz_osoby. | write(A, B), |
| write(A, '\n'), |
| fail. |
| |
wypisz_posortowane :- | wypisz_posortowane :- |
tell(pipe(sort)), | open(pipe(sort), write, A), |
wypisz_osoby, | \+ wypisz_osoby(A), |
told. | close(A). |
</code> | </code> |
| |
| ==== - Temat: GraphViz i ImageMagick ==== |
| |
==== Temat: GraphViz i ImageMagick ==== | |
| |
[[:graphviz]] jest aplikacją służącą do wizualizacji grafów. | [[misc: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... | 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... |
| |
</code> | </code> |
| |
Wywołanie generujące graf jako obrazek PNG ([[:graphviz]] generuje graf na standardowym wyjściu): | ''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 ([[misc:Graphviz]] generuje graf na standardowym wyjściu): |
dot -T png przyklad.dot > przyklad.png | dot -T png przyklad.dot > przyklad.png |
| |
{{:pl:prolog:prolog_lab:przyklad.png}} | {{:pl:prolog:prolog_lab:przyklad.png}} |
| |
==== Metaprogramowanie i Potoki ==== | ==== - 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: {{:pl:prolog:prolog_lab:graph.pl}}. | 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 {{:pl:prolog:prolog_lab:graph2.pl}}) będący argumentem wywołania predykatu ''dotegen/1'', np.: |
Przykładowe wykorzystanie {{:pl:prolog:prolog_lab:rysuj.pl}}: | |
| 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//: |
| |
<code prolog> | <code prolog> |
graf(jeden,cztery). | graf(jeden,cztery). |
| |
:- [graph]. | :- [graph2]. |
| rysuj :- |
rysuj :- | open(pipe('dot -T png | display'), write, A), |
tell(pipe('dot -T png | display')), | dotgen(A, graf/2), |
dotgen(graf/2), | close(A). |
told. | |
| |
rysuj_w :- | rysuj_w :- |
tell(pipe('dot -T png | display &')), | open(pipe('dot -T png | display &'), write, A), |
dotgen(graf/2), | dotgen(A, graf/2), |
told. | close(A). |
</code> | </code> |
| |
==== Temat: Uruchamianie Prologu w potoku ==== | ==== - Temat: Uruchamianie Prologu w potoku ==== |
| |
Program w Prologu można również uruchomić z poziomu systemu operacyjnego 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: | Np. do wygenerowania grafu może służyć polecenie: |
| |
swipl -f rysuj.pl -q -t 'dotgen(graf/2).' | dot -Tpng | display | swipl -s rysuj.pl -q -t 'dotgen(graf/2).' | dot -Tpng | display |
| |
bądź też współbieżnie: | bądź też współbieżnie: |
| |
swipl -f rysuj.pl -q -t 'dotgen(graf/2).' | dot -Tpng | display & | swipl -s rysuj.pl -q -t 'dotgen(graf/2).' | dot -Tpng | display & |
| |
| |
===== ĆWICZENIA ===== | |
| |
==== 7.1 Ćwiczenie: Tworzenie potoków ==== | ===== - #6 ĆWICZENIA ===== |
| |
Przeanalizuj działanie {{graph.pl}}. | ==== - Ćwiczenie: Tworzenie skryptów ==== |
| |
Przetestuj i porównaj działanie predykatów ''rysuj'' oraz ''rysuj_w'' z {{rysuj.pl}}. | 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. |
| |
| ==== - Ć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? | Jaka jest różnica? dlaczego? |
| |
==== 7.2 Ćwiczenie: Wizualizacja drzewa genealogicznego potomków ==== | |
| |
Korzystając z predykatów określających koligacje rodzinne z [[prolog_lab_1]] oraz na podstawie {{graph.pl}} napisz predykat generujący graf będący drzewem genealogicznym określającym potomków wskazanej osoby: | ==== - Ćwiczenie: Wizualizacja drzewa genealogicznego potomków ==== |
| |
| Korzystając z predykatów określających koligacje rodzinne z [[pl:prolog:prolog_lab: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 [[misc:Graphviz]], następnie wizualizację. |
| |
| ==== - Ć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) | rysuj_potomek(+Kto,+Rodzic,+Kobieta,+Mezczyzna) |
rysuj_potomek(franek,rodzic/2,kobieta/1,mezczyzna/1) | 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ą zdefinowanymi predykatami, których klauzule przechowują informacje o koligacjach rodzinnych. | 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ę. | Podpowiedź: najpierw napisz predykat znajdujący potomków, potem dodaj generację danych dla [[misc:Graphviz]], następnie wizualizację. |
| |
==== 7.3 Ćwiczenie: Wizualizacja drzewa genealogicznego ==== | 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: | Napisz predykat: |
rysuj_drzewo(+Kto,+Rodzic,+Kobieta,+Meżczyzna) | rysuj_drzewo(+Kto,+Rodzic,+Kobieta,+Meżczyzna) |
| |
rysujący kompletne drzewo dla wskazanej osoby. | rysujący kompletne drzewo dla wskazanej osoby; zarówno potomków jak i przodków. |
| |
Przykład drzewa genealogicznego: | Przykład drzewa genealogicznego: |
| |
{{:pl:prolog:prolog_lab:drzewo_gen_przyklad.png}} | {{:pl:prolog:prolog_lab:drzewo_gen_przyklad.png}} |
| |
| ====== Uwagi, komentarze, propozycje ====== |
| Tu studenci mogą wpisywać swoje uwagi. |
| |
| |
| |
| --- //[[gjn@agh.edu.pl|Grzegorz J. Nalepa]] 2009/05/06 09:13// |
| |