Esempio di Programmazione in Lambda Prolog

I seguenti due moduli contengono la definizione di alcune operazioni sugli insiemi, e la definizione di un database di persone e alcune relazioni fra di esse.


%%=============================================================
%% MODULO 1:
%%
%% Operazioni sugli insiemi.

%%=============================================================
%% Un insieme verra' rappresentato tramite una funzione
%% da U (universo) nei booleani (funzione caratteristica).
%% Cioe': X appartiene all'insieme rappresentato da A sse
%% (A X) e' vero.
%%=============================================================

module insiemi.

%% Una possibile definizione di unione ed intersezione:

type unione, intersezione (U -> o) -> (U -> o) -> (U -> o).

%% X appartiene all'unione di A e B se X appartiene ad A o
%% X appartiene a B.
%% Analogamente, X appartiene all'intersezione di A e B se
%% X appartiene ad A e X appartiene a B.

unione A B X :- A X.
unione A B X :- B X.

intersezione A B X :- A X , B X.

%%=============================================================

%% Definizione alternativa di unione ed intersezione:

type union, intersection (U -> o) -> (U -> o) -> (U -> o) -> o.

%% C e' l'unione di A e B se per ogni X, X appartiene a C sse
%% X appartiene ad A o a B (si ricorda che "or" e' il ";")
%% Analogamente, C e' l'intersezione di A e B se per ogni X,
%% X appartiene a C sse X appartiene ad A e a B.

union A B (X\ (A X ; B X)).

intersection A B (X\ (A X , B X)).

%%=============================================================

%% Definizione (intenzionale) di sottoinsieme

type sottoinsieme (U -> o) -> (U -> o) -> o.

%% A e' sottoinsieme di B sse per ogni X, se X appartiene ad A
%% allora X appartiene a B

sottoinsieme A B :- pi X\(A X => B X).

%%=============================================================



%%=============================================================
%% MODULO 2:
%%
%% Database di persone e alcune relazioni.
%%=============================================================

module persone.
accumulate insiemi.

kind persona type.

%% Elenco persone del database

type gino, pippo, luca, gianna, maria, isabella persona.

%% Suddivisione in uomini e donne

type man, woman persona -> o.

man gino.
man pippo.
man luca.

woman gianna.
woman maria.
woman isabella.

%% Relazione "padre", "madre" e "marito"

type father, mother, husband persona -> persona -> o.

father gino pippo.
father pippo luca.

mother gianna pippo.
mother gianna maria.
mother isabella luca.

husband gino gianna.
husband pippo isabella.

%% Relazioni primarie e derivate

type prim_rel, der_rel (persona -> persona -> o) -> o.

prim_rel father.
prim_rel mother.
prim_rel husband.

der_rel R :- prim_rel R1, prim_rel R2, R = X\Y\(sigma Z\ (R1 X Z, R2 Z Y)).

%% Predicati "prete", "monaca" e "ecclesiastico".

type priest, nun, eccles persona -> o.

priest luca.

nun maria.

eccles X :- priest X.
eccles X :- nun X.

%%=============================================================



Esempio di sessione

I precedenti moduli sono stati salvati in un file "esempio.mod"

leo:~> Terzo
loading /home/stud/catuscia/terzo/bin/.lpsml ......................... done
Terzo lambda-Prolog, Version 1.0b, Built Tue Jul 16 15:52:11 EDT 1996
[reading file /home/stud/catuscia/terzo/lib/terzo.rc]
path /home/stud/catuscia/terzo/lib/ .
[reading file /home/stud/catuscia/terzo/lib/list_util.mod]
GC #0.0.0.0.1.1: (0 ms.)
GC #0.0.0.1.2.16: (10 ms.)
module ListUtil
[closed file /home/stud/catuscia/terzo/lib/list_util.mod]
[reading file /home/stud/catuscia/terzo/doc/SystemModules/maps.mod]
module maps
[closed file /home/stud/catuscia/terzo/doc/SystemModules/maps.mod]
[closed file /home/stud/catuscia/terzo/lib/terzo.rc]
Terzo> #load "esempio.mod".
[reading file ./esempio.mod]
module persone
[closed file ./esempio.mod]
Terzo> #query persone.

La prossima query chiede se e' vero che un insieme A e' sempre contenuto nell'unione di A con un altro insieme B
?- pi A\ (pi B\ (sottoinsieme A (unione A B) ) ).

solved

La prossima query chiede se e' vero che i preti sono un sottoinsieme degli ecclesiastici
?- sottoinsieme priest eccles.

solved

La prossima query chiede se e' vero che i preti sono un sottoinsieme degli uomini. La risposta sara' no perche' "sottoinsieme" e' definito intenzionalmente. Ovvero: nonostante che nel presente database sia vero che i preti sono un sottoinsieme degli uomini, cio' non e' una conseguenza logica del database (se aggiungiamo nuovi fatti potrebbe non essere piu' vero).
?- sottoinsieme priest man.

no

La prossima query chiede di trovare tutte le relazioni R e le persone X tali che gino e' legato a X da R, ed R e' una relazione secondaria. La prima risposta e' R="nonno" e X=luca, la seconda risposta e' R="patrigno" e X=pippo, la seconda risposta e' R="patrigno" e X=maria. Notare che i "patrigni", in questa definizione, includono i padri.
?- der_rel R, R gino X.

R = X1\ Y\ sigma Z\ father X1 Z , father Z Y
X = luca ;

R = X2\ Y1\ sigma Z1\ husband X2 Z1 , mother Z1 Y1
X = pippo ;

R = X3\ Y2\ sigma Z2\ husband X3 Z2 , mother Z2 Y2
X = maria ;

no more solutions

La prossima query chiede di trovare tutte le persone Z che sono madri o padri di qualcuno (Is_mother o Is_father, definite nel goal stesso). La quantificazione esistenziale di Is_mother, Is_father permette di "nascondere" la definizione di queste relazioni e quindi di non visualizzarla nella c.a.s.
?- sigma Is_mother\ sigma Is_father\ (
- Is_mother = (X\sigma Y\ mother X Y),
- Is_father = (X\sigma Y\ father X Y),
- unione Is_mother Is_father Z
- ).

Z = gianna ;

Z = gianna ;

Z = isabella ;

Z = gino ;

Z = pippo ;

no more solutions
?- #end.
Terzo> leo:~>