Dateien und Streams
main :-
tmp_file(prolog, Datei),
setup_call_cleanup(
open(Datei, write, Aus),
( format(Aus, "eins~nzwei~ndrei~n", []), format(Aus, "Zahl: ~d~n", [42]) ),
close(Aus)),
read_file_to_string(Datei, Text, []),
string_length(Text, L), format("~d Zeichen~n", [L]),
read_file_to_string(Datei, T2, []),
split_string(T2, "\n", "", Zeilen), writeln(Zeilen),
setup_call_cleanup(open(Datei, read, In), lies_zeilen(In), close(In)),
delete_file(Datei),
( exists_file(Datei) -> writeln(da) ; writeln(geloescht) ).
lies_zeilen(In) :-
read_line_to_string(In, Z),
( Z == end_of_file -> true ; format("> ~s~n", [Z]), lies_zeilen(In) ).24 Zeichen [eins,zwei,drei,Zahl: 42,] > eins > zwei > drei > Zahl: 42 geloescht
Terme lesen und schreiben
main :-
term_to_atom(T, 'f(X, y, [1,2])'), print(T), nl,
term_to_atom(foo(bar, "text", 1.5), A), writeln(A),
with_output_to(string(S), (write(a), write(' '), print(b))), string_length(S, L), writeln(S-L),
format(atom(F), "~w-~w", [x, y]), writeln(F),
writeq('Hallo Welt'), nl,
print([1, 'A b', "str"]), nl,
write_canonical([a, 'B']), nl,
read_term_from_atom('p(Q)', Term, []), print(Term), nl,
copy_term(f(X1, X1, _), Kopie), print(Kopie), nl,
tab(3), writeln(eingerückt),
( ground(f(a)) -> writeln(grundterm) ; true ),
( X1 = 1, ground(X1) -> writeln(gebunden) ; true ).f(_4978,y,[1,2]) foo(bar,"text",1.5) a b-3 x-y 'Hallo Welt' [1,'A b',"str"] [a,'B'] p(_5128) f(_5144,_5144,_5148) eingerückt grundterm gebunden
Module
Module kapseln Prädikate. module(Name, [Exporte]) definiert, was sichtbar ist:
flaeche(kreis(R), A) :- A is pi * R * R.
flaeche(rechteck(B, H), A) :- A is B * H.
umfang(kreis(R), U) :- U is 2 * pi * R.
umfang(rechteck(B, H), U) :- U is 2 * (B + H).
main :-
flaeche(rechteck(3, 4), A), writeln(A),
flaeche(kreis(1), K), format("~4f~n", [K]),
umfang(rechteck(3, 4), U), writeln(U).12 3.1416 14
Am Anfang einer Moduldatei geometrie.pl steht :- module(geometrie, [flaeche/2, umfang/2]).. In einem Projekt lädst du ein Modul mit :- use_module(geometrie). oder aus der Bibliothek :- use_module(library(lists))..
Tabling: Memoization
Mit :- table merkt sich Prolog Ergebnisse und löst Linksrekursion:
:- table fib/2.
fib(0, 0).
fib(1, 1).
fib(N, F) :- N > 1, A is N - 1, B is N - 2, fib(A, FA), fib(B, FB), F is FA + FB.
:- table pfad/2.
kante(a, b). kante(b, c). kante(c, a). kante(c, d).
pfad(X, Y) :- pfad(X, Z), kante(Z, Y).
pfad(X, Y) :- kante(X, Y).
main :-
fib(100, F), writeln(F),
findall(Y, pfad(a, Y), Ziele), sort(Ziele, Sortiert), writeln(Sortiert).354224848179261915075 [a,b,c,d]
Tests und Ökosystem
:- use_module(library(plunit)).
verdoppeln(X, Y) :- Y is X * 2.
:- begin_tests(arithmetik).
test(verdoppeln) :- verdoppeln(4, 8).
test(verdoppeln_negativ, true(Y == -6)) :- verdoppeln(-3, Y).
test(fehlschlag, fail) :- verdoppeln(1, 3).
:- end_tests(arithmetik).
main :- run_tests, writeln(fertig).fertig
| Werkzeug | Zweck |
|---|---|
swipl | Interpreter und Compiler |
library(clpfd) | Constraint-Lösen über Ganzzahlen |
library(dcg/basics) | Parsen |
library(http) | Webserver und Clients |
library(plunit) | Unit-Tests |
| SWISH (swish.swi-prolog.org) | Prolog im Browser |
| Logtalk | Objektorientierung für Prolog |
| ECLiPSe, GNU Prolog, Scryer | Weitere Implementierungen |
Merke
- Dateien mit
open/3,setup_call_cleanup/3,read_file_to_string/3 - Module (
:- module) kapseln Code,use_moduleimportiert :- tablespeichert Zwischenergebnisse und verhindert Endlosschleifenplunitfür Tests; SWISH zum Ausprobieren im Browser
Aufgabe
Schreibe ein Modul liste_utils mit zweitletztes/2 und teste es mit plunit.