如何在Prolog中编写类型的条件计划? [英] How to write kind of Conditional Planning in Prolog?

查看:111
本文介绍了如何在Prolog中编写类型的条件计划?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图编写一个可以理解用C#编写的学生程序的序言代码。现在,我被困在识别学生程序中的 if陈述的过程中。例如:
以下是我希望学生给出的代码。

I tried to write a prolog code that can understand student program written in C#. Now I'm stuck in the process of recognizing the 'if' statement in student's program. For example: The following is the code that I expect from the student.

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;

我将此预期代码的目标定义为:

I defined the goal of this expected code as:

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]

问题是我该如何在序言事实和规则中表示上述学生代码,以找出目标对所有可能的条件都感到满意。

The problem is how can I represent the above student code in prolog facts and rules, to find out that the goal is satisfied for any possible conditions.

我试图将学生代码的第一部分更改为如下事实,但实际上并不知道如何表示学生的'if'陈述作为prolog中的事实/规则(我想,我不应该将其更改为prolog'if',对吗?)

I tried to change the first part of the student code to become facts like the following, but don't really know how to represent the student's 'if' statement as facts/rules in prolog (I guess, I should not change it to prolog 'if', right?)

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 )。

And another one, in my goal, when I have comparison such as gt(Vd,0) I think I cannot use the prolog greater than operator, neither Vd> 0 nor Vd @> 0 cause the value in Vd is actually a certain value entered by user, but it is represented as symbolic value (in this case it is: val_d).

注意:使用上述目标,我认为如果将学生代码更改为以下代码,则可以满足已定义的目标。

Note: using the above goal, I think the defined goal will be satisfied if student code is changed to the following code.

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;

但是我还是需要帮助/想法,如何才能在序言中将此代码表示为action / rule /事实达到目标。

But again, I need help/idea how this code can be represented in prolog as action/rule/fact to meet the goal.

任何帮助都很感激。

非常感谢

推荐答案

通常,语言实现需要抽象的语法树,在该语法树中,可以方便地指定实现允许我们表达的构造的语义动作。

Usually a language implementation requires an abstract syntax tree, where it's convenient to specify the semantic actions that implements the constructs we are allowed to express.

您似乎跳过了构建语法树的阶段,并且(手动?)表示程序的中间级别。

You seem skipping the phase of building the syntax tree, and (by hand?) represent the intermediate level of the program.

如果您坚持这样的中级表示形式,您可以使用递归术语(实际上是抽象树),例如 if(Condition,Then,Else),其中每个var依次是语法树

If you stick to such medium level representation, you can use a recursive term (an abstract tree, in effect) like if(Condition, Then, Else) where each var it's in turn a syntax tree.

否则,一种更实用的表示形式(通常用于命令式语言),使用基本块的概念(无跳转的指令序列),然后使用标签来描述执行流程。

Otherwise, a more practical representation (usually applied for imperative language), use the concepts of basic blocks (an instruction sequence without jumps) and then labels, to describe the execution flow.

结果是一个图形,程序的行为由该程序的拓扑决定

The result it's a graph, and the behaviour of the program is determined by the 'topology' of that representation.

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),
   .....

请注意,我没有注意正确描述您的示例程序,只是将跳来显示这种可能性...

Note that I didn't pay any attention to describe correctly your sample program, just placed the jumps to show this possibility...

编辑我认为 general 问题无法解决,等效于图灵机的停止问题。对于当前的特殊情况,没有循环,我会在AST上使用抽象解释来解决该问题。即,一个解释器会计算出有趣的内容。

edit I think that the general problem can't be solved, being equivalent to the halting problem for a Turing Machine. For the particular case at hand, without loops, I would attack the problem using abstract interpretation on the AST. I.e. an interpreter that computes what's interesting.

如果可行le取决于目标程序的一般性。您应该能够为每个条件点所涉及的每个变量划分整数域。事情变得非常复杂...

If it's feasible depends on the generality of your target programs. You should be able to partition the integer domain for each variable involved in each condition point. Things become rapidly complex...

特别是在否则尝试对域进行分区的条件下。使用这种方法,让Prolog在IF中测试两个分支并传播值,从而执行执行。但是,正如我所说,这并不是一件容易的事。

Specifically, at the condition point of the IF THEN ELSE attempt to partition the domain. Using such approach, let Prolog execute the IF testing both branches, propagating the values. But, as I said, is not really easy...

这篇关于如何在Prolog中编写类型的条件计划?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆