2012-02-04 6 views
1

У меня есть этот сценарий, в котором я получить линейное уравнение в запросе Prolog, как показано ниже:Как работать с уравнениями, которые передаются в цели/запросе пролога?

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

Так мой запрос имеет уравнение 3X + 5Y = 10, что в общем случае принимает вид AX + BY = C, где A = 3, B = 5 и C = 10.

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

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

Я новичок в Prolog, любая помощь действительно оценена.

+0

Какую реализацию пролога вы используете? кажется, что в swi-prolog вы не можете иметь аргумент формы, которую вы описали (3X + 5Y = 10) –

+0

Я искал пролог eclipse, но все должно быть хорошо, мне просто нужно правильно понять понятия. – kallakafar

ответ

1

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

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 как данность, первый arg из Term является Val1, функтор Val1 является F1 с арностью A1 (а значит, он имеет A1 args - subparts - сам), а второй arg срока в Val1 хранится под именем Val12. Чтобы уточнить, любые символические данные в Prolog находятся в форме fff(aa,bb,cc,...), где fff - это какое-то имя, называемое functor, и к «аргументам» в этом выражении можно получить доступ через вызов arg.

Это означает, что исходное выражение (3*_X + 5*_Y = 10) фактически хранится в Prolog как '='('+'('*'(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 

EDIT: ответить на ваш другой вопрос (с комментариями):

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

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

Yes 

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

EDIT: еще одна вещь, чтобы попытаться это =.. предикат, называется "Унив":

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 
+0

Спасибо за редактирование .. Кажется, я понял логику. Позвольте мне попробовать. – kallakafar

+0

@kallakafar btw в случае, если вы этого не знали, здесь, в Stackoverflow, вы можете * принять * ответ, если/который, по вашему мнению, отвечает на ваш вопрос, нажав на большой пустой зеленый галочкой (V-образный) рядом с ним. Это даст автору определенную репутацию (15?). Кроме того, можно «проголосовать» за ответ, который дает ему 10 очков репутации. Часть опыта SO. :) –

+0

yep, я попытался поднять этот ответ, но потом он сказал, что мне нужно иметь 15 очков, чтобы сделать это, что, к сожалению, я не делаю. я не заметил его как ответ, так что я могу попробовать его сам, и, возможно, пост-ответы на вопросы. :) Я буду, как только я закончу .. обязательно! спасибо, Уилл. – kallakafar

1

Вы можете, например, использовать термин осмотр предикаты: ARG/3, функтор/3, вар/1, (= ..)/2 и т.д.

+0

Умм .. не могли бы вы рассказать о том, как получить 3, хранящихся в A1, x, как A2, 5 как B1, Y как B2 и 10 как C (из примера, который я дал в основном вопросе).? Я по-прежнему борюсь за то, как использовать аргумент arg (или, в этом случае, functor/3, var/1 и т. Д.) Для примера, который я привел. Благодаря! – kallakafar

0

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

Вот глава (минус 1 страница) из книги п и Следствия, которые могут оказаться полезными: Clause and Effect - Chapter Six: Term Rewriting

Другой из искусства Пролог: современные методы программирования 23 An equation solver

Programming in Prolog также имеет раздел (7.11) о символическом дифференцировании.

2

SWI-Prolog имеет ограничение library 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 как язык хозяина, поэтому обычные идентификаторы могут применяться для идентификации варов, констант и т.п.