Как мне работать с уравнениями, которые передаются в цели / запросе пролога?

У меня есть этот сценарий, в котором я получаю линейное уравнение в запросе Prolog, как показано ниже:

?- myquery( 3X + 5Y = 10, Result).

Итак, в моем запросе есть уравнение 3X + 5Y = 10, которое в целом принимает форму AX + BY = C, где A = 3, B = 5 и C = 10.

Теперь в своей программе пролога я пытаюсь определить предикат, который может принимать выражение, упомянутое в запросе выше. То есть я как-то хочу получить значения A, B и C, а также задействованный оператор (в приведенном выше случае оператор плюс), сохраненный и затем используемый в логике, которую я определяю в программе. Мне интересно, как это можно сделать.

В более общем смысле, вопрос в том, как определить константы и оператор, участвующие в уравнении, которое передается через цель / запрос?


person kallakafar    schedule 04.02.2012    source источник
comment
какую реализацию пролога вы используете? похоже, что в swi-prolog у вас не может быть аргумента в описанной вами форме (3X + 5Y = 10)   -  person Thanos Tintinidis    schedule 04.02.2012
comment
Я ищу пролог eclipse, но все должно быть в порядке, мне просто нужно правильно понять концепции.   -  person kallakafar    schedule 04.02.2012


Ответы (4)


Следующая стенограмма может оказаться полезной:

32 ?- Term = (3*_X + 5*_Y = 10), functor(Term,F,A).

Term = 3*_G527+5*_G530=10
F = =
A = 2 

33 ?- Term = (3*_X + 5*_Y = 10), arg(Arg,Term,Val).

Term = 3*_G459+5*_G462=10
Arg = 1
Val = 3*_G459+5*_G462 ; % user pressed ';' interactively

Term = 3*_G459+5*_G462=10
Arg = 2
Val = 10 ; % user pressed ';' interactively

No
35 ?- Term = (3*_X + 5*_Y = 10), arg(1,Term,Val1), functor(Val1,F1,A1),
      arg(2,Val1,Val12).

Term = 3*_G693+5*_G696=10
Val1 = 3*_G693+5*_G696
F1 = +
A1 = 2
Val12 = 5*_G696 

Последний запрос гласит: для Term, как указано, 1-й arg из Term равен Val1, функтор Val1 - F1 с арностью A1 (то есть он имеет A1 args - подчасти - самого себя), а 2-й arg термина в Val1 хранится в Val12 имя. Чтобы уточнить, любые символьные данные в Прологе имеют форму fff(aa,bb,cc,...), где fff - это какое-то имя, называемое функтором, а к «аргументам» в этом выражении можно получить доступ через вызов arg.

Это означает, что исходное выражение (3*_X + 5*_Y = 10) фактически хранится в Прологе как '='( '+'( '*'(3,_X), '*'(5,_Y)), 10). Когда вы дойдете до атомарных частей (функторов с арностью 0), вы можете проверить их дальше:

47 ?- arg(1,(3*X),V), functor(V,F,A), number(V).

X = _G441
V = 3
F = 3
A = 0 

Yes

РЕДАКТИРОВАТЬ: чтобы ответить на ваш другой вопрос (из комментариев):

1 ?- (3*_X + 5*_Y = 10) = (A*X + B*Y = C).

A = 3
X = _G412
B = 5
Y = _G415
C = 10 

Yes

Если вы настаиваете на том, чтобы не записывать знак умножения * явно, вам придется представить свои термины в виде строк и проанализировать эту строку. Это было бы гораздо более сложной задачей.

РЕДАКТИРОВАТЬ: еще одна вещь, которую стоит попробовать, - это =.. предикат, называемый "Univ":

4 ?- (3*_X + 5*_Y = 10) =.. X.

X = [=, 3*_G454+5*_G457, 10] 

Yes
5 ?- (3*_X + 5*_Y = 10) =.. X, X=[X1,X2,X3], X2 =.. Y.

X = [=, 3*_G545+5*_G548, 10]
X1 = =
X2 = 3*_G545+5*_G548
X3 = 10
Y = [+, 3*_G545, 5*_G548] 

Yes
person Will Ness    schedule 04.02.2012
comment
Спасибо за редактирование .. Кажется, теперь я понял логику. Дай мне попробовать. - person kallakafar; 05.02.2012
comment
@kallakafar, кстати, если вы этого не знали, здесь, в Stackoverflow, вы можете принять ответ, если / который, по вашему мнению, отвечает на ваш вопрос, щелкнув большую пустую зеленую галочку (V-образную) рядом с ним. Это даст автору несколько очков репутации (15?). Кроме того, можно проголосовать за ответ, что даст ему 10 очков репутации. Часть опыта SO. :) - person Will Ness; 05.02.2012
comment
Да, я пытался проголосовать за этот ответ, но потом он сказал, что мне нужно самому набрать 15 баллов, чтобы сделать это, чего, к сожалению, я не делаю. Я не пометил это как ответ, чтобы я мог попробовать сам и, возможно, задать дополнительные вопросы. :) Я сделаю это, когда закончу .. конечно! спасибо, Уилл. - person kallakafar; 05.02.2012
comment
@kallakafar Я добавил к ответу еще несколько примеров кода, проверьте это. :) - person Will Ness; 05.02.2012
comment
Спасибо, @Will Ness. Я все еще пробую ваши решения, но думаю, что понял вашу точку зрения. Я обновлю этот пост, если у меня возникнут вопросы. Спасибо! - person kallakafar; 06.02.2012

SWI-Prolog имеет ограничение библиотека clp (Q, R), которая решает на символическом уровне следующие уравнения:

[debug]  ?- [library(clpq)].
% library(clpq) compiled into clpq 0,27 sec, 992 clauses
true.

?- {3 * X + 5 * Y = 10}.
{Y=2-3 rdiv 5*X}.

У Eclipse наверняка будет что-то более продвинутое. Эти библиотеки не простые, жесткие ...

Вас интересует, что в качестве основного языка используется синтаксис Prolog, поэтому обычные встроенные функции могут применяться для идентификации переменных, констант и т.п.

person CapelliC    schedule 05.02.2012

Например, вы можете использовать предикаты проверки терминов: arg / 3, functor / 3, var / 1, (= ..) / 2 и т. Д.

person mat    schedule 04.02.2012
comment
Умм .. не могли бы вы уточнить, как сохранить 3 в A1, x как A2, 5 как B1, Y как B2 и 10 как C (из примера, который я привел в основном вопросе) ..? Я все еще борюсь с тем, как использовать arg (или, если на то пошло, functor / 3, var / 1 и т. Д.) Для примера, который я процитировал. Спасибо! - person kallakafar; 04.02.2012

Возможно, вы захотите взглянуть на примеры символической дифференциации, реализованной с использованием правил перезаписи терминов; они справляются с такими выражениями.

Вот глава (минус 1 страница) из книги Clause and Effect, которую вы можете найти полезной: Пункт и последствия - Глава шестая: Перезапись терминов

Еще одна статья из книги «Искусство Пролога: передовые методы программирования» 23 Решатель уравнений

Программирование на Prolog также имеет раздел (7.11) о символическом различении.

person Roman    schedule 04.02.2012