Both sides previous revision
Poprzednia wersja
Nowa wersja
|
Poprzednia wersja
|
pl:prolog:lab_prolog_ansic [2007/11/27 15:39] kosmo |
pl:prolog:lab_prolog_ansic [2007/11/27 16:18] kosmo |
| |
| |
====== Wstęp ====== | |
| |
Prolog można łatwo zintegrować z językiem //ANSI C//. | |
| |
W [[http://www.swi-prolog.org/|SWI]] służy do tego podstawowy [[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreign.html|Foreign Language Interface]] | |
| |
Preliminaria: | |
* znajomość Prologu | |
* znajomość ANSI C | |
| |
====== Cel Lab ====== | |
| |
====== Ćwiczenia ====== | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
===== Etap 1: Podstawy ===== | |
* Uwagi na początek: | |
* Praktycznie wszystkie funkcje interfejsu Prolog <-> C SWI-Prologu zwracają wartość różną od 0 w przypadku powodzenia i zerową w przypadku błędu. | |
* Nawet drobne błędy w użyciu API Prologu mogą zaowocować znaczącą destabilizacją całego programu bądź jego niewytłumaczalmnym działaniem. | |
* Programy w C należy kompilować przy pomocy załączonego pliku {{:pl:prolog:prolog_lab:Makefile-lab-ansic.txt|Makefile}}. Należy go skopiować pod nazwą //Makefile// do katalogu, w którym będą źródła programów tworzonych podczas tego ćwiczenia. Po wydaniu komendy //make// wszystkie pliki *.c zostaną skompilowane i skonsolidowane z Prologiem. | |
| |
* Uruchamianie i zatrzymywanie SWI-Prologu: | |
Interpreter Prologu uruchamia funkcja ''[[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#PL_initialise()|int PL_initialise(int argc, char *argv[])]]'', a zatrzymuje ''[[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#PL_cleanup()|void PL_cleanup(int status)]]''. Wszystkie wywołania Prologu (poza jednym wyjątkiem opisanym w dalszej części ćwiczenia) muszą zawierać się pomiędzy tymi funkcjami. | |
| |
* Uruchamianie konsoli SWI-Prologu: | |
SWI-Prolog udostępnia funcję ''[[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#PL_toplevel()|int PL_toplevel()]]'' umożliwającą uruchomienie standardowej konsoli kompilatora z poziomu programu w C. | |
| |
* **Zadanie**: | |
Należy napisać program w C, który uruchomi konsolę Prologu. | |
| |
| |
| |
| |
===== Etap 2: Ładowanie kodu Prologu i uruchamianie predykatów z poziomu C ===== | |
| |
Komunikacja pomiędzy Prologiem a C odbywa się wewnątrz //ramek//, które określa się za pomocą funkcji ''[[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#PL_open_foreign_frame()|fid_t PL_open_foreign_frame()]]'' oraz ''[[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#PL_close_foreign_frame()|void PL_close_foreign_frame()]]''. | |
Ramki umożliwają cofnięcie zmian w Prologu wprowadzonych przez kod w języku C. Można to zrobić za pomocą wywołań ''[[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#PL_discard_foreign_frame()|void PL_discard_foreign_frame(fid_t id)]]'' oraz ''[[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#PL_rewind_foreign_frame()|void PL_rewind_foreign_frame(fid_t id)]]''. | |
| |
Wewnątrz ramki można wywołać predykat Prologu. Najprościej użyć w tym celu funkcji ''[[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#PL_call()|int PL_call(term_t goal, module_t m)]]''. Uruchamiane wyrażenie możemy stworzyć za pomocą wywyołania ''[[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#PL_chars_to_term()|int PL_chars_to_term(const char *chars, term_t -t)]]'', która skonwertuje string języka C na //term// języka Prolog. Aby konwersja była możliwa, należy wcześniej zallokować termy. Służy do tego między innymi funkcja ''[[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigntypes.html#PL_new_term_ref()|term_t PL_new_term_ref()]]''. | |
| |
* **Zadanie:** | |
Należy napisać program w C, który za pomocą predykatu //[[http://gollem.science.uva.nl/SWI-Prolog/Manual/consulting.html#consult/1|consult/1]]// wczyta program w Prologu, a następnie wykona predykat z załadowanego pliku. | |
| |
| |
| |
===== Etap 3: Predykaty w C ===== | |
Prolog umożliwa implementację predykatów w języku C. W przypadku [[http://www.swi-prolog.org|SWI]] predykat jest funkcją zwracającą wartość ''TRUE'' lub ''FALSE'', przyjmującą argumenty typu ''term_t'' w liczbie równej arności danego predykatu. Przed użyciem argumenty muszą być skonwertowane do typów języka C za pomocą odpowiednich [[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#sec:9.6.3.2|funkcji]]. Możliwa jest także ich [[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#sec:9.6.4|modyfikacja]] oraz [[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#sec:9.6.5|unifikacja]]. | |
| |
Predykaty napisane w języku C przed użyciem muszą zostać zarejestrowane przy pomocy funkcji ''[[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#PL_register_foreign()|int PL_register_foreign(const char *name, int arity, foreign_t (*function)(), int flags)]]'' __przed inicjalizacją Prologu__. Po tej czynności mogą być używane zarówno z poziomu języka C jak i Prologu. | |
| |
* **Zadanie:** | |
Należy napisać w języku C predykat przyjmujący jako argument tekst, który zostanie wypisany na ekranie w ozdobych nawiasach (''-=[ ]=-''), a następnie przetestować jego działanie przy pomocy konsoli Prologu. | |
| |
| |
| |
| |
| |
| |
| |
| |
===== Unix: Polecenia Systemowe ===== | |
[[http://www.swi-prolog.org|SWI-Prolog]] posiada mechanizmy pozwalajace na interację z systemem operacyjnym na którym pracuje. Do najprostrzych należy predykat //[[http://gollem.science.uva.nl/SWI-Prolog/Manual/system.html#shell/1|shell/1]]//, który pozwala na uruchomienie dowolnej aplikacji z poziomu Prologu. | |
Na [[http://www.swi-prolog.org/packages/clib.html#sec:2|głębszą interackcję]] pozwala biblioteka [[http://www.swi-prolog.org/packages/clib.html|SWI-Prolog C-library]]. | |
| |
* **Zadanie:** | |
Należy napisać w Prologu program uruchamiający __jednocześnie__ 4 xtermy. | |
| |
===== Unix: sockety ===== | |
[[http://www.swi-prolog.org/packages/clib.html|pakiet Clib]] | |
| |
| |
| |
| |
====== Źródła ====== | |
| |
* [[http://gollem.science.uva.nl/SWI-Prolog/Manual/Contents.html|Podręcznik SWI]] | |
* [[http://gollem.science.uva.nl/SWI-Prolog/Manual/foreign.html|Foreign Language Interface]] | |
* [[http://www.swi-prolog.org/packages/clib.html|SWI-Prolog C-library]] | |
| |