Как написать вид условного планирования в прологе?

Я попытался написать код пролога, который может понять программу студента, написанную на C #. Теперь я застрял в процессе распознавания утверждения «если» в студенческой программе. Например: ниже приведен код, который я ожидаю от студента.

int d = int.Parse(Console.ReadLine());  // value d is inputted by user
int s = 0;

if (d>0)
    s = 2;
else if (d==0)
    s = 1;
else
    s = 0;

Я определил цель этого ожидаемого кода как:

goal:- 
   hasVarName(Vid_s, s),
   hasVarName(Vid_d, d),
   hasVarValue(Vid_d, Vd),
   ((not(gt(Vd,0)); hasVarValue(Vid_s, 2)),           %eq: [Vd>0] -> [val_s = 2]
   ((gt(Vd,0); not(eq(Vd,0)); hasVarValue(Vid_s, 1)), %eq: [~(Vd>0)^(Vd=0)] -> [val_s = 1]
   ((gt(Vd,0); eq(Vd,0); hasVarValue(Vid_s, 0).       %eq: [~(Vd>0)^~(Vd=0)] -> [val_s = 0]

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

Я пытался изменить первую часть кода студента, чтобы она стала похожа на факты, подобные приведенным ниже, но я не знаю, как представить утверждение студента «если» как факты / правила в прологе (я думаю, я не должен менять его на пролог «если», верно?)

hasVarName(varID_d, d)
hasVarValue(varID_d, val_d)   %it is unknown, so I represent it as symbol 'val_d'

hasVarName(varID_s, s)
hasVarValue(varID_s, 0)

И еще один, в моей цели, когда у меня есть сравнение, такое какgt(Vd,0) Я думаю, что я не могу использовать пролог больше, чем оператор, ниVd> 0 ниVd @> 0 причиной того, что значение в Vd на самом деле является определенным значением, введенным пользователем, но оно представляется как символическое значение (в данном случае это:val_d).

Примечание: используя вышеуказанную цель, я думаю, что определенная цель будет достигнута, если код студента будет изменен на следующий код.

int d = int.Parse(Console.ReadLine());  // value d is inputted by user
int s = 0;

if (d>0)
    s = 2;
else if (d==0)
    s = 1;

или же

int d = int.Parse(Console.ReadLine());  // value d is inputted by user
int s = 10;           // any random initialization

if (d>0)
{
    int x = 2;       // unnecessary step, but still Ok.
    s = x;
}
else if (d==0)
    s = 1;
else
    s = 0;

Но опять же, мне нужна помощь / идея, как этот код может быть представлен в прологе как действие / правило / факт для достижения цели.

Любая помощь очень ценится.

Большое спасибо

Ответы на вопрос(2)

о, в котором удобно указывать семантические действия, реализующие конструкции, которые нам разрешено выражать.

Кажется, вы пропускаете этап построения синтаксического дерева и (вручную?) Представляете промежуточный уровень программы.

Если вы придерживаетесь такого представления среднего уровня, вы можете использовать рекурсивный термин (по сути, абстрактное дерево), напримерif(Condition, Then, Else) где каждый var это в свою очередь синтаксическое дерево.

В противном случае, для более практического представления (обычно применяемого для императивного языка), используйте понятия базовых блоков (последовательность команд без переходов), а затем меток, чтобы описать поток выполнения.

В результате получается график, и поведение программы определяется «топологией» этого представления.

goal:- 
   hasVarName(Vid_s, s),
   hasVarName(Vid_d, d),
   hasVarValue(Vid_d, Vd),

   %eq: [Vd>0] -> [val_s = 2]
   ((not(gt(Vd,0)); hasVarValue(Vid_s, 2), goto(label(0))),

   %eq: [~(Vd>0)^(Vd=0)] -> [val_s = 1]
   ((gt(Vd,0); not(eq(Vd,0)); hasVarValue(Vid_s, 1), goto(label(0))),

   %eq: [~(Vd>0)^~(Vd=0)] -> [val_s = 0]
   ((gt(Vd,0); eq(Vd,0); hasVarValue(Vid_s, 0)), % the goto is useless here...

   label(0),
   .....

Обратите внимание, что я не обратил никакого внимания на правильное описание вашей программы-примера, просто поместил переходы, чтобы показать эту возможность ...

редактировать Я думаю, чтоГенеральная проблема не может быть решена, будучи эквивалентнойпроблема остановки для машины Тьюринга. Для конкретного случая под рукой,без петельЯ бы атаковал проблему, используя абстрактную интерпретацию на AST. То есть интерпретатор, который вычисляет то, что интересно.

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

В частности, в точке условия IF THEN ELSE попытаться разбить домен. Используя такой подход, давайте прологвыполнять IF проверяет обе ветви, распространяя значения. Но, как я уже сказал, это не очень легко ...

 Budi Hartanto26 окт. 2012 г., 00:03
Привет Чак, спасибо за предложенное решение. Можете ли вы объяснить немного больше вашего предложения? К вашему сведению, это все, что я сделал: у меня есть программа на C #, которая читает программу C # для студентов. В моей программе на C # у меня есть AST студенческого кода. Из этого AST я создаю предложения по прологу, чтобы позволить прологу определить, выполнена ли поставленная мною цель для задачи студента или нет. Итак, у меня есть готовый AST в моей программе на C #, но я не знаю, как представить его в прологе, чтобы связать его с моей целью. Или, может быть, то, как я определяю свою цель, неверно? Спасибо

что вы пытались смоделировать if-then-else с помощью импликации, используя следующую логическую идентификацию:

A -> B == ~A v B.

Вместо использования сочетаний значений легче использовать дизъюнкцию для выбора между ветвями и конъюнкцией вдоль потока управления. Но то, что вы исключаете предыдущие if-условия через отрицание, все еще необходимо.

Возьмите свой пример:

if (d>0)
   s = 2;
else if (d==0)
   s = 1;
else
   s = 0;

Вы можете использовать CLP (*) для моделирования. Добавьте дополнительные переменные, чтобы переменные не переопределялись, но это не проблема в небольшом приведенном фрагменте. В CLP (*) приведенный выше фрагмент становится, я использую CLP (FD) для простоты:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 6.3.0)
Copyright (c) 1990-2012 University of Amsterdam, VU Amsterdam
?- use_module(library(clpfd)).
?- [user].
that_if(D, S) :-
   (D #> 0, S #= 2;
    D #=< 0, D #= 0, S #= 1;
    D #=< 0, D #\= 0, S #= 0)
^D

В приличной системе CLP (*) вы можете произвольно создавать или ограничивать D или S в запросе. Мы получаем, например, уже в CLP (FD):

/* What conditions give result S #= 1 ? */
?- S #= 1, that_if(D, S).
S = 1,
D = 0 .

/* What results give condition D #= 1 */
?- D #= 1, that_if(D, S).
D = 1,
S = 2 ;
false.

/* What conditions give a result S #=< 1 */
?- S #=< 1, that_if(D, S).
S = 1,
D = 0 ;
S = 0,
D in inf.. -1.

/* What results give a condition D #>= 0 */
?- D #>= 0, that_if(D, S).
S = 2,
D in 1..sup ;
D = 0,
S = 1 ;
false.

до свидания

 CapelliC25 окт. 2012 г., 15:27
CLP это интересно, но я думаю, что новичок могдействительно трудно понять это.
 j4n bur5325 окт. 2012 г., 16:14
Не мое мнение: я также не знаю, является ли Буди Хартанто новичком, и у меня нет статистических данных о том, что CLP (*) особенно сложен. CLP (*) должен быть проще, так как он более декларативный.
 Budi Hartanto25 окт. 2012 г., 23:45
Привет Cookie Monster, Спасибо за предложенное решение. Проблема в том, что в моем случае я бы никогда не узнал, каково значение d, потому что я никогда не буду запускать код студента. Мне просто нужно проанализировать, что код студента содержит достаточно планов (условий), чтобы решить поставленную перед ним задачу. Поэтому я никогда не узнаю значение D, и в моем примере я просто назначаю val_d как символическое представление содержимого переменной d. Итак, моя проблема в этом случае больше похожа на проверку плана (кода) учащегося, если он может быть использован для решения поставленной ему задачи.
 j4n bur5326 окт. 2012 г., 09:09
CLP (*) также не присваивает значения, если, например, в CLP (FD) не используется маркировка. Но ответ типа D в 1..sup - это не присвоение значения, а диапазон домена для переменной. Но вам потребуется немного больше кодирования и, в конечном итоге, ограничения, чтобы получить более точные ответы от вашего CLP (*) относительно вашего вопроса. Например, проверка spec_if (D, S) <-> code_if (D, S).
 j4n bur5325 окт. 2012 г., 16:18
Далее без некоторого CLP (*) не так много можно проверить. Если у вас есть int d = int.Parse (Console.ReadLine ()); тогда данные могут быть произвольными, и стандартный исчерпывающий поиск Prolog практически не будет отвечать на ваши запросы. Вам нужно что-то более символическое, например, CLP (*).

Ваш ответ на вопрос