Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine porta Logan in un'avventura inedita, violenta e fortemente narrativa, costruita attorno alla sua natura di combattente e al difficile rapporto con il proprio passato. Insomniac Games punta su combattimenti spettacolari, progressione e personalizzazione, inserendo l'azione in un mondo segnato dalla persecuzione dei mutanti. Un viaggio intenso, che alterna mattanza, esplorazione e momenti sorprendentemente emotivi.
DJI Romo 2: tante novità lo rendono un robot completo
DJI Romo 2: tante novità lo rendono un robot completo
Romo 2 è la seconda generazione di robot lavapavimenti di DJI, un modello che si caratterizza per la precisione nel sistema di navigazione e per il funzionamento particolarmente silenzioso. Con le modifiche introdotte in questa seconda versione, e un posizionamento di prezzo più allineato alla concorrenza, rappresenta una valida alternativa sul mercato delle soluzioni di pulizia domestica
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Il primo Sony con retroilluminazione True RGB alla prova del banco di misura e dei contenuti: luminanza enorme, colori accurati in HDR e un antiriflesso molto efficace. I limiti sono due sole HDMI 2.1 e il blooming fuori asse
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 18-12-2012, 17:49   #1
e-commerce84
Senior Member
 
Iscritto dal: Feb 2009
Messaggi: 700
[Prolog] Implementazione della funzione member

Ciao a tutti,
ho da poco iniziato a studiare per un esame che comprende l'uso del Prolog e sono un tantinello disperato con la visione dichiarativa di tale linguaggio.

Un esempio proposto è l'implementazione di una propria funzione member2 che, come la funzione member, restiuisce TRUE se un elemento appartiene alla lista e falso se l'elemento non appartiene alla lista.

Il codice proposto è semplicemente questo:

Codice:
/* FATTO: (CASO BASE) L'elemento X appartiene alla lista se è in testa alla lista */
member2(X, [X|_]).

/* REGOLA: Se non è in testa è nella TAIL */
member2(X,[_|T]):- member2(X,T).
A grandi linee ho capito come funziona questo semplice programmino ma ho dei dubbi...please...se c'è qualcuno che ne sà qualcosa mi aiuti...

Il FATTO rappresenta il CASO BASE DELLA RICORSIONE

Sostanzialmente dicendo:
Codice:
member2(X, [X|_]).
stò dicendo che la proposizione member2 è VERA se l'elemento X unifica con la head della lista nel quale stò cercando l'elemento X cercato.

La REGOLA rappresenta il caso generale in cui l'elemento cercato non è nella HEAD della lista quindi praticamente elimino il primo elemento dalla lista e ricorsivamente guardo se l'elemento X ricercato è nella HEAD della restante parte della lista:

Codice:
member2(X,[_|T]):- member2(X,T).
La cosa che non mi è ben chiara è come funziona esattamente tale operazione...

in pratica penso che nella head della regola member2(X,[_|T]) fà si che X unifica con la variabile anonima _ (che unifica con tutto).

Poi chiama il body della regola member2(X,T)

A questo punto Prolog controlla se c'è un fatto del tipo:
Codice:
member2(X, [X|_]).
con X che è sempre il nostro elemento da cercare ed il secondo membro [X|_] dove X è il primo elemento della TAIL di prima e vede se il fatto è verificato...se è verificato risponde TRUE, altrimenti richiama ricorsivamente

Ci può stare come raggionamento?

La cosa che però mi risulta assolutamente oscusa in questo ragionamento è la seguente: da quello che sò quando ho una regola del tipo:

HEAD :- BODY

significa che stò dicendo: affinchè HEAD sia verificata, deve essere verificata BODY

Ok...in questo caso però (se fosse come dico io) BODY viene verificata DOPO che la HEAD ha tolto il primo elemento dalla lista...come mai?

Grazie mille

Andrea
e-commerce84 è offline   Rispondi citando il messaggio o parte di esso
Old 18-12-2012, 23:10   #2
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da e-commerce84 Guarda i messaggi
member2(X,[_|T]):- member2(X,T).
member2(X, [X|_]).
Il ragionamento e' un po' piu' semplice se vuoi.

Quote:
HEAD :- BODY

significa che stò dicendo: affinchè HEAD sia verificata, deve essere verificata BODY

Ok...in questo caso però (se fosse come dico io) BODY viene verificata DOPO che la HEAD ha tolto il primo elemento dalla lista...come mai?
Head non toglie elementi dalla lista. In prolog gli elementi non vengo mai aggiunti o tolti.
Si tratta solo di unificare (con delle eccezioni se vuoi, ma la regola generale e' quella).
Ti riscrivo il caso generico in forma piu' estesa
Codice:
member2(X,Y):- 
   Y = [_|T],
   member2(X,T).
(Se mi ricordo correttamente la notazione) e' una formulazione assolutamente identica.
E va letta cosi'
"X e' un element di Y se sono verificate le seguenti condizioni:
1 - Y e' una lista, del cui primo elemento non mi frega niente, ma tutto il resto lo chiamo T
2 - X e' un elemento di T"
Come vedi non c'e' alcuna aggiunta o rimozione, si tratta semplicemente di identificare alcune variabili (o parti di), con altre.

Analogamente potresti pensare il caso base come
Codice:
member2(X, Y):-
  Y = [X|_].
Ovvero "X e' un elemento di Y se il primo elemento di Y e' X stesso"
(ancora una volta, spero di ricordarmi correttamente la notazione, ma spero sia comunque chiaro il discorso)
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 19-12-2012, 21:34   #3
e-commerce84
Senior Member
 
Iscritto dal: Feb 2009
Messaggi: 700
Grazie mille per il chiarimento...ho capito cosa intendi dire anche se purtroppo il tuo codice và in errore in SWI Prolog (vedendo il trace mi viene da pensare che ci possa essere qualcosa che non và quando fai l'assegnazione Y = [_|T] ...non sò se si usi il carattere =, io sapevo che per fare le assegnazioni si usa is ma facendo tipo Y is [_|T] [/b] sbrocca comunque DISPERAZIONE Se ti venisse qualche idea...sarebbe molto figo

Già che ci sono ne approfitto un altro po' per vedere se ho capito bene un altro esempio relativo alla concatenazione di 2 stringhe:

E' richiesto che dato: myappend(L1,L2,L3), a fine esecuzione si ha che L1*L2 (L2 concatenato ad L1)

Il codice è il seguente:

Codice:
/* FATTO: CASO BASE: La lista vuota concatenata alla lista L è uguale alla lista L */
myappend([], L, L).

/* REGOLA */

myappend([X|L1], L2, [X|L]) :- myappend(L1,L2,L).
Da quello che ho capito, anche alla luce di quello che mi hai detto te:

FATTO = CASO BASE DELLA RICORSIONE: Corrisponde al caso in cui la prima lista è vuota e la seconda no --> La concatenazione delle due liste sarà sicuramente uguale alla seconda lista L2.

REGOLA = CASO GENERALE:

A questo punto, andandomi a vedere il trace di ciò che avviene nelle variabili mi pare di capire funzioni così (facciamo un esempio su di un caso concreto):

[b]
myappend([a,b], [c,d], L3).
|
|
\/
NON è il caso base, quindi ricado nella regola che consuma un elemento dalla prima lista
|
|
\/
myappend([b], [c, d], L3)
|
|
\/
NON è il caso base, quindi ricado nella regola che consuma un elemento dalla prima lista
myappend([], [c, d], L3)
|
|
\/
Sono nel caso base, applico il caso base myappend([], L, L). Quindi L3 viene UNIFICATA CON [c,d]
|
|
\/
myappend([], [c, d], [c, d])

Una volta che ho raggiunto il caso base torno indietro ricorsivamente ed "applico la HEAD della regola...tornando indietro di uno step avrei:

myappend([b], [c, d], L3) e la HEAD della regola era: myappend([X|L1], L2, [X|L])

quindi il primo parametro è [X|L1] che corrisponde a [b|[]], il terzo invece sarà [X|[c,d]]

Ed io lo interpreto come X = b, prendi b e sbattilo al posto della X nel terzo parametro che diventa così [b,c,d]

Probabilmente continuo a sbagliare modo di pensare e stavo appunto cercando una forma estesa tipo la tua...

Avevo pensato a qualcosa del genere (ma non riuscendo a far girare questi esempi in forma estesa booo):

Codice:
myappend(L1,L2,L3) :-
      Y = [X|L1].
      myappend(Y,L2,L3).
La mia idea sarebbe la seguente chiamo la funzione su L1 ed L2 da concatenare.
Nella prima istruzione estraggo un elemento dalla lista L1 e richiamo la funzione myappend su Y (L1 senza la sua head)...questa cosa viene fatta fintanto che Y non è la lista vuota [], a questo punto si esegue il caso base ed L3 si unifica ad L2 (quindi contiene gli stessi elementi)...ed ora si fà backtracking ma non riesco a capire come vengono messe in testa gli elementi di L1 che sono stati estratti uno ad uno...

Oddio...sono disperato...ma è normale che ragionare in questo modo sia così difficile (eppure in programmazione tipo Java et similia me la cavo benino...)
e-commerce84 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED Sony Bravia 9 II: il True RGB alla prova, dove l...
Geely EX5, un mese al volante: il SUV elettrico cinese che ci ha sorpreso (quasi) senza riserve Geely EX5, un mese al volante: il SUV elettrico ...
Mova Z70 Ultra Roller Complete: motore potente, rullo di lavaggio e l'IA a guidare Mova Z70 Ultra Roller Complete: motore potente, ...
La Serie A con DAZN e Amazon Prime con l...
Giochi Ubisoft su Steam senza Ubisoft Co...
Miami Beach ha autorizzato la maxi opera...
Apple regala un altro anno di funzioni s...
Alla fine è successo davvero: Vol...
Il meglio di Amazon del weekend in uno s...
Speciale TV in offerta su Amazon: Hisens...
Non c'è pace per Trezor: 347.000 e-mail ...
È un portatile Dell e li vale tut...
Apple iPhone 17 Pro Max 256GB a 1.195€ (...
GPT-6 Astra è davvero AGI o non s...
LG OLED G6S 48'' a 845€ e G6 55'' a 1368...
Mantax Otax: il malware Android che crip...
Musk incassa un altro maxi contratto IA:...
Le vendite di EV sono esplose in tutto i...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 17:42.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v