带参数的Prolog-DCG

带参数的Prolog-DCG,prolog,arguments,dcg,Prolog,Arguments,Dcg,我不知道如何使用参数处理DCG。假设我们想用DCG来代表父母及其子女,我们可以说: father --> [Peter]. mother --> [Isabel]. child --> [Guido]. child --> [Claudia]. verb --> [is]. relation --> [father, of]. relation --> [mothter, of]. s --> father, verb, relation,

我不知道如何使用参数处理DCG。假设我们想用DCG来代表父母及其子女,我们可以说:

father --> [Peter].
mother --> [Isabel].

child --> [Guido].
child --> [Claudia].

verb --> [is].
relation --> [father, of].
relation --> [mothter, of].

s --> father, verb, relation, child.
s --> mother, verb, relation, child.
然后可以通过以下方式进行查询:
?-s([Peter,is,father,of,Guido])。
返回
true


我如何在DCG上使用参数,可以说添加参数很容易,如果您按照下面的方法进行操作,但无法使查询工作,我也不会感到惊讶。实现这一点的诀窍是,当DCG被转换为Prolog时,通过向每个谓词线程化两个额外的参数,知道DCG被转换为常规Prolog。它们可以随意命名,我个人更喜欢将状态命名为
S0
S
,但如果它们有更具体的含义,请更改它们

同样值得注意的是,在以下代码中,由于名称以大写字母开头,它们需要是原子,而不是使用
peter
,原子以
'
结尾,例如
'peter'

father('Peter') --> ['Peter']. 
mother('Isabel') --> ['Isabel'].

child('Guido') --> ['Guido']. 
child('Claudia') --> ['Claudia'].

verb(is) --> [is]. 
relation('father of') --> [father, of]. 
relation('mother of') --> [mother, of].

s --> father(Father), verb(Verb), relation(Relation), child(Child). 
s --> mother(Father), verb(Verb), relation(Relation), child(Child).
现在检查您的第一个查询:

?- s([Peter, is, father, of, Guido], []).
true ;
true ;
true ;
true.
对于阅读本文的其他人来说,这是相同的答案,没有添加参数。如果您有疑问,请检查它

现在是使用添加的隐藏参数的父查询

?- father(Father,S0,S).
Father = 'Peter',
S0 = [_5662|S].
你也可以这样做

?- father(Father,_,_).
Father = 'Peter'.

旁注:

更好的方法是使用,或者,我说使用,而不是回答,因为你问的问题是如何查询子句父,而不是使用它来解析数据或使用短语谓词

test :-
    DCG = father(Father),
    phrase(DCG,Input,Rest),
    format('Father: ~w~n',[Father]).

?- test.
Father: Peter
true.


这些也起作用

?- s(S0,S).
S0 = ['Peter', is, father, of, 'Guido'|S] ;
S0 = ['Peter', is, father, of, 'Claudia'|S] ;
S0 = ['Peter', is, mother, of, 'Guido'|S] ;
S0 = ['Peter', is, mother, of, 'Claudia'|S] ;
S0 = ['Isabel', is, father, of, 'Guido'|S] ;
S0 = ['Isabel', is, father, of, 'Claudia'|S] ;
S0 = ['Isabel', is, mother, of, 'Guido'|S] ;
S0 = ['Isabel', is, mother, of, 'Claudia'|S].

?- s(S0,[]).
S0 = ['Peter', is, father, of, 'Guido'] ;
S0 = ['Peter', is, father, of, 'Claudia'] ;
S0 = ['Peter', is, mother, of, 'Guido'] ;
S0 = ['Peter', is, mother, of, 'Claudia'] ;
S0 = ['Isabel', is, father, of, 'Guido'] ;
S0 = ['Isabel', is, father, of, 'Claudia'] ;
S0 = ['Isabel', is, mother, of, 'Guido'] ;
S0 = ['Isabel', is, mother, of, 'Claudia'].

?- phrase(s,S,[]).
S = ['Peter', is, father, of, 'Guido'] ;
S = ['Peter', is, father, of, 'Claudia'] ;
S = ['Peter', is, mother, of, 'Guido'] ;
S = ['Peter', is, mother, of, 'Claudia'] ;
S = ['Isabel', is, father, of, 'Guido'] ;
S = ['Isabel', is, father, of, 'Claudia'] ;
S = ['Isabel', is, mother, of, 'Guido'] ;
S = ['Isabel', is, mother, of, 'Claudia'].

如果使用,您可以看到DCG转换为Prolog,这将显示通过谓词线程化的两个额外参数

?- listing.  

child('Guido', ['Guido'|A], A).
child('Claudia', ['Claudia'|A], A).

verb(is, [is|A], A).

relation('father of', [father, of|A], A).
relation('mother of', [mother, of|A], A).

father('Peter', ['Peter'|A], A).
mother('Isabel', ['Isabel'|A], A).

s(A, B) :-
    father(Father, A, C),
    verb(Verb, C, D),
    relation(Relation, D, E),
    child(Child, E, B).
s(A, B) :-
    mother(Father, A, C),
    verb(Verb, C, D),
    relation(Relation, D, E),
    child(Child, E, B).

test :-
    DCG=father(Father),
    phrase(DCG, Input, Rest),
    format('Father: ~w~n', [Father]).

true.

添加参数很容易,如果您按照下面的操作进行,但无法使查询工作,我也不会感到惊讶。实现这一点的诀窍是,当DCG被转换为Prolog时,通过向每个谓词线程化两个额外的参数,知道DCG被转换为常规Prolog。它们可以随意命名,我个人更喜欢将状态命名为
S0
S
,但如果它们有更具体的含义,请更改它们

同样值得注意的是,在以下代码中,由于名称以大写字母开头,它们需要是原子,而不是使用
peter
,原子以
'
结尾,例如
'peter'

father('Peter') --> ['Peter']. 
mother('Isabel') --> ['Isabel'].

child('Guido') --> ['Guido']. 
child('Claudia') --> ['Claudia'].

verb(is) --> [is]. 
relation('father of') --> [father, of]. 
relation('mother of') --> [mother, of].

s --> father(Father), verb(Verb), relation(Relation), child(Child). 
s --> mother(Father), verb(Verb), relation(Relation), child(Child).
现在检查您的第一个查询:

?- s([Peter, is, father, of, Guido], []).
true ;
true ;
true ;
true.
对于阅读本文的其他人来说,这是相同的答案,没有添加参数。如果您有疑问,请检查它

现在是使用添加的隐藏参数的父查询

?- father(Father,S0,S).
Father = 'Peter',
S0 = [_5662|S].
你也可以这样做

?- father(Father,_,_).
Father = 'Peter'.

旁注:

更好的方法是使用,或者,我说使用,而不是回答,因为你问的问题是如何查询子句父,而不是使用它来解析数据或使用短语谓词

test :-
    DCG = father(Father),
    phrase(DCG,Input,Rest),
    format('Father: ~w~n',[Father]).

?- test.
Father: Peter
true.


这些也起作用

?- s(S0,S).
S0 = ['Peter', is, father, of, 'Guido'|S] ;
S0 = ['Peter', is, father, of, 'Claudia'|S] ;
S0 = ['Peter', is, mother, of, 'Guido'|S] ;
S0 = ['Peter', is, mother, of, 'Claudia'|S] ;
S0 = ['Isabel', is, father, of, 'Guido'|S] ;
S0 = ['Isabel', is, father, of, 'Claudia'|S] ;
S0 = ['Isabel', is, mother, of, 'Guido'|S] ;
S0 = ['Isabel', is, mother, of, 'Claudia'|S].

?- s(S0,[]).
S0 = ['Peter', is, father, of, 'Guido'] ;
S0 = ['Peter', is, father, of, 'Claudia'] ;
S0 = ['Peter', is, mother, of, 'Guido'] ;
S0 = ['Peter', is, mother, of, 'Claudia'] ;
S0 = ['Isabel', is, father, of, 'Guido'] ;
S0 = ['Isabel', is, father, of, 'Claudia'] ;
S0 = ['Isabel', is, mother, of, 'Guido'] ;
S0 = ['Isabel', is, mother, of, 'Claudia'].

?- phrase(s,S,[]).
S = ['Peter', is, father, of, 'Guido'] ;
S = ['Peter', is, father, of, 'Claudia'] ;
S = ['Peter', is, mother, of, 'Guido'] ;
S = ['Peter', is, mother, of, 'Claudia'] ;
S = ['Isabel', is, father, of, 'Guido'] ;
S = ['Isabel', is, father, of, 'Claudia'] ;
S = ['Isabel', is, mother, of, 'Guido'] ;
S = ['Isabel', is, mother, of, 'Claudia'].

如果使用,您可以看到DCG转换为Prolog,这将显示通过谓词线程化的两个额外参数

?- listing.  

child('Guido', ['Guido'|A], A).
child('Claudia', ['Claudia'|A], A).

verb(is, [is|A], A).

relation('father of', [father, of|A], A).
relation('mother of', [mother, of|A], A).

father('Peter', ['Peter'|A], A).
mother('Isabel', ['Isabel'|A], A).

s(A, B) :-
    father(Father, A, C),
    verb(Verb, C, D),
    relation(Relation, D, E),
    child(Child, E, B).
s(A, B) :-
    mother(Father, A, C),
    verb(Verb, C, D),
    relation(Relation, D, E),
    child(Child, E, B).

test :-
    DCG=father(Father),
    phrase(DCG, Input, Rest),
    format('Father: ~w~n', [Father]).

true.

仍然有一些
'
引号缺少
s/[Peter]/[Peter']/
旁注:我使用SWI-Prolog。在这里,上面使用的变量将给出有关单例变量的警告。一个好的做法是编写
\u Peter
而不是
Peter
,这样可以解决警告问题。应该认真对待单例警告-在这种情况下,这意味着无法在某个时候实例化此变量。换句话说,对彼得的任何替代都是可以的。您可以通过检查
短语[marie_antoinette,is,mother,of,john_lennon])
成功。如果你指的是atom
Peter
你必须把它放在引号中
'Peter'
。仍然有一些
'
引号缺少
s/[Peter]/[Peter']/
旁注:我使用的是SWI Prolog。在这里,上面使用的变量将给出有关单例变量的警告。一个好的做法是编写
\u Peter
而不是
Peter
,这样可以解决警告问题。应该认真对待单例警告-在这种情况下,这意味着无法在某个时候实例化此变量。换句话说,对彼得的任何替代都是可以的。您可以通过检查
短语[marie_antoinette,is,mother,of,john_lennon])
成功。如果你指的是一个原子
Peter
,你必须把它放在引号中
“Peter”