lunghezza([],0).
lunghezza([T|C],N):-lunghezza(C,M),
N is M+1.
/* Somma degli elementi positivi di una lista */
somma_pos([],0).
somma_pos([T|C],S):-somma_pos(C,Q),
comp1(T,Q,S).
comp1(T,Q,S):- T>0,
S is Q+T.
comp1(T,Q,S):- T=<0,
S is Q.
/* oppure: comp1(T,Q,Q):-T=<0. */
/* Eliminazione Elementi Ripetuti di una lista */
elimina_rip([],[]).
elimina_rip([T|C],L):- elimina_rip(C,L1),
comp3(T,L1,L).
comp3(T,L1,[T|L1]):- not member(T,L1).
comp3(T,L1,L1):- member(T,L1).
/* UNIONE DI DUE INSIEMI (con il member):
union(insieme1,insieme2,insieme_unione) */
union(A,[],A). /* passo base */
union([],A,A):-!. /* caso particolare */
union(A,[T|C],Q):-union(A,C,K),
u(T,K,Q).
u(T,K,[T|K]):-not member(T,K).
u(T,K,K):-member(T,K).
/* Unione di due insiemi: METODO PROCEDURALE */
unione(E1,E2,L):- uni(E1,E2,L,E1).
uni(E1,[],L,L).
uni([],E2,E2,_):-!. /* caso particolare */
uni(E1,[T|C],L,P):- member(T,P),
uni(E1,C,L,P).
uni(E1,[T|C],L,P):-not member(T,P),
uni(E1,C,L,[T|P]).
/* ANCOR MEGLIO:
il primo argomento di uni e' inutile, quindi si puo' togliere,
di conseguenza bisogna spostare il caso particolare */
unione2([],E2,E2):-!. /* caso particolare */
unione2(E1,E2,L):- uni2(E2,L,E1).
uni2([],L,L).
uni2([T|C],L,P):- member(T,P),
uni2(C,L,P).
uni2([T|C],L,P):-not member(T,P),
uni2(C,L,[T|P]).
/* LA PRIMA LISTA E' PREFISSO DELLA SECONDA? */
prefix([],_).
prefix([T|C],[T|K]):-prefix(C,K).
/* LA PRIMA LISTA E' SUFFISSO DELLA SECONDA? */
suffix(A,A).
suffix(L,[T|C]):-suffix(L,C).
/* INTERSEZIONE DI DUE INSIEMI */
intersezione(A,[],[]). /* passo base */
intersezione([],A,[]). /* caso particolare */
intersezione([T|C],A,Q):-intersezione(C,A,K),
i(T,A,K,Q).
i(T,A,K,K):-not member(T,A).
i(T,A,K,[T|K]):-member(T,A).
/* Intersezione di due insiemi: METODO PROCEDURALE */
intersezione2(E1,[],[]):-!. /* caso particolare */
intersezione2(E1,E2,L):- inters(E1,E2,L,[]).
inters([],_,L,L).
inters([T|C],E2,L,P):- member(T,E2),
inters(C,E2,L,[T|P]).
inters([T|C],E2,L,P):- not member(T,E2),
inters(C,E2,L,P).
/* Differenza di due insiemi */
differenza(X,[],X):-!.
differenza(X,Y,Z):-diff(X,Y,Z,[]).
diff([],Y,Z,Z).
diff([T|C],Y,Z,P):- not member(T,Y),
diff(C,Y,Z,[T|P]).
diff([T|C],Y,Z,P):- member(T,Y),
diff(C,Y,Z,P).
/* ORDINAMENTI */
/* Date due liste ordinate (istanziate) produce una
lista ordinata che contiene gli elementi di
entrambe. */
merge([],[],[]):-!. /* serve per evitare il risoddisfacimento
in caso di due liste uguali */
merge([],Lista2,Lista2).
vv
merge(Lista1,[],Lista1).
merge([T1|C1],[T2|C2],[T1,T2|C]):- T1=T2,
merge(C1,C2,C).
merge([T1|C1],[T2|C2],[T1|C]):- T1T2,
merge([T1|C1],C2,C).
/* ORDINAMENTO DI UNA LISTA
(il termine sort esiste gia' di sistema) */
/* insort funziona per liste di numeri */
insort([],[]).
insort([T|C],L):-insort(C,K),
insert_ord(T,K,L).
insert_ord(A,[],[A]).
insert_ord(A,[T|C],[A,T|C]):-A=T,
insert_ord(A,C,Q).
/* APPEND
(alias giustapposizione di due liste) */
/* il minimo indispensabile */
append([],L,L).
append([T|C],L,[T|K]):-append(C,L,K).
/* OSSERVAZIONE: alla domanda ?-append(X,Y,[1,2,3]).
risponde dando tutti i modi possibili
di creare [1,2,3] giustapponendo due liste */
/* ALTERNATIVA_1: aggiunta del caso particolare */
append1([],L,L). /* passo base */
append1(L,[],L). /* caso particolare */
append1([T|C],L,[T|K]):-not eq(L,[]),
append1(C,L,K).
/* OSSEVAZIONE: si ottengono risposte diverse da quelle di append solo
alle domande di tipo ?-append1(X,Y,[1,2,3]).
?-append2(X,Y.[1,2,3]).
e a quelle di tipo ?-append1(X,Y,Z).
?-append2(X,Y,Z). */
/* ALTERNATIVA_2: caso particolare con ! e senza il not eq */
append2([],L,L). /* passo base */
append2(L,[],L):-!. /* caso particolare */
append2([T|C],L2,[T|K]):-append(C,L2,K).
/* INVERSIONE DEGLI ELEMENTI DI UNA LISTA */
/* reverse_append inverte gli elementi di una lista utilizzando
il predicato append */
df:-radice(X),
visita_df(X).
radice(X):-arco(X,_),
not arco(_,X),!.
/* tab(num) provoca la scrittura di tanti caratteri blank
quanti son indicati da num */
/* PROGRAMMA: ( Prima Versione )
via1(X,Y). stampa le foglie dell'albero tali che
il peso totale del cammino dalla radice a quelle
foglie e' compreso tra i numeri X e Y dati
dall'utente */
/* PROGRAMMA: ( Seconda Versione )
esercizio1(L,X,Y). stampa le foglie dell'albero tali
che il peso totale del cammino dalla radice a quelle
foglie e' compreso tra i numeri X e Y dati
dall'utente */
/* PROGRAMMA:
via2(X,Y). stampa la prima foglia tale che il
totale del cammino dalla radice a quella foglia
e' compreso tra i numeri X e Y dati dall'utente */
via2(X,Y):-foglie(L),
esercizio2(L,1,Test,X,Y).
esercizio2([T|C],1,Test,X,Y):-radice(A),
contapeso(A,T,Peso),
azione2(T,Peso,X,Y,Test),
esercizio2(C,Test,Test2,X,Y).
esercizio2([],_,_,_,_):-write('Non è stata trovata alcuna foglia'),
write(' soddisfacente la relazione.').
esercizio2(_,0,_,_,_).
azione2(T,Peso,X,Y,Test):-compreso(Peso,X,Y),
write('La prima foglia che soddisfa la relazione è:'),
tab(1),
write(T),write('.'),
Test=0.
azione2(T,P,X,Y,_):-not compreso(P,X,Y).
/* PROGRAMMA:
via3_4. restituisce il cammino radice-foglia di
costo minimo e quello di costo massimo */
via3_4:-radice(A),
foglie(L),
esercizio3(A,L).
esercizio3(A,[T|C]):-camm3(A,T,Peso,L,[T]),
mincamm3(A,C,Peso,L,Pmin,Lmin),
azione3(Lmin),
maxcamm3(A,C,Peso,L,Pmax,Lmax),
azione4(Lmax).
camm3(A,A,0,L,L).
camm3(A,T,Peso,L,K):-arco(B,T,P),
camm3(A,B,P1,L,[B|K]),
Peso is P1+P.
mincamm3(_,[],P,L,P,L).
mincamm3(A,[T|C],P1,L1,Pmin,Lmin):-camm3(A,T,P2,L2,[T]),
confronto3(P1,L1,P2,L2,P3,L3),
mincamm3(A,C,P3,L3,Pmin,Lmin).
maxcamm3(_,[],P,L,P,L).
maxcamm3(A,[T|C],P1,L1,Pmax,Lmax):-camm3(A,T,P2,L2,[T]),
confronto4(P1,L1,P2,L2,P4,L4),
maxcamm3(A,C,P4,L4,Pmax,Lmax).
confronto3(P1,L1,P2,L2,P1,L1):-P1 =< P2.
confronto3(P1,L1,P2,L2,P2,L2):-P1 > P2.
confronto4(P1,L1,P2,L2,P1,L1):-P1 >= P2.
confronto4(P1,L1,P2,L2,P2,L2):-P1 < P2.
azione3(L):-write('Il cammino radice-foglia di peso minimo è:'),
tab(1),
write(L),
nl.
azione4(L):-write('Il cammino radice-foglia di peso massimo è:'),
tab(1),
write(L).
/* cercanodi(L). stampa la lista dei nodi di un grafo
ordinato ciclico */
nodi:-radice(A),
cercanodi(L),
write([A|L]).
cercanodi(L):-findall(B,arco(A,B,_),K),
eliminarip(K,L,[]).
eliminarip([],L,L).
eliminarip([T|C],L,P):- member(T,C),
eliminarip(C,L,P).
eliminarip([T|C],L,P):- not member(T,C),
eliminarip(C,L,[T|P]).
member(T,[T|_]).
member(T,[_|C]):-member(T,C).
/* PROGRAMMA:
via5. stampa l'arco per il quale risulta massima
la somma dei tre numeri seguenti:
- PESO DELL'ARCO,
- PESO DEL NODO-PADRE,
- PESO DEL NODO-FIGLIO. */
/* ESERCIZIO D'ESAME:
Trattare una lista come fosse un vettore, cioe' data una lista e un
indice i oppurtuno, il programma restituisce l'i-esimo elemento
della lista */
es(Num,[T|C],_):- Num=<0,
nl,
tab(10),
write('INDICE SCORRETTO !!!').
es(_,[],_):- nl,
write('Il vettore e'' vuoto.'),
nl,
write('Qualsiasi sia l''indice che '),
write('hai messo, e'' sicuramente scorretto !').
es(Num,[T|C],_):- cardinalita([T|C],N),
Num>N,
nl,
tab(10),
write(' INDICE TROPPO GRANDE !').
es(Num,L,Elem):- esercizio(Num,L,1,Elem).
esercizio(Num,[T|C],Cont,T):- Cont=Num.
esercizio(Num,[T|C],Cont,Elem):- Cont<Num,
J is Cont+1,
esercizio(Num,C,J,Elem).
cardinalita([],0).
cardinalita([T|C],N):- cardinalita(C,M),
N is M+1.