如何用 Java 或 C# 等语言实现统一算法?
我正在研读我拿到的人工智能教科书,并解决了我的部分的最后一个作业问题:
“用您选择的任何语言实现第 69 页上概述的统一算法。”
在第 69 页,您有以下统一算法的伪代码:
function unify(E1, E2);
begin
case
both E1 and E2 are constants or the empty list:
if E1 = E2 then return {}
else return FAIL;
E1 is a variable:
if E1 occurs in E2 then return FAIL
else return {E2/E1}
E2 is a variable
if E2 occurs in E1 then FAIL
else return {E1/E2}
either E1 or E2 are empty then return FAIL
otherwise:
begin
HE1 := first element of E1;
HE2 := first element of E2;
SUBS1 := unify(HE1, HE2);
if SUBS1 := FAIL then return FAIL;
TE1 := apply(SUBS1, rest of E1);
TE2 := apply(SUBS1, rest of E2);
SUBS2 := unify(TE1, TE2);
if SUBS2 = FAIL then return FAIL;
else return composition(SUBS1, SUBS2)
end
end
end
现在,我了解统一的一般概念,但我完全不知道如何开始用 Java 或 C# 等语言来实现它。
我什至不确定方法签名是什么样子。它需要什么类型的变量?我相当确定我需要返回列表来表示谓词演算结构,但这是一个猜测。
例如,当它说“E1 是一个变量”时,如果我将它传递到 Unify 方法中,它怎么可能不是呢?我可以检查 null,但这会与“空列表”不同吗?
任何人都可以帮助我或为我指明在 C# 或 Java 中实现 Unificaiton 算法的正确方向吗?
I'm working through my AI textbook I got and I've come to the last homework problem for my section:
"Implement the Unification Algorithm outlined on page 69 in any language of your choice."
On page 69, you have the following pseudo-code for the unification algorithm:
function unify(E1, E2);
begin
case
both E1 and E2 are constants or the empty list:
if E1 = E2 then return {}
else return FAIL;
E1 is a variable:
if E1 occurs in E2 then return FAIL
else return {E2/E1}
E2 is a variable
if E2 occurs in E1 then FAIL
else return {E1/E2}
either E1 or E2 are empty then return FAIL
otherwise:
begin
HE1 := first element of E1;
HE2 := first element of E2;
SUBS1 := unify(HE1, HE2);
if SUBS1 := FAIL then return FAIL;
TE1 := apply(SUBS1, rest of E1);
TE2 := apply(SUBS1, rest of E2);
SUBS2 := unify(TE1, TE2);
if SUBS2 = FAIL then return FAIL;
else return composition(SUBS1, SUBS2)
end
end
end
Now, I understand the general concept of unification but I have absolutely no idea how I would even begin to implement this in a language like Java or C#.
I'm not even sure what the method signature would look like. What type of variables would it take? I'm fairly certain I need to return lists to represent predicate calculus constructs but that is a guess.
For example, when it says "E1 is a variable", well, if I'm passing it into the Unify method, how could it be anything but? I could check for null but would that be different than "empty list"?
Can anyone help me or point me in the right direction for implementing the Unificaiton algorithm in C# or Java?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于任何感兴趣的人,我在以下位置找到了相同的算法
http://www.cs.trincoll.edu/~ram/cpsc352 /notes/unification.html 有更多上下文。
让我们看第一行:
E1 和 E2 是表达式:列表、变量或常量。在传统的 OOP 风格中,通常我们会创建一个抽象基类
Expression
并从中派生其他类,例如List
、Variable
或Constant
。但在我看来,这太过分了。我使用dynamic
关键字在 C# 中实现了这一点。下一个问题是它返回什么?可以作为
Dictionary
实现的绑定列表。下面是我所在的 Jigsaw 库的 C# 实现片段为教学如何实现 C# 语言而开发。
您可以在 http: //code.google.com/p/jigsaw-library/source/browse/trunk/Unifier.cs。并不是说在此示例中,
List
类实际上是我为库实现的 Lisp 样式列表。For anyone interested I found the same algorithm at
http://www.cs.trincoll.edu/~ram/cpsc352/notes/unification.html with a bit more context.
Lets look at the first line:
E1 and E2 are expressions: either lists, variables, or constants. In traditional OOP style typically we would create an abstract base class
Expression
and derive other classes from it likeList
,Variable
, orConstant
. However in my opinion this is overkill. I implemented this in C# using thedynamic
keyword.The next question is what does it return? A list of bindings which can be implemented as a
Dictionary<string, Object>
.Below is a snippet from the C# implementation of an implementation from a library called Jigsaw that I am developing for teaching how to implement languages C#.
You can find the rest of the algorithm code online at http://code.google.com/p/jigsaw-library/source/browse/trunk/Unifier.cs. Not that in this example the
List
class is actually a Lisp-style list that I implemented for the library.表示类型变体的最佳方式是继承。例如,表达式序列仍然只是一个表达式。空列表将由序列对象中的零长度容器表示。因此,对于失败,返回 null 是可以接受的,我用“?”表示。我不确定 C# 是否真的有“?”,但应该明白了。
编辑:该列表是协变的。请参阅此处。我的 C# Vala 方言支持此功能(目前),但我不相信 .net 可以。
The best way to represent type variants is with inheritance. For example, a sequence of expressions is still just an expression. An empty list would be represented by a zero length container in the sequence object. Returning null is therefore acceptable for failure, which I indicate with '?'. I'm not sure if C# actually has a '?', but should get the drift.
EDIT: The list is covariant. See here. My Vala dialect of C# supports this (for now), but I don't believe .net does.
实现算法时将使用的变量也许可以称为元变量。它们是程序中的变量,描述其他程序中的变量(或常量,或列表等)。因此,您需要使用一个变量来告诉您对象的类型(例如变量、常量)和对象的值。您可以按照 Samuel Danielson 的建议通过继承来完成此操作,或者通过某种 Variant 对象(如果您的语言提供了一种),或者可以描述任何类型变量的手动变体类(例如,通过描述类型的枚举和各种类型字段,其中只有一个有效,具体取决于类型)。
The variables you will use when implementing the algorithm are perhaps what you could call metavariables. They are variables in your program that describe a variable (or constant, or list, etc) in some other program. As such you need to use a variable that tells you the type of the object (eg. variable, constant) and the value of the object. You can do this via inheritance as Samuel Danielson has suggested, or via some sort of Variant object if your language provides one, or a hand-rolled variant class that can describe any type of variable (eg. via an enum describing the type and a variety of typed fields, of which only one is valid, dependent on the type).
“...是一个变量”意味着检查变量的类型。如果 E1 的类型是变量值(即不是类型列表且不是常量值),则执行某些操作。
The "... is a variable" means to check the type of the variable. If the type of E1 is a variable value (i.e. not of the type list and not a constant value), then do something.