0
votes

I'm just starting my Prolog course, and I'm having a really hard time understanding my latest practice. I'm supposed to modify some code my teacher gave us so it answers certain queries about the subway at Mexico City. Here's the code:

linea(1,[observatorio,tacubaya,juanacatlan,chapultepec,sevilla,cuahtemoc,
     balderas,salto_del_agua,isabel_la_catolica,pino_suarez,merced,
     candelaria,san_lazaro,moctezuma,balbuena,bulevard_puerto_aereo,
     gomez_farias,zaragoza,pantitlan]).
linea(2,[cuatro_caminos,panteones,tacuba,cuitlahuac,popotla,colegio_militar,
     normal,san_cosme,revolucion,hidalgo,bellas_artes,allende,zocalo,
     pino_suarez,san_antonio_abad,chabacano,viaducto,xola,villa_de_cortes,
     nativitas,portales,ermita,general_anaya,tasquena]).
linea(3,[indios_verdes,deportivo_18_de_marzo,potrero,la_raza,tlatelolco,
     guerrero,hidalgo,juarez,balderas,niños_heroes,hospital_general,
     centro_medico,etiopia,eugenia,division_del_norte,zapata,coyoacan,
     viveros,miguel_angel_de_quevedo,copilco,universidad]).
linea(4,[martin_carrera,talisman,bondojito,consulado,canal_del_norte,
     morelos,candelaria,fray_servando,jamaica,santa_anita]).
linea(5,[politecnico,instituto_del_petroleo,autobuses_norte,la_raza,misterios,
     valle_gomez,consulado,eduardo_molina,aragon,oceania,terminal_aerea,
     hangares,pantitlan]).
linea(6,[el_rosario,tezozomoc,azcapotzalco,ferreria,norte_45,vallejo,
     instituto_del_petroleo,lindavista,deportivo_18_de_marzo,basilica,
     martin_carrera]).
linea(7,[el_rosario,aquiles_serdan,camarones,refineria,tacuba,
     rio_san_joaquin,polanco,auditorio,constituyentes,tacubaya,
     san_pedro_de_los_pinos,san_antonio,mixcoac,barranca_del_muerto]).
linea(8,[garibaldi,bellas_artes,san_juan_de_letran,salto_del_agua,
     doctores,obrera,chabacano,la_viga,santa_anita,coyuya,iztacalco,
     apatlaco,aculco,escuadron_201,atlalilco,iztapalapa,
     cerro_de_la_estrella,uami,constitucion_de_1917]).
linea(9,[tacubaya,patriotismo,chilpancingo,centro_medico,lazaro_cardenas,
     chabacano,jamaica,mixihuca,velodromo,ciudad_deportiva,puebla,
     pantitlan]).
linea(a,[pantitlan, agricola_oriental,canal_de_san_juan,tepalcates,guelatao,
     peñon_viejo,acatitla,santa_marta,los_reyes,la_paz]).
linea(b,[ciudad_azteca,plaza_aragon,olimpica,ecatepec,muzquiz,
     rio_de_los_remedios,impulsora,nezahualcoyotl,villa_de_aragon,
     bosque_de_aragon,deportivo_oceania,oceania,romero_rubio,
     r_flores_magon,san_lazaro,morelos,tepito,lagunilla,garibaldi,
     guerrero,buenavista]).
linea(12,[mixcoac,insurgentes_sur,hospital_20_de_noviembre,zapata,
      parque_de_los_venados,eje_central,ermita,mexicaltzingo,
      atlalico,culhuacan,san_andres_tomatlan,lomas_estrella,calle_11,
      periferico_oriente,tezonco,olivos,nopalera,zapotitlan,
      tlaltenco,tlahuac]).

% Utilidades

member(X,[X|Xs])
member(X,[Y|Xs]):-member(X,Xs).

For the lists, the first element (the number) is the subway line number, and second element (the sublist) are the stations on each line. I just don't know how to interpret the lists, or why they're stated as facts, or why he would add the line number as a member of the list instead of putting it in the name.

If anyone could explain to me how I could query prolog using the member statement and get a true/false answer, I'd be really greatful.

Edit: I managed to make it work using member(atlalilco, L), but it just gives the following:

L = [atlalilco|_G396] :-;
L = [_G395, atlalilco|_G399] |;
L = [_G395, _G398, atlalilco|_G402] |;
L = [_G395, _G398, _G401, atlalilco|_G405] |;
L = [_G395, _G398, _G401, _G404, atlalilco|_G408] |
.
.
.

I can't make heads nor tails of all that. Any help is appreciated.

1
I'm not sure what you're confused about; maybe try clarifying your question? I assume the predicate linea(N,ListOfStations). is meant to be a statement that line N consists of the stations in the supplied list. What modifications were you asked to make? - Mark Reed
For example, I have to write the statement same(X,Y) that says if two stations are on the same line. And you're right, it's not really clear what I'm asking. Sorry about that. I'll edit the origina post. - user3898085
To answer your question on using member(atlalilco, L) : - the first response [atlalilco | Rest] says that atlalilco is a member of the list where atlalilco is the first element of a list with anything following (Rest); which is indeed true - second response says that atlalilco is a member of the list where atlalilco is the second element of the list, anything being the first member and anything following, and so on ! Very logical don't you think? - peter.cyc

1 Answers

0
votes

Assuming the given member function works, then you can use it like this:

same(X,Y) :- linea(_,L), member(X,L), member(Y,L), !.

That says that X and Y are on the same line if there is some line (we don't care which one, hence the "don't-care" placeholder _) that has a list of stations L such that both X and Y are members of L.

The cut operator ! says that once the interpreter finds any line where this is true, it can stop looking for more; all we care about is the boolean result.