На этом шаге мы рассмотрим сравнение.
Пролог может сравнивать арифметические выражения так же, как символы, сроки и идентификаторы. Следующее выражение в Прологе эквивалентно выражению: "Сумма X плюс 4 меньше 9 минус Y".
X+49-YОператор отношения "меньше чем" (<) показывает отношение между двумя выражениями: X+4 и 9-Y.
Пролог использует инфиксную нотацию, которая означает, что оператор располагается между операндами (X+4) вместо того, чтобы предшествовать им (+(X,4)). Полный ряд отношений, разрешенных в Прологе, приведен в таблице 1.
Идентификатор | Отношение | Идентификатор | Отношение |
---|---|---|---|
< | Меньше | > | Больше |
<= | Меньше или равно | >= | Больше или равно |
= | Равно | <> или >< | Не равно |
В Прологе такие операторы, как N=N1-2 показывают отношение между тремя объектами (N,N1 и 2) или отношение между двумя объектами (N и величиной N1-2). Если N еще свободно, оператор может быть удовлетворен присвоением N значения выражения N1-2. Это приблизительно соответствует тому, что в других языках программирования называется оператором присваивания. Заметим, что поскольку N1 является частью вычисляемого выражения, оно всегда должно быть определено (т.е. должно быть связано со значением).
Когда вы для сравнения вещественных величин используете предикат равенства (=), нужно позаботиться о том, чтобы приближенное представление вещественных чисел не привело к непредсказуемым результатам. Например, цель
7/3*3=7потерпит неудачу. Программа, приведенная ниже, иллюстрирует еще один пример.
predicates test(real,real) clauses test(X,X):-!, write("ok\n"). test(X,Y):- Diff=X-Y, write(X,"<>",Y,"\nX-Y=",Diff,'\n'). goal X=47, Y=4.7*10, test(X,Y).
Результат будет следующий:
47<>47
X-Y=7.1054273576E-15
Следовательно, сравнивая два вещественных числа на равенство, вам всегда следует проверять, чтобы эти два числа находились в определенном диапазоне друг относительно друга.
Приведем следующий пример:
Следующая программа показывает, как обработать приблизительное равенство. Она представляет собой итеративную процедуру вычисления квадратного корня для определения решений квадратного уравнения:
A*Х*Х+В*Х+С=0Наличие решений зависит от значения дискриминанта D, определяемого как
D=В*В-4*А*СВ данном случае:
predicates solve(real,real,real) reply(real,real,real) mysqrt(real,real,real) equal(real,real) clauses solve(A,B,C):- D=B*B-4*A*C, reply(A,B,D),nl. reply(_,_,D):- D<0, write("No solution"), !. reply (A,B,D):- D=0, X=-B/(2*A), write("x=", X),!. reply(A,B,D):- mysqrt(D,D,SqrtD), X1=(-B+SqrtD)/(2*A), X2=(-B-SqrtD)/(2*A), write("Xl = ",X1," and X2 = ", X2). mysqrt(X,Guess,Root):- NewGuess=Guess-(Guess*Guess-X)/2/Guess, not(equal(NewGuess,Guess)), !, mysqrt(X,NewGuess,Root). mysqrt(_,Guess,Guess). equal(X,Y):- X/Y>0.99999, X/Y<1.00001. goal solve(1,2,1).
Чтобы решить квадратное уравнение, эта программа вычисляет квадратный корень из дискриминанта D. Программа вычисляет квадратные корни по итеративной формуле, где новое значение (NewGuess) квадратного корня от X может быть получено из предыдущего значения (Guess):
NewGuess=Guess-(Guess*Guess-X)/2/GuessКаждая итерация немного приближается к квадратному корню от X. Когда условие equal(X,Y) удовлетворяется, дальнейшего приближения достичь нельзя - вычисление заканчивается. Теперь программа может решить квадратное уравнение, используя значения Xl и Х2
X1=(-В+sqrtD)/(2*A)На следующем шаге мы рассмотрим сравнение символов, строк и идентификаторов.