2014-11-16 105 views
1

在我的Prolog程序中,我有一个谓词reg/1,它说如果某个东西是正则表达式。我想让程序将正则表达式序列识别为正则表达式。因此,如果reg(a_1),reg(a_2),...,reg(a_n)都是正则表达式,Prolog应该回答是/否回答reg(a_1, a_2, ..., a_n)。 但我不知道该怎么做。函数不是固定的(Prolog)

我所做的是以下几点:

reg([H|T]) :- reg(H), reg(T). 
reg([X]) :- reg(X). 

如果,例如,reg(a)reg(b)reg(c)都在知识基础,然后Prolog的回答是/真到查询reg([a, b])reg([b, a, c]),但我不能问它像reg(a, b)reg(b, a, c),即我不能摆脱方括号。

回答

3

在Prolog中,使用具有不同arities的相同结构是非常罕见的。为了向你展示一个他们可能被使用但不是的地方,考虑它们用于声明谓词动态,多文件或不连续的指令。说,我想声明a/2b/5动态。下列选项ISO-Prolog的是可能的:

:- dynamic(a/2). 
:- dynamic(b/5). 

:- dynamic([a/2,b/5]). % using a list 

:- dynamic((a/2,b/5)). % using an and-sequence 

此外,许多Prolog的系统已经宣布dynamic/1前缀运算符(如实现特有的扩展名),这样你可以写:

:- dynamic a/2. 
:- dynamic b/5. 

:- dynamic [a/2,b/5]. 

:- dynamic a/2, b/5. 

然而,没有

:- dynamic(a/2,b/5). % does not work 

这将符合您的想法。


如果你真的想使用的表示,你将需要(=..)/2了点。我会说这是许多潜在错误的来源。


我想到的地方与“变量”元数的结构是常用的是组变量简洁表示,因为它们在setof/3实现中使用的唯一情况。代替使用变量列表Vs,使用结构V

term_varvect(T, V) :- 
    term_variables(T, Vs), 
    V =.. ['.'|Vs].   % some use v instead of '.' 

在系统与你必须处理溢出情况下,有限的max_arity

term_varvect(T, V) :- 
    term_variables(T, Vs), 
    catch(V =.. ['.'|Vs], 
      error(representation_error(max_arity), _), 
      Vs = V). 
+0

这是一门功课,所以我不能由我自己决定如何表述的东西。其实这与我所说的有点不同。我的程序应该认识到所有原子是正则表达式,即is_regexp(X): - atomic(X)。并且对于任意序列,它应该回答'is_regexp(seq(a,b,42,qwe))'这样的查询。所以我认为我必须使用'(= ..)/ 2'这样的东西,即使我的教授从未谈论过它。或者在这种情况下是不同的? – Matteo

+0

Ops,我错了。他们谈论它,并称之为univ – Matteo