/* Nota: per eseguire il codice occorre prima salvarlo come file di testo (ad esempio come limericks.pl), poi lanciare l'interprete SWI Prolog, infine caricare il sorgente scrivendo: consult(limericks). Anche questa versione è basata sul testo a buchi. Se si propone il goal "limerick." scrive un possibile limerick casuale; per vederne un'altro, premere TAB. */ % Copyright Stefano Penge 2017 % added random Andrea Sterbini 2019 % Released under GPL v.3.0 :- use_module(library(random)). /* Vocabolario */ personaggio(signore). % person personaggio(elefante). personaggio(chirurgo). aggettivo("molto piccolo"). % adjective aggettivo("molto allegro"). aggettivo(allampanato). provenienza(como). % from_place provenienza(alghero). provenienza(milano). tempo('una volta'). % time tempo('un giorno'). tempo('tutti i mesi'). desiderio('salì'). % desire desiderio('si addormentò'). desiderio('giocava a tressette'). luogo('in cima al duomo'). % somewhere luogo('sotto un pero'). luogo('sul divano'). evento('ma quando fu sulla cima'). % something appened evento('ma passate tre ore'). evento('ma mangiando le carte'). risultato('era alto come prima'). % results risultato('gli venne il mal di cuore'). risultato('rimase in disparte'). commento('micropiccolo'). % final adjective commento('assonnato'). commento('affamato'). /* Grammatica */ verso1(Verso, Personaggio, Provenienza):- a_caso(personaggio(Personaggio)), a_caso(aggettivo(Aggettivo)), a_caso(provenienza(Provenienza)), atomic_list_concat(["Un",Personaggio, Aggettivo, "di",Provenienza]," ",Verso). verso2(Verso):- a_caso(tempo(Tempo)), a_caso(desiderio(Desiderio)), a_caso(luogo(Luogo)), atomic_list_concat([Tempo, Desiderio, Luogo]," ",Verso). verso3(Verso):- a_caso(evento(Evento)), atomic_list_concat([Evento],Verso). verso4(Verso):- a_caso(risultato(Risultato)), atomic_list_concat([Risultato],Verso). verso5(Verso, Personaggio, Provenienza):- a_caso(commento(Commento)), atomic_list_concat(["quel",Commento, Personaggio, "di",Provenienza]," ",Verso). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% limerick:- repeat, verso1(Verso1, Personaggio, Provenienza), % verso1 chooses a Person and Place verso2(Verso2), verso3(Verso3), verso4(Verso4), verso5(Verso5, Personaggio, Provenienza), % that are used in verso5 ListaVersi = [Verso1, Verso2,Verso3,Verso4,Verso5], atomic_list_concat(ListaVersi, "\n", Frase), writeln(Frase). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Utility: extract a random fact from the database (SWI-Prolog specific) a_caso(Fact) :- Fact =.. [PredName, _], % retrieve predicate functor (name) Pred =.. [PredName, _], % clone it with empty variables predicate_property(Pred, number_of_clauses(N)), % find how many match random_between(1, N, Nth), % clauses start counting from 1, choose a random index nth_clause(Pred, Nth, ClauseRef), % get the Nth clause clause(Fact,true,ClauseRef). % facts have Body=true, retrieve the head and unify with original Fact %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%