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.
#!/bin/sh swipl -s program.pl -g go -t halt
#!/bin/sh swipl -s $1 -g $2 -t halt
wtedy można go uruchomić poleceniem
./nazwa_skryptu program.pl go
#!/usr/bin/swipl -q -t go -s tresc programu w prologu
chmod u+rx skrypt
Więcej można przeczytać na:
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:
date > dzisiaj.txt
lista-osob.txt
i umieszczenie rezultatu w pliku lista-osob-posortowana
: sort < lista-osob.txt > lista-osob-posortowana.txt
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.
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).
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:
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).
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 &
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.
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?
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ę.
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.
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
Tu studenci mogą wpisywać swoje uwagi.
— Grzegorz J. Nalepa 2009/05/06 09:13