我正在努力创建一个系统来从输入文本中推广规则。我使用reVerb创建了我的初始规则集。例如,使用以下命令[*]:
$ echo "Bananas are an excellent source of potassium." | ./reverb -q | tr '\t' '\n' | cat -n
生成表格的输出:
1 stdin
2 1
3 Bananas
4 are an excellent source of
5 potassium
6 0
7 1
8 1
9 6
10 6
11 7
12 0.9999999997341693
13 Bananas are an excellent source of potassium .
14 NNS VBP DT JJ NN IN NN .
15 B-NP B-VP B-NP I-NP I-NP I-NP I-NP O
16 bananas
17 be source of
18 potassium
我目前正在将输出汇总到一个文件,其中包含前面的空格和数字,如上所示。
我真正追求的只是最后的简单规则,即第16,17和16行。 18.我一直在尝试创建一个脚本来提取该组件,并以Prolog子句的形式将其放到一个新文件中,即be source of(banans, potassium).
这可行吗? Prolog规则可以包含这样的空格吗?
我认为我已经锁定从reVerb获取所有输出,那么提取所需组件的最佳方法是什么?使用Perl脚本?或者也许是sed?
*后来我打算用更大的输入文件替换它,而不是单个句子。
答案 0 :(得分:3)
这似乎很浪费。为什么不按原样保留标签,并使用:
$ echo "Bananas are an excellent source of potassium." \
| ./reverb -q | cut --fields=16,17,18
是的,你可以在Prolog中有这样的规则。请参阅answer by @mat。我想你需要先知道一些Prolog,我猜。
然而,更容易使字符串成为谓词的有效名称:
be_source_of
带下划线而不是空格'be source of'
包含空格,并用单引号括起来。您可以使用awk
来完成三个字段所需的操作。例如,请参阅printf
中的awk
命令。或者,您可以直接从Prolog再次解析它。我觉得两者都超出了你当前问题的范围。
答案 1 :(得分:1)
sed -n 'N;N
:cycle
$!{N
D
b cycle
}
s/\(.*\)\n\(.*\)\n\(.*\)/\2 (\1,\3)/p' YourFile
如果数字在输出中而不仅仅是参考,则更改上一个sed操作
s/\^ *[0-9]\{1,\} \{1,\}\(.*\)\n *[0-9]\{1,\} \{1,\}\(.*\)\n *[0-9]\{1,\} \{1,\}\(.*\)/\2 (\1,\3)/p
假设最后3行是你的"规则#34;
的来源答案 2 :(得分:1)
关于问题的Prolog部分:
是的,Prolog事实可以包含这样的空格,并且存在合适的运算符声明。
例如:
:- op(700, fx, be).
:- op(650, fx, source).
:- op(600, fx, of).
示例查询及其结果,让您查看使用以下语法创建的术语的形状:
?- write_canonical(be source of(a, b)).
be(source(of(a,b))).
因此,使用这些运算符声明,如下所示:
be source of(a, b).
与陈述完全相同:
be(source(of(a,b)).
根据用例和其他定义,创建此类事实甚至可能是有利的(即be/1
而不是source_of/2
形式的事实。如果这是您需要的唯一事实,您只需写下:
source_of(a, b).
这不会创建冗余包装器并且更易于使用。
或者,正如Boris建议的那样,您可以使用'be source of'/2
中的单引号。