EMZETT.
Login

Kurz: = rechnet nicht. Für Arithmetik benutzt man is:

Teil des Kurses Prolog

Kapitel 2 von 8 im Kurs Prolog. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

is und Auswertung

= rechnet nicht. Für Arithmetik benutzt man is:

main :-
    X is 2 + 3 * 4, writeln(X),
    Y is 7 / 2, writeln(Y),
    Z is 7 // 2, writeln(Z),
    M is 7 mod 3, writeln(M),
    P is 2 ** 10, writeln(P),
    Q is 2 ^ 10, writeln(Q),
    R is sqrt(16), writeln(R),
    A is abs(-5), writeln(A),
    B is max(3, 9), writeln(B),
    C is truncate(3.99), writeln(C),
    D is round(3.5), writeln(D),
    E is pi, format("~4f~n", [E]),
    F is 10 rdiv 4, writeln(F),
    G is atan2(1, 1) * 4, format("~3f~n", [G]).

Ausgabe:

14
3.5
3
1
1024
1024
4.0
5
9
3
4
3.1416
5r2
3.142

Achtung

X = 1 + 2 bindet X an den Term 1+2, ohne zu rechnen. Erst X is 1 + 2 ergibt 3. Rechts von is müssen alle Variablen gebunden sein.

Vergleiche

OperatorBedeutung
=:= , =\=arithmetisch gleich / ungleich
< , > , =< , >=größer/kleiner (Achtung: =<, nicht <=)
== , \==strukturell identisch / nicht identisch
= , \=unifizierbar / nicht unifizierbar
@< , @>Standardordnung der Terme
main :-
    ( 3 =< 3 -> writeln(ja) ; writeln(nein) ),
    ( 1 + 2 =:= 3 -> writeln('=:= ja') ; true ),
    ( a == a -> writeln('== ja') ; true ),
    ( X == Y -> writeln(gleich) ; writeln('verschiedene Variablen') ),
    ( X = Y, X == Y -> writeln('nach Unifikation gleich') ; true ),
    ( abc @< abd -> writeln('abc vor abd') ; true ),
    compare(Ordnung, 3, 5), writeln(Ordnung).

Ausgabe:

ja
=:= ja
== ja
verschiedene Variablen
nach Unifikation gleich
abc vor abd
<

Rekursion mit Arithmetik

Schleifen gibt es nicht; man schreibt Rekursion mit einem Basisfall:

fak(0, 1) :- !.
fak(N, F) :- N > 0, N1 is N - 1, fak(N1, F1), F is N * F1.
 
summe_bis(0, 0) :- !.
summe_bis(N, S) :- N1 is N - 1, summe_bis(N1, S1), S is S1 + N.
 
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.
 
% endrekursiv mit Akkumulator
laenge_akk([], N, N).
laenge_akk([_|T], A, N) :- A1 is A + 1, laenge_akk(T, A1, N).
 
main :-
    fak(10, F), writeln(F),
    summe_bis(100, S), writeln(S),
    fib(15, X), writeln(X),
    laenge_akk([a,b,c,d], 0, L), writeln(L),
    fak(25, G), writeln(G).

Ausgabe:

3628800
5050
610
4
15511210043330985984000000

SWI-Prolog rechnet mit beliebig großen Ganzzahlen: fak(25, G) läuft nicht über.

between, forall und Zählschleifen

main :-
    forall(between(1, 5, I), (write(I), write(' '))), nl,
    findall(Q, (between(1, 6, N), Q is N * N), Quadrate), writeln(Quadrate),
    aggregate_all(count, between(1, 10, _), Anzahl), writeln(Anzahl),
    aggregate_all(sum(N2), between(1, 100, N2), Summe), writeln(Summe),
    aggregate_all(max(N3), member(N3, [3, 9, 4]), Maximum), writeln(Maximum),
    ( between(1, inf, K), K * K > 200 -> writeln(K) ; true ).

Ausgabe:

1 2 3 4 5
[1,4,9,16,25,36]
10
5050
9
15

Merke

  • is rechnet, = unifiziert; =:= vergleicht Werte, == vergleicht Terme
  • Vergleich „kleiner gleich“ schreibt man =<
  • Rekursion mit Basisfall ersetzt Schleifen; between/3 und forall/2 zählen
  • SWI-Prolog hat unbegrenzt große Ganzzahlen

Übungsaufgabe

Schreibe potenz(Basis, Exponent, Ergebnis) rekursiv.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Einführung und erstes Programm

Weiter: Listen und rekursive Strukturen

Alle Kapitel: Prolog im Überblick