/* 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 % added gender agreement Andrea Sterbini 2022 % Released under GPL v.3.0 :- use_module(library(random)). /* Vocabolario */ personaggio(signore, m). % person personaggio(elefante, m). personaggio(elefantessa, f). personaggio(chirurgo, _). articolo('Un', m). % article articolo('Una', f). aggettivo("molto piccolo", m). % adjective aggettivo("molto allegro", m). aggettivo(allampanato, m). aggettivo("molto piccola", f). % adjective aggettivo("molto allegra", f). aggettivo(allampanata, f). 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 alta come prima', f). % results risultato('era alto come prima', m). % results risultato('gli venne il mal di cuore', m). risultato('le venne il mal di cuore', f). risultato('rimase in disparte', _). commento('micropiccolo', m). % final adjective commento('assonnato', m). commento('affamato', m). commento('micropiccola', f). % final adjective commento('assonnata', f). commento('affamata', f). that('quel', m). that('quella', f). /* Grammatica */ verso1(Verso, Personaggio, G, Provenienza):- a_caso(personaggio(Personaggio, G)), articolo(Articolo,G), % the article should agree with the chosen person a_caso(aggettivo(Aggettivo, G)), % gender agreement with the chosen person a_caso(provenienza(Provenienza)), atomic_list_concat([Articolo,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, G):- a_caso(risultato(Risultato, G)), % gender agreement with the chosen person atomic_list_concat([Risultato],Verso). verso5(Verso, Personaggio, G, Provenienza):- a_caso(commento(Commento, G)), that(That, G), % gender agreement with the chosen person atomic_list_concat([That,Commento, Personaggio, "di",Provenienza]," ",Verso). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% limerick:- repeat, verso1(Verso1, Personaggio, G, Provenienza), % verso1 chooses a Person and Place verso2(Verso2), verso3(Verso3), verso4(Verso4, G), verso5(Verso5, Personaggio, G, 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) :- % FIXME: extend to predicates like pred('text', male, singular) with properties % EXPECT the string as first arg, remaining args as properties Fact =.. [PredName, _ | Args], % retrieve predicate functor (PredName) and properties (args) Pred =.. [PredName, _ | Args], % clone it with a new empty variable for the string 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 reference to the Nth clause that matches clause(Fact,true,ClauseRef). % facts have Body=true, retrieve the head and unify with original Fact %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%