Azzal kezdem, hogy mi tanulsag azok szamara is, akiket az alabbi reszletek
nem erdekelnek. (Mindket dolgot persze a DP-n probaltam mar tanitani nektek :-()
(1) Fontos mindig szem elott tartani, hogy a Prolog kifejezesek
fastrukturak, minden Prologon beluli transzformacio ezen a nagyon egyszeru
belso alapstruktura alakon tortenik. Beolvasaskor es kiiraskor a belso alak
es az "olvashato" kulso alak kozott transzformal a rendszer. Ami NAGYON
FONTOS az az, hogy amikor a Prolog "belsejeben" vagyunk, mindenkeppen az
alapstruktura (vagy pointeres fastruktura) alakban kepzeljuk el a
kifejezeseinket!
(2) Meg egy kisebb hordereju de altalanos tanulsag: Egy apro "csunyasag"
van a Prologban a prefix operatorok es az alapstruktura alak
megkulonboztesere. Ha p egy prefix operator, akkor a p(X)-et a rendszer
*nem* operatoros kifejezeskent elemzi, hanem alapstruktura alakkent. Ha
operatoros alakkent akarjuk ertelmeztetni, akkor szokozt kell irnunk az
operator es a `(' koze.
Marton Jozsef Erno <mj492(a)hszk.bme.hu> writes:
Itt en erre gondoltam:
| ?- use_module(library(clpfd)).
| ?- write_canonical(\(2..4) /\ (7..9)).
/\(\(..(2,4)),..(7,9))
yes
| ?- expand_term(\(2..4) /\ (7..9), T).
T = (\ (2..4))/\(7..9) ? ;
no
| ?- expand_term((2..4)/\ \(7..9), T).
T = (2..4)/\(\ (7..9)) ? ;
no
Az expand_term egy olyan eljaras, amelyet a rendszer akkor alkalmaz, amikor
programot olvas be. Miutan beolvasott egy ponttal lezart kifejezest,
meghivja ra az expand_term-et, es ez adja a beolvasas eredmenyet.
Az expand_term nem csinal mast, mint elvegzi a DCG-kifejtest valamint
a felhasznalo (vagy konyvtar) altal esetlegesen a term_expansion altal
definialt *klozszintu* transzformaciokat, pl.
| ?- expand_term((a-->b,c), T).
T = (a(_A,_B):-b(_A,_C),c(_C,_B)) ?
A clpfd konyvtar a term_expansion mechanizmust hasznalja az FP predikatumok
feldolgozasara, de masra nem (a goal_expansion mechanizmus szolgal a
korlatok kifejtesere). Az expand_term soha sem hivodik meg olyan
parameterrel, mint ami a te peldadban szerepel, kiveve, ha ezek a
kifejezesek egy .-tal lezart programelemkent szerepelnek.
A fenti expand_term hivasok pontosan ugyanazt a kifejezest adjak vissza a
masodik parameterukben, mint amit kapnak az elsoben. Tehat ugyanazt a
valaszt kapod, ha csak egy = /2 hivast irsz:
| ?- T = \(2..4) /\ (7..9).
T = (\ (2..4))/\(7..9) ? ;
no
| ?- T = (2..4)/\ \(7..9).
T = (2..4)/\(\ (7..9)) ? ;
no
| ?-
Na, azt hiszem most ertettem meg, hogy mi a gondod. Talan az, hogy miert
nem ugyanazt irja vissza a valaszban a Prolog. Hat azert, mert amit
beadtal, a `\(2..4)', az egy f(...) alaku strukturakifejezes, es miutan van
egy ervenyes operatordeklaracio a \ /1 strukturakra, a kiiras az operatoros
alakot hasznalja. Azon gondolom nem lepodsz meg, ha a
| ?- T = +(1,2). kerdesre T = 1+2 a valasz.
A kovetkezo kerdes, hogy miert rakja zarojelbe: (\ (2..4)). Hat azert, mert
a \ egy 500 prioritasu, fy fajtaju operator, mig az utana jovo /\
prioritasa szinten 500. Az fy azt jelenti, hogy jobboldalan magaval azonos
prioritasu operatort elfogad, tehat \ X /\ Y zarojelezese ez lenne:
\ (X /\ Y). Mivel a kiirando kifejezes nem ilyen szerkezetu, ezert az /\ elso
operandusat zarojelezni kell.
A level elejen levo (2) megjegyzes szerint tehat
\(2..4) /\ (7..9)
es
\ (2..4) /\ (7..9)
nem ugyanaz a kifejezes, az elsoben a legkulso struktura funktora /\ /2,
mig a masodikban \ /1.
-Peter