Prolog:根据DCG从列表中生成一个术语

时间:2016-01-07 22:23:05

标签: list prolog dcg parse-tree

我有以下DCG:

from django.db import models
from django.core.urlresolvers import reverse
from django_markdown.models import MarkdownField


class EntryQuerySet(models.QuerySet):
    def published(self):
        return self.filter(publish=True)


class Tag(models.Model):
    slug = models.SlugField(max_length=200, unique=True)

    def __str__(self):
        return self.slug


class Entry(models.Model):
    title = models.CharField(max_length=200)
    body = MarkdownField()
    slug = models.SlugField(max_length=200, unique=True)
    publish = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    objects = EntryQuerySet.as_manager()
    tags = models.ManyToManyField(Tag)

    def get_absolute_url(self):
        return reverse("post_detail", kwargs={"slug": self.slug})

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = "Blog Entry"
        verbose_name_plural = "Blog Entries"
        ordering = ["-created"]

我可以验证s --> np, vp. np --> det, n. vp --> v. det --> [the]. n --> [cat]. v --> [sleeps]. 之类的句子,我会收到回复" s([the,cat,sleeps], [])"。

但我需要这句话作为一个术语,例如:yes

如何从列表s(np(det(the),n(cat)),vp(v(sleeps)))中生成该字词?

1 个答案:

答案 0 :(得分:3)

您只需要扩展当前的DCG以包含一个定义您所追求的术语的参数:

s(s(NP, VP))  -->  np(NP), vp(VP).

np(np(Det, Noun))  -->  det(Det), n(Noun).
vp(vp(Verb))  -->  v(Verb).

det(det(the))  -->  [the].

n(n(cat))  -->  [cat].

v(v(sleeps))  -->  [sleeps].

然后使用phrase调用它:

| ?- phrase(s(X), [the, cat, sleeps]).
X = s(np(det(the),n(cat)),vp(v(sleeps)))

代码可能看起来有点令人困惑,因为您想要的术语名称恰好与您选择的谓词名称相匹配。重命名谓词,使其更清晰:

sentence(s(NP, VP))  -->  noun_part(NP), verb_part(VP).

noun_part(np(Det, Noun))  -->  determiner(Det), noun(Noun).
verb_part(vp(Verb))  -->  verb(Verb).

determiner(det(the))  -->  [the].

noun(n(cat))  -->  [cat].

verb(v(sleeps))  -->  [sleeps].

| ?- phrase(sentence(X), [the, cat, sleeps]).
X = s(np(det(the),n(cat)),vp(v(sleeps)))

如果你想通过包括更多名词来扩充它,你可以这样做:

noun(n(N)) --> [N], { member(N, [cat, dog]) }.

使用常规查询结果:

| ?- phrase(sentence(X), L).

L = [the,cat,sleeps]
X = s(np(det(the),n(cat)),vp(v(sleeps))) ? a

L = [the,dog,sleeps]
X = s(np(det(the),n(dog)),vp(v(sleeps)))

(1 ms) yes
| ?-