();
34 |
35 | private SyntaxBoxes(boolean showS, boolean showVP, boolean showNP) {
36 | this.showS = showS;
37 | this.showVP = showVP;
38 | this.showNP = showNP;
39 | }
40 |
41 | /**
42 | * This method takes the syntax tree of a parsing result and generates the HTML representation of the
43 | * syntax boxes showing all three types of boxes.
44 | *
45 | * @param parserResult The parsing result.
46 | * @return The HTML representation of the syntax boxes.
47 | */
48 | public static String getBoxesHtml(ACEParserResult parserResult) {
49 | return getBoxesHtml(parserResult, true, true, true);
50 | }
51 |
52 | /**
53 | * This method takes the syntax tree of a parsing result and generates the HTML representation of the
54 | * syntax boxes. The three types of boxes can individually be switched on or off.
55 | *
56 | * @param parserResult The parsing result.
57 | * @param showS true if the gray boxes for (subordinated) sentences should be shown.
58 | * @param showVP true if the yellow boxes for verb phrases should be shown.
59 | * @param showNP true if the blue boxes for noun phrases should be shown.
60 | * @return The HTML representation of the syntax boxes.
61 | */
62 | public static String getBoxesHtml(ACEParserResult parserResult, boolean showS, boolean showVP, boolean showNP) {
63 | String s = new SyntaxBoxes(showS, showVP, showNP).createBoxes(parserResult.get(OutputType.SYNTAX));
64 | String c = s.replace("'", "").replace("{", "").replace("}", "").replace("_that_", "that");
65 | String r =
66 | "\n" +
67 | "\n\n" +
72 | "\n" +
73 | c +
74 | "
\n" +
75 | "
";
76 | // This style-element is actually not allowed at this position, but it works in all tested browsers.
77 |
78 | return r;
79 | }
80 |
81 | private String createBoxes(String p) {
82 | if (p.length() == 0) {
83 | return "";
84 | } else if (p.startsWith(" ")) {
85 | return createBoxes(p.substring(1));
86 | } else if (p.startsWith(",")) {
87 | return createBoxes(p.substring(1));
88 | } else if (p.startsWith("[[")) {
89 | stack.push("");
90 | return createBoxes(p.substring(1));
91 | } else if (p.startsWith("[]")) {
92 | return createBoxes(p.substring(2));
93 | } else if (p.startsWith("[")) {
94 | if (showS) {
95 | for (String s : sNodes) {
96 | if (p.startsWith("[" + s + ",")) {
97 | stack.push("");
98 | return "" + createBoxes(p.substring(s.length()+2));
99 | }
100 | }
101 | }
102 | if (showVP) {
103 | for (String s : vpNodes) {
104 | if (p.startsWith("[" + s + ",")) {
105 | stack.push("
| ");
106 | return "" + createBoxes(p.substring(s.length()+2));
107 | }
108 | }
109 | }
110 | if (showNP) {
111 | for (String s : npNodes) {
112 | if (p.startsWith("[" + s + ",")) {
113 | stack.push("
| ");
114 | return "" + createBoxes(p.substring(s.length()+2));
115 | }
116 | }
117 | }
118 | if (p.indexOf(",") > 0) {
119 | stack.push("");
120 | return createBoxes(p.substring(p.indexOf(",")+1));
121 | }
122 | } else if (p.startsWith("]")) {
123 | String t = stack.pop();
124 | return t + createBoxes(p.substring(1));
125 | } else if (p.indexOf("]") > 0) {
126 | int ci = p.indexOf(",");
127 | int bi = p.indexOf("]");
128 | int i = bi;
129 | if (ci > 0 && ci < bi) i = ci;
130 | String a = p.substring(0, i);
131 | String b = p.substring(i);
132 | return "" + a + " | " + createBoxes(b);
133 | }
134 | return " ERROR(" + p + ")ERROR ";
135 | }
136 |
137 | }
138 |
--------------------------------------------------------------------------------
/java/src/main/java/ch/uzh/ifi/attempto/ape/package-info.java:
--------------------------------------------------------------------------------
1 | // This file is part of the Attempto Parsing Engine (APE).
2 | // Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | //
4 | // The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | // under the terms of the GNU Lesser General Public License as published by the Free Software
6 | // Foundation, either version 3 of the License, or (at your option) any later version.
7 | //
8 | // The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | // PURPOSE. See the GNU Lesser General Public License for more details.
11 | //
12 | // You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | // Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 | /**
16 | * This package provides interfaces to the Attempto Parsing Engine (APE).
17 | *
18 | *
19 | * @author Kaarel Kaljurand
20 | * @author Tobias Kuhn
21 | */
22 | package ch.uzh.ifi.attempto.ape;
23 |
--------------------------------------------------------------------------------
/java/src/main/java/overview.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Java Interface for APE
6 |
7 |
8 |
9 | The Java Interface for APE contains interfaces to the Attempto Parsing Engine (APE)
10 | developed within the Attempto project.
11 | The Java Interface for APE is free software licensed under the
12 | GNU Lesser General Public Licence
13 | (LGPL). It is hosted on GitHub.
14 |
15 |
16 |
--------------------------------------------------------------------------------
/java/src/test/java/ch/uzh/ifi/attempto/ape/APELocalTest.java:
--------------------------------------------------------------------------------
1 | package ch.uzh.ifi.attempto.ape;
2 |
3 | import org.junit.BeforeClass;
4 | import org.junit.Test;
5 |
6 | import static org.junit.Assert.assertEquals;
7 |
8 | public class APELocalTest extends Testcase {
9 |
10 | private static ACEParser parser;
11 |
12 | @BeforeClass public static void setUp() {
13 | parser = getApeLocal();
14 | }
15 |
16 | private static APELocal getApeLocal() {
17 | APELocal.init("../ape.exe", true);
18 | return APELocal.getInstance();
19 | }
20 |
21 | @Test
22 | public void testDRS() throws ACEParserException {
23 | APELocal apeLocal = getApeLocal();
24 | apeLocal.setGuessingEnabled(true);
25 | String drs = apeLocal.getSoloOutput(ACETEXT, OutputType.DRS);
26 | assertEquals("DRS mismatch", ACETEXT_DRS, drs);
27 | }
28 |
29 | @Test
30 | public final void testGetSoloOutput() throws ACEParserException {
31 | parser.setGuessingEnabled(false);
32 | String response = null;
33 | response = parser.getSoloOutput(Testcase.ACETEXT1, OutputType.PARAPHRASE1);
34 |
35 | assertEquals(Testcase.ACETEXT1_CORE_ACE, response.trim());
36 | }
37 | @Test
38 | public final void testGetMultiOutput() {
39 | ACEParserResult result = parser.getMultiOutput(Testcase.ACETEXT, OutputType.DRS, OutputType.TPTP);
40 | assertEquals(Testcase.ACETEXT_DRS, result.get(OutputType.DRS));
41 | assertEquals(Testcase.ACETEXT_TPTP, result.get(OutputType.TPTP));
42 | }
43 | @Test
44 | public final void testGetMultiOutput3() {
45 | parser.setGuessingEnabled(true);
46 | ACEParserResult response = parser.getMultiOutput(Testcase.ACETEXT, OutputType.DRSPP);
47 | assertEquals(Testcase.ACETEXT_DRSPP, response.get(OutputType.DRSPP).trim());
48 | }
49 |
50 | }
--------------------------------------------------------------------------------
/java/src/test/java/ch/uzh/ifi/attempto/ape/APESocketTest.java:
--------------------------------------------------------------------------------
1 | package ch.uzh.ifi.attempto.ape;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | public class APESocketTest {
8 | private static final ACEParser parser = new APESocket(5000);
9 |
10 | @Test
11 | public final void testGetSoloOutput() {
12 | parser.setGuessingEnabled(false);
13 | String response = null;
14 | try {
15 | response = parser.getSoloOutput(Testcase.ACETEXT1, OutputType.PARAPHRASE1);
16 | } catch (ACEParserException e) {
17 | fail(e.getMessageContainer().toString());
18 | }
19 | assertEquals(Testcase.ACETEXT1_CORE_ACE, response.trim());
20 | }
21 |
22 |
23 | @Test
24 | public final void testGetMultiOutput() {
25 | //Lexicon lexicon = new Lexicon();
26 | //lexicon.addEntry(LexiconEntry.createNounSgEntry("dooog", "DOOOG", Gender.NEUTRAL));
27 | parser.setGuessingEnabled(true);
28 | ACEParserResult response = parser.getMultiOutput(Testcase.ACETEXT2, OutputType.PARAPHRASE1);
29 | assertEquals(Testcase.ACETEXT2_CORE_ACE, response.get(OutputType.PARAPHRASE1).trim());
30 | }
31 |
32 |
33 | @Test
34 | public final void testGetMultiOutput3() {
35 | parser.setGuessingEnabled(true);
36 | ACEParserResult response = parser.getMultiOutput(Testcase.ACETEXT, OutputType.DRSPP);
37 | assertEquals(Testcase.ACETEXT_DRSPP, response.get(OutputType.DRSPP).trim());
38 | }
39 | }
--------------------------------------------------------------------------------
/java/src/test/java/ch/uzh/ifi/attempto/ape/LexiconEntryTest.java:
--------------------------------------------------------------------------------
1 | package ch.uzh.ifi.attempto.ape;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | public class LexiconEntryTest {
8 |
9 | @Test
10 | public final void testCreateAdvEntry() {
11 | LexiconEntry le = LexiconEntry.createAdvEntry(Testcase.WORD, Testcase.SYMBOL);
12 | assertEquals(le.toString(), Testcase.ENTRY);
13 | }
14 |
15 | @Test
16 | public final void testCreateAdvEntryEquals() {
17 | LexiconEntry le1 = LexiconEntry.createAdvEntry(Testcase.WORD, Testcase.SYMBOL);
18 | LexiconEntry le2 = LexiconEntry.createAdvEntry(Testcase.WORD, Testcase.SYMBOL);
19 | assertEquals(le1, le2);
20 | }
21 |
22 | @Test
23 | public final void testCreateAdvEntryHashCode() {
24 | LexiconEntry le1 = LexiconEntry.createAdvEntry(Testcase.WORD, Testcase.SYMBOL);
25 | LexiconEntry le2 = LexiconEntry.createAdvEntry(Testcase.WORD, Testcase.SYMBOL);
26 | assertEquals(le1.hashCode(), le2.hashCode());
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/java/src/test/java/ch/uzh/ifi/attempto/ape/Testcase.java:
--------------------------------------------------------------------------------
1 | package ch.uzh.ifi.attempto.ape;
2 |
3 | public class Testcase {
4 |
5 | public static final String ACETEXT = "John waits.";
6 | public static final String ACETEXT_DRSPP = "[A]\npredicate(A,wait,named(John))-1/2";
7 | public static final String ACETEXT_DRS = "drs([A],[predicate(A,wait,named('John'))-1/2])";
8 | public static final String ACETEXT_TPTP = "fof(f1, axiom, (\n? [A] : (predicate1(A,wait,'John')))).";
9 |
10 | public static final String ACETEXT1 = "Every dog's friend is an animal.";
11 | public static final String ACETEXT1_CORE_ACE = "If there is a friend X1 of a dog then the friend X1 is an animal.";
12 |
13 | public static final String ACETEXT2 = "Every dooog's friend is an animal.";
14 | public static final String ACETEXT2_CORE_ACE = "If there is a friend X1 of a n:dooog then the friend X1 is an animal.";
15 |
16 | public static final String ACETEXT3 = "John|pn_sg|John_PN| |tv_finsg|buy_V2 everything that | isn't a present|noun_sg|present_N .";
17 | public static final String ACETEXT3_OWLFSS = "'Ontology'(test,['SubClassOf'('ObjectComplementOf'('':present_N),'ObjectSomeValuesFrom'('ObjectInverseOf'('':buy_V2),'ObjectOneOf'(['':'John_PN'])))])";
18 |
19 | public static final String ACETEXT4 =
20 | "the Åland_islands|pndef_pl|Åland_islands_PN|neutr are larger-than|adj_tr|larger-than_A2|than the Black_Forest|pndef_sg|Black_Forest_PN|neutr .";
21 | public static final String ACETEXT4_OWLFSS =
22 | "'Ontology'(test,['ObjectPropertyAssertion'('':'larger-than_A2','':'Åland_islands_PN','':'Black_Forest_PN')])";
23 |
24 | public static final String WORD = "multi word";
25 | public static final String ENTRY= "adv('multi word', 'sym(multi word)')";
26 | public static final String SYMBOL = "sym(multi word)";
27 |
28 | }
--------------------------------------------------------------------------------
/make_exe.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | del ape.exe
3 | swipl -O -F none -g "working_directory(_, 'prolog/parser'), [fit_to_plp], halt." -t halt & swipl -O -f ape.pl -g "qsave_program('ape.exe', [goal(ape), toplevel(halt)])." -t halt
4 | if exist ape.exe goto success
5 | echo Could not find the SWI Prolog command.
6 | echo Make sure that the location of the SWI Prolog binaries is in the PATH variable.
7 | goto end
8 | :success
9 | echo ape.exe created.
10 | :end
11 |
--------------------------------------------------------------------------------
/pack.pl:
--------------------------------------------------------------------------------
1 | name(ape).
2 | version('6.7.180715').
3 |
4 | % see http://www.swi-prolog.org/howto/PackInfo.html
5 |
6 | download('https://github.com/Attempto/APE/releases/*.zip').
7 |
8 | title('Parser for Attempto Controlled English (ACE)').
9 | author('Kaarel Kaljurand','kaljurand@gmail.com').
10 | author('Norbert E. Fuchs','fuchs@ifi.uzh.ch').
11 | author('Tobias Kuhn','kuhntobias@gmail.com').
12 |
13 | home('https://github.com/Attempto/APE').
14 |
--------------------------------------------------------------------------------
/prolog/lexicon/chars.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(chars, [
17 | is_digit/1,
18 | is_capitalized/1,
19 | to_lowercase/2,
20 | is_lowercase/1,
21 | is_uppercase/1,
22 | is_letter/1,
23 | is_unused/1,
24 | is_sentence_end_symbol/1
25 | ]).
26 |
27 | /** Characters
28 |
29 | @author Kaarel Kaljurand
30 | @author Tobias Kuhn
31 | @version 2009-04-29
32 |
33 | Note: SWI has char_type/2 which could be used instead of the predicates defined
34 | in this module. But Sicstus does not seem to have anything similar.
35 | Note also: char_type/2 does not seem to be good because it does not handle anything
36 | beyond ASCII-7.
37 | */
38 |
39 |
40 | %% is_capitalized(+Token:atom) is semidet.
41 | %
42 | % Succeeds if Token starts with an uppercase letter.
43 | %
44 | % @param Token is an ACE token
45 | %
46 | is_capitalized(Token) :-
47 | atom(Token),
48 | atom_codes(Token, [Code | _]),
49 | is_uppercase(Code).
50 |
51 |
52 | %% to_lower_case(+TokenIn, -TokenOut)
53 | %
54 | % Transforms the first character into a lowercase character. The same token is returned if the first
55 | % character is not an uppercase character.
56 | %
57 | to_lowercase(TokenIn, TokenOut) :-
58 | atom(TokenIn),
59 | atom_codes(TokenIn, [Code|CodesRest]),
60 | is_uppercase(Code),
61 | !,
62 | NewCode is Code + 32,
63 | atom_codes(TokenOut, [NewCode|CodesRest]).
64 |
65 | to_lowercase(Token, Token).
66 |
67 |
68 | %% is_digit(+Code:integer) is semidet.
69 | %
70 | % Succeeds if Code corresponds to an ASCII-7 digit symbol.
71 | %
72 | % @param Code is a character code
73 | %
74 | is_digit(Code) :-
75 | 48 =< Code, Code =< 57.
76 |
77 |
78 | %% is_lowercase(+Code:integer) is semidet.
79 | %
80 | % Succeeds iff Code corresponds to a lowercase letter.
81 | %
82 | % @param Code is a character code
83 | %
84 | % We also test lowercase letters from the upper half of latin1.
85 |
86 | % 0x61 -- 0x7a (a..z)
87 | is_lowercase(Code) :-
88 | 97 =< Code, Code =< 122.
89 |
90 | % 0xdf -- 0xf6
91 | is_lowercase(Code) :-
92 | 223 =< Code, Code =< 246.
93 |
94 | % 0xf8 -- 0xff
95 | is_lowercase(Code) :-
96 | 248 =< Code, Code =< 255.
97 |
98 |
99 | %% is_uppercase(+Code:integer) is semidet.
100 | %
101 | % Succeeds iff Code corresponds to an uppercase letter.
102 | %
103 | % @param Code is a character code
104 | %
105 | % We also test uppercase letters from the upper half of latin1.
106 |
107 | % 0x41 -- 0x5a (A..Z)
108 | is_uppercase(Code) :-
109 | 65 =< Code, Code =< 90.
110 |
111 | % 0xc0 -- 0xd6
112 | is_uppercase(Code) :-
113 | 192 =< Code, Code =< 214.
114 |
115 | % 0xd8 -- 0xde
116 | is_uppercase(Code) :-
117 | 216 =< Code, Code =< 222.
118 |
119 |
120 | %% is_letter(+Code:integer) is semidet.
121 | %
122 | % Succeeds iff Code corresponds to a lower- or uppercase letter.
123 | %
124 | % @param Code is a character code
125 | %
126 | is_letter(Code) :-
127 | is_lowercase(Code).
128 |
129 | is_letter(Code) :-
130 | is_uppercase(Code).
131 |
132 |
133 | %% is_unused(+Code:integer) is semidet.
134 | %
135 | % Succeeds iff Code corresponds to an unused character according to
136 | % http://www.w3.org/MarkUp/html3/latin1.html
137 | % In addition: tab, linefeed.
138 | %
139 | % @param Code is a character code
140 | %
141 | is_unused(Code) :-
142 | Code =< 31.
143 |
144 | is_unused(Code) :-
145 | 127 =< Code, Code =< 160.
146 |
147 |
148 | %% is_sentence_end_symbol(?Token:atom) is semidet.
149 | %
150 | % Tests if Token is an ACE sentence end symbol.
151 | %
152 | % @param Token is a token.
153 | %
154 | is_sentence_end_symbol('.').
155 | is_sentence_end_symbol('?').
156 | is_sentence_end_symbol('!').
157 |
--------------------------------------------------------------------------------
/prolog/lexicon/clex.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(clex, [
17 | clex_switch/1, % ?Switch
18 | set_clex_switch/1 % +Switch
19 | ]).
20 | :- use_module(library(error)).
21 |
22 | /** Common Lexicon Interface
23 |
24 | This module contains the predicates for the management of the common lexicon that is compiled into
25 | the executable.
26 |
27 | @author Tobias Kuhn
28 | @version 2008-07-17
29 | */
30 |
31 |
32 | %% clex_file(-ClexFile)
33 | %
34 | % This predicate defines the clex-file that is loaded and compiled into the executable. In order to
35 | % change this, you have to edit the source code and recompile.
36 |
37 | clex_file(clex_lexicon).
38 | %clex_file(clex_lexicon_small).
39 | %clex_file('').
40 |
41 |
42 | % The predicates for the lexicon entries are declared dynamic. In this way, they don't fail if
43 | % no entry exists.
44 |
45 | :- dynamic adv/2.
46 | :- dynamic adv_comp/2.
47 | :- dynamic adv_sup/2.
48 | :- dynamic adj_itr/2.
49 | :- dynamic adj_itr_comp/2.
50 | :- dynamic adj_itr_sup/2.
51 | :- dynamic adj_tr/3.
52 | :- dynamic adj_tr_comp/3.
53 | :- dynamic adj_tr_sup/3.
54 | :- dynamic noun_sg/3.
55 | :- dynamic noun_pl/3.
56 | :- dynamic noun_mass/3.
57 | :- dynamic mn_sg/2.
58 | :- dynamic mn_pl/2.
59 | :- dynamic pn_sg/3.
60 | :- dynamic pn_pl/3.
61 | :- dynamic pndef_sg/3.
62 | :- dynamic pndef_pl/3.
63 | :- dynamic iv_finsg/2.
64 | :- dynamic iv_infpl/2.
65 | :- dynamic tv_finsg/2.
66 | :- dynamic tv_infpl/2.
67 | :- dynamic tv_pp/2.
68 | :- dynamic dv_finsg/3.
69 | :- dynamic dv_infpl/3.
70 | :- dynamic dv_pp/3.
71 | :- dynamic prep/2.
72 |
73 |
74 | % Load the clex-file
75 | :- style_check(-discontiguous).
76 | :- clex_file(ClexFile), ( ClexFile == '' ; load_files(ClexFile, [encoding(utf8)]) ).
77 | :- style_check(+discontiguous).
78 |
79 |
80 | %% clex_switch(?Switch)
81 | %
82 | % This predicate returns 'on' if clex is switched on, or 'off' otherwise.
83 |
84 | :- dynamic(clex_switch/1).
85 |
86 | clex_switch(on).
87 |
88 |
89 | %% set_clex_switch(+Switch)
90 | %
91 | % This predicate switches clex on (Switch='on') or off (Switch='off').
92 |
93 | set_clex_switch(Switch) :-
94 | must_be(oneof([on,off]), Switch),
95 | retractall(clex_switch(_)),
96 | assert(clex_switch(Switch)).
97 |
--------------------------------------------------------------------------------
/prolog/lexicon/illegalwords.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(illegalwords, [
17 | is_illegalword/2 % +IllegalWord:atom, -ErrorMessage
18 | ]).
19 |
20 |
21 | %% is_illegalword(+IllegalWord:atom, -ErrorMessage) is semidet.
22 | %
23 | % @param IllegalWord is a word that is not allowed in ACE
24 | % @param ErrorMessage is an error message explaning how to act
25 | %
26 | % This is a simple list of (function) words that are not allowed in ACE.
27 | % BUG: The question remains if one could be allowed to define such words as
28 | % content words and use them anyway. In this case, the error message would be misleading.
29 | % Should we in ACE define a set of words that are not ACE function words and that can not
30 | % be ACE content words either.
31 | %
32 | is_illegalword(any, 'The word \'any\' is not allowed. Did you mean \'every\', \'some\', or \'a\'?').
33 | is_illegalword('Any', 'The word \'Any\' is not allowed. Did you mean \'Every\', \'Some\', or \'A\'?').
34 | is_illegalword(anybody, 'The word \'anybody\' is not allowed. Did you mean \'everybody\' or \'somebody\'?').
35 | is_illegalword('Anybody', 'The word \'Anybody\' is not allowed. Did you mean \'Everybody\' or \'Somebody\'?').
36 | is_illegalword(anything, 'The word \'anything\' is not allowed. Did you mean \'everything\' or \'something\'?').
37 | is_illegalword('Anything', 'The word \'Anything\' is not allowed. Did you mean \'Everything\' or \'Something\'?').
38 |
39 | is_illegalword(this, 'The word \'this\' is not allowed. Did you mean \'the\'?').
40 | is_illegalword('This', 'The word \'This\' is not allowed. Did you mean \'The\'?').
41 | is_illegalword(these, 'The word \'these\' is not allowed. Did you mean \'the\'?').
42 | is_illegalword('These', 'The word \'These\' is not allowed. Did you mean \'The\'?').
43 |
44 | is_illegalword(Pronoun, ErrorText) :-
45 | is_illegal_pronoun(Pronoun),
46 | with_output_to(atom(ErrorText), format("The pronoun \'~w\' is not allowed. Use only third person singular or plural.", [Pronoun])).
47 |
48 |
49 | %% is_illegal_pronoun(+Pronoun:atom) is semidet.
50 | %
51 | % @param Pronoun is an English pronoun
52 | %
53 | % Succeeds if Pronoun is not allowed in ACE.
54 | %
55 | is_illegal_pronoun('I').
56 | is_illegal_pronoun(me).
57 | is_illegal_pronoun('Me').
58 | is_illegal_pronoun(my).
59 | is_illegal_pronoun('My').
60 | is_illegal_pronoun(mine).
61 | is_illegal_pronoun('Mine').
62 | is_illegal_pronoun(yours).
63 | is_illegal_pronoun('Yours').
64 | is_illegal_pronoun(we).
65 | is_illegal_pronoun('We').
66 | is_illegal_pronoun(us).
67 | is_illegal_pronoun('Us').
68 | is_illegal_pronoun(our).
69 | is_illegal_pronoun('Our').
70 | is_illegal_pronoun(ours).
71 | is_illegal_pronoun('Ours').
72 | is_illegal_pronoun('Theirs').
73 |
--------------------------------------------------------------------------------
/prolog/lexicon/is_in_lexicon.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(is_in_lexicon, [
17 | is_in_lexicon/1,
18 | is_functionword/1,
19 | is_contentword/1
20 | ]).
21 |
22 |
23 | /** Is a token in the lexicon?
24 |
25 | @author Kaarel Kaljurand
26 | @author Tobias Kuhn
27 | @version 2007-12-06
28 |
29 | */
30 |
31 | :- use_module(functionwords).
32 | :- use_module(lexicon_interface).
33 | :- use_module(illegalwords).
34 | :- use_module(chars).
35 |
36 |
37 | %% is_in_lexicon(+WordForm:atom) is semidet.
38 | %
39 | % @param WordForm is an ACE wordform
40 | %
41 | % Succeeds if WordForm is among the ACE words, possibly
42 | % one of the illegal words like `any' or `this'.
43 | %
44 | is_in_lexicon(WordForm) :-
45 | (
46 | is_functionword(WordForm)
47 | ;
48 | is_contentword(WordForm)
49 | ;
50 | is_illegalword(WordForm, _)
51 | ).
52 |
53 |
54 | %% is_functionword(+WordForm:atom) is nondet.
55 | %
56 | % @param WordForm is an ACE wordform
57 | %
58 | % Succeeds if WordForm is among the ACE function words.
59 | %
60 | is_functionword(WordForm) :-
61 | (
62 | functionwords:rawnumber_number(WordForm, _)
63 | ;
64 | functionwords:functionword(WordForm)
65 | ;
66 | functionwords:variable(WordForm)
67 | ).
68 |
69 |
70 | %% is_contentword(+WordForm:atom) is nondet.
71 | %
72 | % @param WordForm is an ACE wordform
73 | %
74 | % Succeeds if WordForm is in the content word lexicon.
75 | %
76 | is_contentword(WordForm) :-
77 | (
78 | adv(WordForm, _)
79 | ;
80 | adv_comp(WordForm, _)
81 | ;
82 | adv_sup(WordForm, _)
83 | ;
84 | adj_itr(WordForm, _)
85 | ;
86 | adj_itr_comp(WordForm, _)
87 | ;
88 | adj_itr_sup(WordForm, _)
89 | ;
90 | adj_tr(WordForm, _, _)
91 | ;
92 | adj_tr_comp(WordForm, _, _)
93 | ;
94 | adj_tr_sup(WordForm, _, _)
95 | ;
96 | noun_sg(WordForm, _, _)
97 | ;
98 | noun_pl(WordForm, _, _)
99 | ;
100 | noun_mass(WordForm, _, _)
101 | ;
102 | mn_sg(WordForm, _)
103 | ;
104 | mn_pl(WordForm, _)
105 | ;
106 | pn_sg(WordForm, _, _)
107 | ;
108 | pn_pl(WordForm, _, _)
109 | ;
110 | pndef_sg(WordForm, _, _)
111 | ;
112 | pndef_pl(WordForm, _, _)
113 | ;
114 | iv_finsg(WordForm, _)
115 | ;
116 | iv_infpl(WordForm, _)
117 | ;
118 | tv_finsg(WordForm, _)
119 | ;
120 | tv_infpl(WordForm, _)
121 | ;
122 | tv_pp(WordForm, _)
123 | ;
124 | dv_finsg(WordForm, _, _)
125 | ;
126 | dv_infpl(WordForm, _, _)
127 | ;
128 | dv_pp(WordForm, _, _)
129 | ;
130 | ( chars:to_lowercase(WordForm, WordFormL), prep(WordFormL, _) )
131 | ).
132 |
--------------------------------------------------------------------------------
/prolog/parser/.gitignore:
--------------------------------------------------------------------------------
1 | /*.plp
2 |
--------------------------------------------------------------------------------
/prolog/parser/compile.sh:
--------------------------------------------------------------------------------
1 |
2 | swipl -g "[fit_to_plp], halt."
3 |
--------------------------------------------------------------------------------
/prolog/parser/fit_to_plp.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | %==============================================================================
17 | % Convert fit (i.e. ProFIT) files into plp (i.e. Prolog).
18 | % Kaarel Kaljurand
19 | % Tobias Kuhn
20 | % 2008-03-13
21 | %==============================================================================
22 | % Notes:
23 | % * No interactivity is needed, so you can run it on the commandline, e.g.
24 | % swipl -g "[fit_to_plp], halt."
25 | %==============================================================================
26 |
27 | :- op(400, fy, -).
28 | :- op(400, fy, ~).
29 | :- op(500, xfx, =>).
30 | :- op(500, xfx, v).
31 |
32 |
33 | :- [prologfeatures].
34 |
35 | :- resolve_features([sorts, grammar, grammar_functionwords, grammar_contentwords]).
36 |
--------------------------------------------------------------------------------
/prolog/parser/sentence_failure.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(sentence_failure, [
17 | get_all_sentence_errors/2, % +SentenceTokens, -ErrorTextList
18 | get_sentence_error_text/2 % +SentenceTokens, -ErrorText
19 | ]).
20 |
21 | :- use_module('../lexicon/lexicon_interface').
22 |
23 | :- use_module('../lexicon/chars', [
24 | is_capitalized/1
25 | ]).
26 |
27 | :- use_module('../lexicon/is_in_lexicon', [
28 | is_functionword/1
29 | ]).
30 |
31 | :- use_module('../lexicon/illegalwords').
32 |
33 | :- style_check(-singleton).
34 | :- style_check(-discontiguous).
35 | :- use_module('grammar.plp').
36 | :- style_check(+discontiguous).
37 | :- style_check(+singleton).
38 |
39 | /** Sentence Failure
40 |
41 | @author Norbert E. Fuchs
42 | @author Tobias Kuhn
43 | @author Kaarel Kaljurand
44 | @version 2011-07-18
45 | */
46 |
47 | %% get_all_sentence_errors(+SentenceTokens:list, -ErrorTextList:list) is det.
48 | %
49 | % @param SentenceTokens is a list of tokens in the sentence
50 | % @param ErrorTextList is a list of error messages
51 | %
52 | get_all_sentence_errors(SentenceTokens, ErrorTextList) :-
53 | findall(ErrorText, get_sentence_error_text(SentenceTokens, ErrorText), ErrorTextListIntermediate),
54 | % remove duplicate messages
55 | list_to_set(ErrorTextListIntermediate, ErrorTextList).
56 |
57 |
58 | %% get_sentence_error_text(+SentenceTokens:list, -ErrorText:atom) is nondet.
59 | %
60 | % @param SentenceTokens is a list of tokens in the sentence
61 | % @param ErrorText is an error message
62 | %
63 |
64 | % check for illegal words
65 | get_sentence_error_text(SentenceTokens, ErrorText) :-
66 | member(IllegalWord, SentenceTokens),
67 | % BUG: add: \+ is_contentword(IllegalWord)
68 | % because maybe the user defined `any' as a contentword
69 | is_illegalword(IllegalWord, ErrorText).
70 |
71 | % check for repetitions of tokens
72 | get_sentence_error_text(SentenceTokens, ErrorText) :-
73 | append(_, [Token, '<>', Token|_], SentenceTokens),
74 | \+ is_repeatable(Token),
75 | with_output_to(atom(ErrorText), format("Token \'~w\' repeated.", [Token])).
76 |
77 | % check for `there is' + proper name
78 | get_sentence_error_text(SentenceTokens, ErrorText) :-
79 | append(_, [There, is, Token, '<>' | _], SentenceTokens),
80 | (
81 | There = there
82 | ;
83 | There = 'There'
84 | ),
85 | (
86 | Token = the
87 | ;
88 | is_capitalized(Token)
89 | ;
90 | pn_sg(Token, _, _)
91 | ),
92 | with_output_to(atom(ErrorText), format("The construct \'there is\' + \'~w\' is not allowed.", [Token])).
93 |
94 | % check for `there are' + proper name
95 | get_sentence_error_text(SentenceTokens, ErrorText) :-
96 | append(_, [There, are, Token, '<>' | _], SentenceTokens),
97 | (
98 | There = there
99 | ;
100 | There = 'There'
101 | ),
102 | (
103 | Token = the
104 | ;
105 | is_capitalized(Token)
106 | ;
107 | pn_pl(Token, _, _)
108 | ),
109 | with_output_to(atom(ErrorText), format("The construct \'there are\' + \'~w\' is not allowed.", [Token])).
110 |
111 | % check for intransitive verb followed by that-subordination
112 | % Example: John appears that Mary waits. (`appear' is an intransitive verb that is not transitive)
113 | get_sentence_error_text(SentenceTokens, ErrorText) :-
114 | append(_, [Wordform, '<>', that | _], SentenceTokens),
115 | (
116 | iv_finsg(Wordform, Verb)
117 | ;
118 | iv_infpl(Wordform, Verb)
119 | ),
120 | with_output_to(atom(ErrorText), format("The intransitive verb \'~w\' cannot be followed by that-subordination. Use a transitive verb.", [Verb])).
121 |
122 | get_sentence_error_text(SentenceTokens, 'The sentence contains \'then\' but not \'if\'.') :-
123 | member(then, SentenceTokens),
124 | \+ member(if, SentenceTokens),
125 | \+ member('If', SentenceTokens).
126 |
127 | get_sentence_error_text(SentenceTokens, 'The sentence contains \'if\' but not \'then\'.') :-
128 | (
129 | member(if, SentenceTokens)
130 | ;
131 | member('If', SentenceTokens)
132 | ),
133 | \+ member(then, SentenceTokens).
134 |
135 |
136 | % check for illegal use of commas
137 | % Note that this rule does not find all illegal uses of commas, e.g.:
138 | % [...] ... , ... [...]
139 | % {...} ... , ... {...}
140 | % ,!
141 | get_sentence_error_text(SentenceTokens, 'Commas must be immediately followed by \'and\' or \'or\', or must occur at specified positions in lists, sets and commands.') :-
142 | append(Front, [',', NextToken | Tail], SentenceTokens),
143 | % comma not immediately followed by 'and'
144 | NextToken \= and,
145 | % comma not immediately followed by 'or'
146 | NextToken \= or,
147 | % comma not followed by an exclamation mark (command)
148 | \+ member('!', Tail),
149 | % comma not between [ and ] (list)
150 | \+ (member('[', Front), member(']', Tail)),
151 | % comma not between { and } (set)
152 | \+ (member('{', Front), member('}', Tail)).
153 |
154 |
155 | get_sentence_error_text(_, 'This is the first sentence that was not ACE. The sign <> indicates the position where parsing failed.').
156 |
157 |
158 | %% is_repeatable(?Token) is nondet.
159 | %
160 | % @param Token is an ACE token that can be repeated
161 | %
162 | % Example: ((1+2)-3) = 0.
163 | %
164 | is_repeatable('{').
165 | is_repeatable('}').
166 | is_repeatable('(').
167 | is_repeatable(')').
168 | is_repeatable('[').
169 | is_repeatable(']').
170 | is_repeatable('"').
171 |
--------------------------------------------------------------------------------
/prolog/parser/tokens_to_sentences.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(tokens_to_sentences, [
17 | tokens_to_sentences/2,
18 | tokens_to_paragraphs/2
19 | ]).
20 |
21 |
22 | :- use_module('../lexicon/chars', [
23 | is_sentence_end_symbol/1
24 | ]).
25 |
26 |
27 | /** APE Sentence splitter
28 |
29 | Converts a flat list of tokens into a list of sentences,
30 | each of which is a list of tokens. Sentences end with
31 | one of the three symbols: '.', '?', and '!'.
32 |
33 | For example, the following list of tokens:
34 |
35 | ==
36 | [John, likes, Mary, ., Every, man, owns, a, car, .]
37 | ==
38 |
39 | is converted into the following list of sentences
40 |
41 | ==
42 | [[John, likes, Mary, .], [Every, man, owns, a, car, .]]
43 | ==
44 |
45 | @author Kaarel Kaljurand
46 | @author Tobias Kuhn
47 | @version 2009-05-21
48 |
49 | @bug should we generate error messages here (if token list does not end with ./?/!)
50 |
51 | */
52 |
53 |
54 | %% tokens_to_sentences(+Tokens:list, -Sentences:list) is semidet.
55 | %
56 | % Succeeds if Tokens is a list of ACE sentences, in this case
57 | % the sentences are returned. To succeed the token list must either
58 | % be empty or end with a sentence end symbol. E.g. the following
59 | % token list would cause a failure:
60 | %
61 | %==
62 | %[a, b, c]
63 | %==
64 | %
65 | % @param Tokens is a list of ACE tokens
66 | % @param Sentences is a list of sentences (where a sentence is a list of ACE tokens)
67 | %
68 | tokens_to_sentences([], []).
69 |
70 | tokens_to_sentences(Tokens, [[^|Sentence]|Sentences]) :-
71 | first_sentence(Tokens, Sentence, RestTokens),
72 | tokens_to_sentences(RestTokens, Sentences).
73 |
74 |
75 | %% first_sentence(+Tokens:list, -Sentence:list, -RestTokens:list) is det.
76 | %
77 | % Note that the token list can contain variables (added by the guesser
78 | % to match prefixed in the parser). Thus we have to make sure that a variable
79 | % is not "mistaken" for a sentence end symbol.
80 | %
81 | % @param Tokens is a list of ACE tokens
82 | % @param Sentence is an ACE sentence (a list of ACE tokens)
83 | % @param RestTokens is a list of ACE tokens
84 | %
85 | first_sentence([SentenceEndSymbol | RestTokens], [SentenceEndSymbol], RestTokens) :-
86 | nonvar(SentenceEndSymbol),
87 | is_sentence_end_symbol(SentenceEndSymbol),
88 | !.
89 |
90 | first_sentence([Token | RestTokens], RestSentence, RestTokens2) :-
91 | Token == '',
92 | !,
93 | first_sentence(RestTokens, RestSentence, RestTokens2).
94 |
95 | first_sentence([Token | RestTokens], [Token | RestSentence], RestTokens2) :-
96 | first_sentence(RestTokens, RestSentence, RestTokens2).
97 |
98 |
99 | %% tokens_to_paragraphs(+Tokens, -Paragraphs).
100 |
101 | tokens_to_paragraphs([], []).
102 |
103 | tokens_to_paragraphs(Tokens, [Paragraph|Paragraphs]) :-
104 | first_paragraph(Tokens, Paragraph, RestTokens),
105 | tokens_to_paragraphs(RestTokens, Paragraphs).
106 |
107 |
108 | %% first_paragraph(+Tokens, -Paragraph, -RestTokens).
109 |
110 | first_paragraph([Token | RestTokens], [], RestTokens) :-
111 | Token == ' ',
112 | !.
113 |
114 | first_paragraph([Token | RestTokens], [Token | RestParagraph], RestTokens2) :-
115 | first_paragraph(RestTokens, RestParagraph, RestTokens2).
116 |
117 | first_paragraph([], [], []).
118 |
--------------------------------------------------------------------------------
/prolog/utils/drs_ops.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(drs_ops, [
17 | drs_operator/1,
18 | unary_drs_operator/1,
19 | binary_drs_operator/1
20 | ]).
21 |
22 | /** DRS Operators
23 |
24 | @author Tobias Kuhn
25 | */
26 |
27 |
28 | %% drs_operator(?DRSOperator)
29 |
30 | drs_operator(DRSOperator) :-
31 | (
32 | unary_drs_operator(DRSOperator)
33 | ;
34 | binary_drs_operator(DRSOperator)
35 | ).
36 |
37 |
38 | %% unary_drs_operator(?DRSOperator)
39 |
40 | unary_drs_operator(-).
41 | unary_drs_operator(~).
42 | unary_drs_operator(can).
43 | unary_drs_operator(must).
44 | unary_drs_operator(should).
45 | unary_drs_operator(may).
46 | unary_drs_operator(question).
47 | unary_drs_operator(command).
48 |
49 |
50 | %% binary_drs_operator(?DRSOperator)
51 |
52 | binary_drs_operator(=>).
53 | binary_drs_operator(v).
54 |
55 |
--------------------------------------------------------------------------------
/prolog/utils/drs_reverse.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(drs_reverse, [drs_reverse/2]).
17 |
18 | :- use_module(drs_ops).
19 |
20 | /** Reverse a DRS
21 |
22 | @author Kaarel Kaljurand
23 | @author Tobias Kuhn
24 | @version 2008-05-13
25 |
26 | */
27 |
28 |
29 | %% drs_reverse(+Drs:term, -DrsReversed:term) is det.
30 | %
31 | % Reverses all domains (lists of referents) and condition lists
32 | % of the input DRS.
33 | %
34 | % @param Drs is an Attempto DRS
35 | % @param DrsReversed is the DRS with its domain and conditions reversed
36 | %
37 | drs_reverse(drs([], []), drs([], [])) :- !.
38 |
39 | drs_reverse(drs(Dom, Conds), drs(DomR, CondsR)) :-
40 | reverse(Dom, DomR),
41 | reverse(Conds, Conds1),
42 | conds_reverse(Conds1, CondsR).
43 |
44 |
45 | %% conds_reverse(+Conditions:list, -ConditionsReversed:list) is det.
46 | %
47 | % Reverses each condition in a list of conditions.
48 | %
49 | % @param Conditions is a list of conditions
50 | % @param ConditionsReversed is a list of conditions reversed
51 | %
52 | conds_reverse([], []).
53 |
54 | conds_reverse([First | Conds], [FirstR | CondsR]) :-
55 | condition_reverse(First, FirstR),
56 | conds_reverse(Conds, CondsR).
57 |
58 |
59 | %% condition_reverse(+Condition:term, -ConditionReversed:term) is det.
60 | %
61 | % If the input is a complex condition then reverses its component DRSs.
62 | % If the input is an atomic condition then does nothing.
63 | %
64 | % @param Condition is a DRS condition
65 | % @param ConditionReversed is the condition reversed
66 | %
67 | condition_reverse(Drs, DrsR) :-
68 | Drs =.. [Op, SubDrs],
69 | unary_drs_operator(Op),
70 | drs_reverse(SubDrs, SubDrsR),
71 | !,
72 | DrsR =.. [Op, SubDrsR].
73 |
74 | condition_reverse(Drs, DrsR) :-
75 | Drs =.. [Op, SubDrs1, SubDrs2],
76 | binary_drs_operator(Op),
77 | drs_reverse(SubDrs1, SubDrs1R),
78 | drs_reverse(SubDrs2, SubDrs2R),
79 | !,
80 | DrsR =.. [Op, SubDrs1R, SubDrs2R].
81 |
82 | condition_reverse([H|T], R) :-
83 | reverse([H|T], R1),
84 | conds_reverse(R1, R),
85 | !.
86 |
87 | condition_reverse(Label:Drs, Label:DrsR) :-
88 | drs_reverse(Drs, DrsR),
89 | !.
90 |
91 | condition_reverse(Cond, Cond).
92 |
--------------------------------------------------------------------------------
/prolog/utils/drs_to_ace.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(drs_to_ace, [drs_to_ace/2]).
17 |
18 | :- use_module(drs_to_drslist, [
19 | drs_to_drslist/2
20 | ]).
21 |
22 | :- use_module(drs_to_coreace).
23 |
24 | :- use_module(drs_to_npace).
25 |
26 | /** DRS to ACE verbalizer
27 |
28 | Translate an Attempto DRS into Attempto Controlled English (ACE).
29 | The result is either in Core ACE or in NP ACE.
30 |
31 | @author Kaarel Kaljurand
32 | @version 2009-06-03
33 | */
34 |
35 |
36 | %% drs_to_ace(+Drs:drs, -Ace:list) is det.
37 | %
38 | % Splits the given DRS into a list of (smaller) DRSs,
39 | % and verbalizes each split in either Core ACE or NP ACE.
40 | %
41 | % @param Drs is an Attempto DRS (untyped)
42 | % @param Ace is a list of ACE sentences
43 | %
44 | drs_to_ace(Drs, Ace) :-
45 | drs_to_drslist(Drs, DrsList),
46 | drslist_to_ace(DrsList, Ace).
47 |
48 |
49 | %% drslist_to_ace
50 | %
51 | %
52 | drslist_to_ace([], []).
53 |
54 | drslist_to_ace([Drs | DrsList], [Ace | AceList]) :-
55 | drs_to_ace_x(Drs, Ace),
56 | drslist_to_ace(DrsList, AceList).
57 |
58 |
59 | % BUG: As Drace NP might take very long (due to a bug?) we add
60 | % a timeout to fail if it takes longer than, say, 0.5 seconds.
61 | drs_to_ace_x(Drs, Ace) :-
62 | catch(
63 | call_with_time_limit(
64 | 0.5,
65 | drs_to_npace:drs_to_npace(Drs, Ace)
66 | ),
67 | time_limit_exceeded,
68 | fail
69 | ),
70 | Ace \= [],
71 | \+ member('ERROR', Ace),
72 | !.
73 |
74 | drs_to_ace_x(Drs, Ace) :-
75 | drs_to_coreace:drs_to_coreace(Drs, Ace).
76 |
--------------------------------------------------------------------------------
/prolog/utils/drs_to_ascii.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(drs_to_ascii, [
17 | drs_to_ascii/2, % +Drs, -DrsAscii
18 | display_drs/1 % +Drs
19 | ]).
20 |
21 |
22 | /** DRS Pretty-printer
23 |
24 | Creates a pretty print representation of a DRS.
25 |
26 | @author Kaarel Kaljurand
27 | @version 2008-03-14
28 | */
29 |
30 |
31 | :- op(400, fx, -).
32 | :- op(400, fx, ~).
33 | :- op(500, xfx, =>).
34 | :- op(500, xfx, v).
35 |
36 |
37 | %% drs_to_ascii(+Drs:term, -DrsAscii:atom) is det.
38 | %
39 | % @param Drs is an Attempto DRS
40 | % @param DrsAscii is an ASCII-graphics representation of the DRS
41 | %
42 | drs_to_ascii(Drs, DrsAscii) :-
43 | drs_to_drspp(Drs, PP),
44 | with_output_to(atom(DrsAscii), pp_to_ascii(PP)).
45 |
46 |
47 | %% display_drs(+DRS)
48 | %
49 | % Makes a pretty print of a DRS and writes it out on the screen.
50 | %
51 | display_drs(Drs):-
52 | drs_to_drspp(Drs, PP),
53 | pp_to_ascii(PP).
54 |
55 |
56 | %% drs_to_drspp(+Drs:term, -DrsPP:list) is det.
57 | %
58 | % @param Drs is an Attempto DRS
59 | % @param DrsPP is the DRS with indentation information
60 | %
61 | drs_to_drspp(Drs, PP) :-
62 | copy_term(Drs, DrsCopy),
63 | numbervars(DrsCopy, 0, _),
64 | write_drs(DrsCopy, 0, PP).
65 |
66 |
67 | %% pp_to_ascii(+PP:term) is det.
68 | %
69 | pp_to_ascii([]).
70 |
71 | pp_to_ascii([(Indent, Term) | Rest]) :-
72 | with_output_to(atom(AtomTerm), format('~W', [Term, [numbervars(true)]])),
73 | PrettyIndent is Indent * 3,
74 | writef('%r%w\n', [' ', PrettyIndent, AtomTerm]),
75 | pp_to_ascii(Rest).
76 |
77 |
78 | %% write_drs(+DRS, +Indent, -PP)
79 | %
80 | % Creates a DRS in pretty print and indents it
81 | % according to the value of Indent
82 | %
83 | write_drs(drs(Dom,[]), Indent, [(Indent,'No conditions') | PP]):-
84 | write_dom(Dom, Indent, PP),
85 | !.
86 |
87 | write_drs(drs(Dom,Conds),Indent,PP):-
88 | write_dom(Dom,Indent,PP1),
89 | write_conds(Conds,Indent,PP2),
90 | append(PP1,PP2,PP),
91 | !.
92 |
93 | write_drs(_Term,Indent,[(Indent,'ERROR')]).
94 |
95 |
96 | %% write_dom(+Dom:list, +Indent:integer, -PP:list) is det.
97 | %
98 | %
99 | write_dom(Dom, Indent, [(Indent, Dom)]).
100 |
101 |
102 | %% write_conds(+ConditionsList,+Indent)
103 | %
104 | %
105 | write_conds([],_Indent,[]).
106 |
107 | write_conds([F|R],Indent,PP):-
108 | write_cond(F,Indent,PP1),
109 | write_conds(R,Indent,PP2),
110 | append(PP1,PP2,PP).
111 |
112 |
113 | %% write_cond(+Condition,+Indent)
114 | %
115 | %
116 | write_cond(Restr => Scope,Indent,PP):-
117 | !,
118 | NewIndent is Indent+1,
119 | write_drs(Restr,NewIndent,PP1),
120 | write_drs(Scope,NewIndent,PP2),
121 | append(PP1,[(NewIndent,=>)|PP2],PP).
122 |
123 | write_cond(Restr v Scope,Indent,PP):-
124 | !,
125 | NewIndent is Indent+1,
126 | write_drs(Restr,NewIndent,PP1),
127 | write_drs(Scope,NewIndent,PP2),
128 | append(PP1,[(NewIndent,v)|PP2],PP).
129 |
130 | write_cond([FirstCond|Conds], Indent, PP) :-
131 | !,
132 | NewIndent is Indent+1,
133 | write_conds([FirstCond|Conds], NewIndent, PP).
134 |
135 | write_cond(-DRS, Indent, [(NewIndent,'NOT') | PP]) :-
136 | !,
137 | NewIndent is Indent+1,
138 | write_drs(DRS,NewIndent,PP).
139 |
140 | write_cond(~DRS, Indent, [(NewIndent,'NAF') | PP]) :-
141 | !,
142 | NewIndent is Indent+1,
143 | write_drs(DRS, NewIndent, PP).
144 |
145 | write_cond(can(DRS), Indent, [(NewIndent, 'CAN') | PP]) :-
146 | !,
147 | NewIndent is Indent+1,
148 | write_drs(DRS, NewIndent, PP).
149 |
150 | write_cond(must(DRS), Indent, [(NewIndent, 'MUST') | PP]) :-
151 | !,
152 | NewIndent is Indent+1,
153 | write_drs(DRS, NewIndent, PP).
154 |
155 | write_cond(should(DRS), Indent, [(NewIndent, 'SHOULD') | PP]) :-
156 | !,
157 | NewIndent is Indent+1,
158 | write_drs(DRS, NewIndent, PP).
159 |
160 | write_cond(may(DRS), Indent, [(NewIndent, 'MAY') | PP]) :-
161 | !,
162 | NewIndent is Indent+1,
163 | write_drs(DRS, NewIndent, PP).
164 |
165 | write_cond(question(DRS), Indent, [(NewIndent, 'QUESTION') | PP]) :-
166 | !,
167 | NewIndent is Indent+1,
168 | write_drs(DRS, NewIndent, PP).
169 |
170 | write_cond(command(DRS), Indent, [(NewIndent, 'COMMAND') | PP]) :-
171 | !,
172 | NewIndent is Indent+1,
173 | write_drs(DRS, NewIndent, PP).
174 |
175 | write_cond(Label:DRS, Indent, [(NewIndent, Label) | PP]) :-
176 | !,
177 | NewIndent is Indent+1,
178 | write_drs(DRS, NewIndent, PP).
179 |
180 | write_cond(drs(Dom,Cond),Indent,PP):-
181 | !,
182 | NewIndent is Indent+1,
183 | write_drs(drs(Dom,Cond),NewIndent,PP).
184 |
185 | write_cond(Cond, Indent, [(Indent,Cond)]).
186 |
--------------------------------------------------------------------------------
/prolog/utils/drs_to_drslist.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 | :- module(drs_to_drslist, [
16 | drs_to_drslist/2
17 | ]).
18 |
19 |
20 | :- use_module(drs_ops, [
21 | drs_operator/1
22 | ]).
23 |
24 | /** DRS to DRS lists converter
25 |
26 | This module provides predicates to split a given DRS into
27 | a list of DRSs, such that if the elements of the resulting list
28 | are merged (by concatenating the domains and the condition lists
29 | of its DRSs),
30 | then the resulting DRS is structurally equivalent to the original.
31 | The DRSs in the resulting list do not share discourse referents.
32 |
33 | @author Kaarel Kaljurand
34 | @version 2009-06-03
35 |
36 | */
37 |
38 |
39 | %% drs_to_drslist(+Drs:drs, -DrsList:list) is det.
40 | %
41 | % @param Drs is an Attempto DRS
42 | % @param DrsList is a list of Attempto DRSs
43 | %
44 |
45 | drs_to_drslist(drs(_, CondList), DrsListSorted) :-
46 | termlist_to_termlistlist(CondList, CondListList),
47 | maplist(condlist_to_drs, CondListList, DrsList),
48 | sort_drslist(DrsList, DrsListSorted).
49 |
50 |
51 | condlist_to_drs(CondList, drs(Dom, CondList)) :-
52 | get_toplevel_conds(CondList, ToplevelCondList),
53 | term_variables(ToplevelCondList, Dom).
54 |
55 |
56 | %% get_toplevel_conds(+CondsIn:list, -CondsOut:list)
57 | %
58 | % Extracts from the given list of DRS conditions only
59 | % those conditions that contribute discourse referents
60 | % to the toplevel domain. Such conditions are simple
61 | % toplevel conditions, but also simple conditions in the lists.
62 | % For example, in the DRS of the sentence
63 | %
64 | % Less than 3 dogs hate less than 3 cats.
65 | %
66 | % all discourse referents are toplevel.
67 | %
68 | get_toplevel_conds([], []).
69 |
70 | get_toplevel_conds([Cond-Id | Conds], [Cond-Id | SelectedConds]) :-
71 | !,
72 | get_toplevel_conds(Conds, SelectedConds).
73 |
74 | get_toplevel_conds([[H | T] | Conds], SelectedConds) :-
75 | !,
76 | get_toplevel_conds([H | T], SelectedConds1),
77 | get_toplevel_conds(Conds, SelectedConds2),
78 | append(SelectedConds1, SelectedConds2, SelectedConds).
79 |
80 | get_toplevel_conds([_ComplexCond | Conds], SelectedConds) :-
81 | get_toplevel_conds(Conds, SelectedConds).
82 |
83 |
84 | termlist_to_termlistlist(TermList, TermListList) :-
85 | termlist_to_termlistlist(TermList, [], TermListList).
86 |
87 | termlist_to_termlistlist([], Out, Out).
88 |
89 | termlist_to_termlistlist([Term | TermList], TermListList, Out) :-
90 | (
91 | term_and_termlist_share_variables(Term, TermListList, Included, Excluded)
92 | ->
93 | termlist_to_termlistlist(TermList, [[Term | Included] | Excluded], Out)
94 | ;
95 | termlist_to_termlistlist(TermList, [[Term] | TermListList], Out)
96 | ).
97 |
98 |
99 | term_and_termlist_share_variables(Term, TermListList, IncludedFlat, Excluded) :-
100 | partition(terms_share_variables(Term), TermListList, Included, Excluded),
101 | append(Included, IncludedFlat).
102 |
103 | terms_share_variables(Term1, Term2) :-
104 | term_variables(Term1, List1),
105 | term_variables(Term2, List2),
106 | exists_intersection(List1, List2).
107 |
108 | exists_intersection(List1, List2) :-
109 | member(El1, List1),
110 | member(El2, List2),
111 | El1 == El2,
112 | !.
113 |
114 |
115 | %% sort_drslist(+DrsList:list, -DrsListSorted:list) is det.
116 | %
117 | % Sorts the list of DRSs. Sorting is done by keysort/2, and
118 | % the keys are assigned by assign_key/2. See the definition
119 | % of assign_key/2 to find out how the soring order is determined.
120 | %
121 | %
122 | sort_drslist([], []) :- !.
123 |
124 | sort_drslist([Drs], [Drs]) :- !.
125 |
126 | sort_drslist(DrsList, DrsListSorted) :-
127 | maplist(assign_key, DrsList, DrsListWithKeys),
128 | keysort(DrsListWithKeys, DrsListWithKeysSorted),
129 | maplist(remove_key, DrsListWithKeysSorted, DrsListSorted).
130 |
131 |
132 | %% remove_key(+DrsWithKey:term, -Drs:term)
133 | %
134 | remove_key(_-Drs, Drs).
135 |
136 |
137 | %% assign_key(+Drs:term, -DrsWithKey:term)
138 | %
139 | % The key of a DRS is the smallest (in the standard order of terms)
140 | % sentence ID and token ID combination (SId/TId) of a DRS condition.
141 | % The SId/TId of a complex condition is determined recursively.
142 | % Note that we do not check the 2nd DRS of complex binary conditions
143 | % (e.g. the then-part of an implication), as there the keys are known
144 | % to be larger.
145 | %
146 | assign_key(drs(Dom, Conds), Key-drs(Dom, Conds)) :-
147 | assign_key_to_conds(Conds, Key).
148 |
149 |
150 | assign_key_to_conds(Conds, Key) :-
151 | maplist(get_key, Conds, Keys),
152 | sort(Keys, [Key | _]).
153 |
154 |
155 | get_key(_-Key, Key) :- !.
156 |
157 | get_key(Cond, Key) :-
158 | functor(Cond, Op, _),
159 | drs_operator(Op),
160 | arg(1, Cond, Drs),
161 | assign_key(Drs, Key-_).
162 |
163 | get_key(_Label:Drs, Key) :-
164 | assign_key(Drs, Key-_).
165 |
166 | get_key([H | T], Key) :-
167 | assign_key_to_conds([H | T], Key).
168 |
--------------------------------------------------------------------------------
/prolog/utils/drs_to_ruleml.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(drs_to_ruleml, [
17 | drs_to_ruleml/2
18 | ]).
19 |
20 | /** Attempto DRS to RuleML/folog converter
21 |
22 | This module converts the Attempto DRS into RuleML/folog as
23 | specified by David Hirtle in his thesis.
24 |
25 | @author Kaarel Kaljurand
26 | @author Tobias Kuhn
27 | @version 2012-08-23
28 | @see http://www.ruleml.org/translator/
29 |
30 | @bug Test RuleML validity.
31 | @bug Test correspondence to Hirtle's specification. E.g. DRSs resulting from
32 | query sentences are currently incorrectly supported. (Note that Hirtle just
33 | rejects such DRSs.)
34 | @bug Support ACE 5/5.5/6 extensions (e.g. RuleML supports NAF).
35 | */
36 |
37 |
38 | % The following operators are used in the DRS.
39 | :- op(400, fx, -).
40 | :- op(500, xfx, =>).
41 | :- op(500, xfx, v).
42 |
43 |
44 | %% drs_to_ruleml(+Drs:drs, -RuleML:functor) is det.
45 | %
46 | % Turn the DRS into RuleML/folog (in SWI Prolog's internal XML format)
47 | % as specified in David Hirtle's thesis.
48 |
49 | drs_to_ruleml(
50 | DRS,
51 | element('RuleML', [], [
52 | element('Assert', [], Elements)
53 | ])
54 | ) :-
55 | existdrs_els(DRS, Elements).
56 |
57 |
58 | %% conds_and(+Conds:list, -Element:functor) is det.
59 | %
60 | % Converts a list of DRS conditions into a RuleML and-element.
61 |
62 | conds_and(Conds, ElementsOut) :-
63 | conds_elements(Conds, Elements),
64 | conds_and_x(Elements, ElementsOut).
65 |
66 | conds_and_x([Element], Element) :-
67 | !.
68 |
69 | conds_and_x(Elements, element('And', [], Elements)).
70 |
71 |
72 | %% conds_elements(+Conds:list, -Elements:list) is det.
73 | %
74 | % Converts a list of DRS conditions into RuleML elements.
75 |
76 | conds_elements([], []).
77 |
78 | conds_elements([Cond | Tail], [SCond | STail]) :-
79 | cond_element(Cond, SCond),
80 | conds_elements(Tail, STail).
81 |
82 |
83 | %% cond_element(+Condition:functor, -Element:functor) is det.
84 | %
85 | % Converts a DRS condition into a RuleML element.
86 | %
87 | % As the structure of the DRS doesn't match exactly to the structure
88 | % of the RuleML element (as specified by Hirtle),
89 | % we have to do some ugly appending.
90 |
91 | cond_element(drs(Dom1, Conds1) => DRS2,
92 | element('Forall', [], SubElements0)
93 | ) :-
94 | args_els(Dom1, VarElements1),
95 | conds_and(Conds1, Element1),
96 | existdrs_els(DRS2, SubElements2),
97 | append([Element1], SubElements2, SubElements1),
98 | append(VarElements1, [element('Implies', [], SubElements1)], SubElements0).
99 |
100 |
101 | cond_element(DRS1 v DRS2,
102 | element('Or', [], SubElements0)
103 | ) :-
104 | existdrs_els(DRS1, SubElements1),
105 | existdrs_els(DRS2, SubElements2),
106 | append(SubElements1, SubElements2, SubElements0).
107 |
108 |
109 | cond_element(-DRS, element('Neg', [], SubElements)) :-
110 | existdrs_els(DRS, SubElements).
111 |
112 |
113 | cond_element(Conds, Element) :-
114 | is_list(Conds),
115 | conds_and(Conds, Element).
116 |
117 |
118 | cond_element(Condition-_, element('Atom', [], [element('Rel', [], [Functor]) | Els])) :-
119 | Condition =.. [Functor | Args],
120 | args_els(Args, Els).
121 |
122 |
123 | %% args_els(+List:list, -Elements:list) is det.
124 | %
125 | % Converts the arguments of a DRS condition into RuleML elements.
126 | %
127 | % Note that all terms (e.g. variables and numbers) must be converted into atoms
128 | % to be compatible with the way how SWI represents XML
129 | % documents internally.
130 |
131 | args_els([], []).
132 |
133 | args_els([H | T], [element('Var', [], [HH]) | ElsTail]) :-
134 | var(H),
135 | !,
136 | term_to_atom(H, HH),
137 | args_els(T, ElsTail).
138 |
139 | args_els([H | T], [element('Data', [], [HH]) | ElsTail]) :-
140 | number(H),
141 | !,
142 | term_to_atom(H, HH), % alternatively: atom_number(HH, H)
143 | args_els(T, ElsTail).
144 |
145 | args_els([H | T], [element('Ind', [], [H]) | ElsTail]) :-
146 | args_els(T, ElsTail).
147 |
148 |
149 | %% existdrs_els(+Drs:drs, -Elements:list) is det.
150 | %
151 | % Converts an existential DRS box into RuleML elements.
152 |
153 | existdrs_els(drs([],Conds), [Element]) :-
154 | !,
155 | conds_and(Conds, Element).
156 |
157 | existdrs_els(drs(Dom,Conds), [element('Exists', [], Elements)]) :-
158 | args_els(Dom, DomElements),
159 | conds_and(Conds, Element),
160 | append(DomElements, [Element], Elements).
161 |
162 |
163 | %% to_xml(+Elements:list, -Xml:atom) is det.
164 | %
165 | % @param Elements is a list of XML elements
166 | % @param Xml is an XML document as an atom
167 | %
168 | % @deprecated use SWI's xml_write/3 instead
169 | %
170 | % Converts SWI Prolog's XML represenation into an XML atom.
171 | % Something like xml_write/3 but very simple.
172 |
173 | to_xml([], '').
174 |
175 | to_xml([element(Name, _, Elements) | T], Xml) :-
176 | to_xml(Elements, ElXml),
177 | to_xml(T, TXml),
178 | format(atom(Xml), '<~w>~w~w>~n~w', [Name, ElXml, Name, TXml]).
179 |
180 | to_xml([Text | T], Xml) :-
181 | atom(Text),
182 | to_xml(T, TXml),
183 | format(atom(Xml), '~w~w', [Text, TXml]).
184 |
--------------------------------------------------------------------------------
/prolog/utils/drs_to_sdrs.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(drs_to_sdrs, [drs_to_sdrs/2]).
17 |
18 | :- use_module(drs_ops).
19 |
20 | /** DRS simplifier
21 |
22 | Converts the DRS into a simplified form where every
23 | DRS-box is represented as a list of conditions, i.e.
24 |
25 | ==
26 | drs(Dom, Conds) --> Conds
27 | ==
28 |
29 | where Conds is a list of conditions (with sentence IDs).
30 |
31 | @author Kaarel Kaljurand
32 | @author Tobias Kuhn
33 | @version 2009-05-13
34 |
35 | */
36 |
37 |
38 | %% drs_to_sdrs(+Drs:drs, -SDrs:sdrs) is det.
39 | %
40 | % Removes the domain-argument from all the (non-atomic) DRS conditions,
41 | % including the embedded ones.
42 | %
43 | % @param Drs is an Attempto DRS
44 | % @param SDrs is an Attempto DRS with the domain-arguments removed
45 |
46 | drs_to_sdrs(drs(_, Conds), SConds) :-
47 | conds_sconds(Conds, SConds).
48 |
49 |
50 | conds_sconds([], []).
51 |
52 | conds_sconds([Cond | Tail], [SCond | STail]) :-
53 | simplify(Cond, SCond),
54 | !,
55 | conds_sconds(Tail, STail).
56 |
57 |
58 | simplify(DRS, SDRS) :-
59 | DRS =.. [Op, drs(_, Conds)],
60 | unary_drs_operator(Op),
61 | conds_sconds(Conds, SConds),
62 | SDRS =.. [Op, SConds].
63 |
64 | simplify(DRS, SDRS) :-
65 | DRS =.. [Op, drs(_, Conds1), drs(_, Conds2)],
66 | binary_drs_operator(Op),
67 | conds_sconds(Conds1, SConds1),
68 | conds_sconds(Conds2, SConds2),
69 | SDRS =.. [Op, SConds1, SConds2].
70 |
71 | simplify(Conds, (SConds)) :-
72 | is_list(Conds),
73 | conds_sconds(Conds, SConds).
74 |
75 | simplify(Label:drs(_, Conds), Label:SConds) :-
76 | conds_sconds(Conds, SConds).
77 |
78 | simplify(Cond, Cond).
79 |
--------------------------------------------------------------------------------
/prolog/utils/drs_utils.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(drs_utils, [
17 | get_toplevel_object_referents/2
18 | ]).
19 |
20 | /** Attempto DRS utils
21 |
22 | @author Kaarel Kaljurand
23 | @version 2009-04-08
24 |
25 | */
26 |
27 | %% get_toplevel_object_referents(+ConditionList:list, -Toplevel:term) is det.
28 | %
29 | % Returns a term toplevel(ReferentList, SubjectList, ObjectList, NamedList) where
30 | %
31 | % * ReferentList is a list of top-level object-referents
32 | % * SubjectList is a list of top-level object-referents that are used as subjects
33 | % * ObjectList is a list of top-level object-referents that are used as objects
34 | % * NamedList is a list of top-level object-referents that correspond to proper names (Type = named)
35 | %
36 | % @param ConditionList is a list of DRS conditions
37 | % @param Toplevel is a term containing top-level DRS discourse referents
38 | %
39 | get_toplevel_object_referents(ConditionList, toplevel(ReferentList, SubjectList, ObjectList, NamedList)) :-
40 | get_toplevel_object_referents_x(
41 | ConditionList,
42 | toplevel(
43 | -([], ReferentList),
44 | -([], SubjectList),
45 | -([], ObjectList),
46 | -([], NamedList)
47 | )
48 | ).
49 |
50 |
51 | %% get_toplevel_object_referents_x(+ConditionList:list, -Toplevel:term) is det.
52 | %
53 | % @param ConditionList is a list of DRS conditions
54 | % @param Toplevel is a term containing top-level DRS discourse referents
55 | %
56 | get_toplevel_object_referents_x([], toplevel(R-R, S-S, O-O, N-N)).
57 |
58 | get_toplevel_object_referents_x([Condition | ConditionList], toplevel(R1-R2, S1-S2, O1-O2, N1-N2)) :-
59 | condition_referents(Condition, toplevel(R1-RT, S1-ST, O1-OT, N1-NT)),
60 | get_toplevel_object_referents_x(ConditionList, toplevel(RT-R2, ST-S2, OT-O2, NT-N2)).
61 |
62 |
63 | %% condition_referents(+Condition:term) is det.
64 | %
65 | % Note: the referents of plural objects, mass-objects, query-objects, and objects in the relation-condition
66 | % are considered as named-objects, i.e. they will not be verbalized by "there is/are".
67 | % BUG: This is a hack, and it is DRACE specific.
68 | %
69 | % @param Condition is a DRS condition
70 | %
71 |
72 | % BUG: ???
73 | condition_referents(object(Ref, Noun, Type, _, _Eq, na)-_, toplevel(R-[Ref | R], S-S, O-O, N-N)) :-
74 | Noun \= na,
75 | Type \= named,
76 | Type \= mass,
77 | !.
78 |
79 | % Plural objects (i.e. NP conjunction). BUG: we consider them named-objects for the time being.
80 | condition_referents(object(Ref, na, _, _, _, _)-_, toplevel(R-[Ref | R], S-S, O-O, N1-[Ref | N1])) :- !.
81 |
82 | % Mass objects. BUG: we consider them objects as named-objects for the time being.
83 | condition_referents(object(Ref, _, mass, _, _, _)-_, toplevel(R-[Ref | R], S-S, O-O, N1-[Ref | N1])) :- !.
84 |
85 | % Parts of plural objects. BUG: we consider them named-objects for the time being.
86 | condition_referents(has_part(_, Ref)-_, toplevel(R-R, S-S, O-O, N1-[Ref | N1])) :- !.
87 |
88 | % Relation object. BUG: we consider them named-objects for the time being.
89 | condition_referents(relation(Ref1, of, Ref2)-_, toplevel(R-R, S-S, O-O, N-[Ref1, Ref2 | N])) :- !.
90 |
91 | % Query objects. BUG: we consider them named-objects for the time being.
92 | condition_referents(query(Ref, _)-_, toplevel(R-[Ref | R], S-S, O-O, N1-[Ref | N1])) :- !.
93 |
94 | /* BUG: is the var/nonvar stuff really necessary? */
95 |
96 | condition_referents(predicate(_, _, Ref)-_, toplevel(R-R, S-[Ref | S], O-O, N-N)) :-
97 | var(Ref),
98 | !.
99 |
100 | condition_referents(predicate(_, _, Ref, O1)-_, toplevel(R-R, S-[Ref | S], O-[O1 | O], N-N)) :-
101 | var(Ref), var(O1),
102 | !.
103 |
104 | condition_referents(predicate(_, _, Ref, O1)-_, toplevel(R-R, S-[Ref | S], O-O, N-N)) :-
105 | var(Ref), nonvar(O1),
106 | !.
107 |
108 | condition_referents(predicate(_, _, Ref, O1)-_, toplevel(R-R, S-S, O-[O1 | O], N-N)) :-
109 | nonvar(Ref), var(O1),
110 | !.
111 |
112 | condition_referents(predicate(_, _, Ref, O1, O2)-_, toplevel(R-R, S-[Ref | S], O-[O1, O2 | O], N-N)) :-
113 | var(Ref), var(O1), var(O2),
114 | !.
115 |
116 | condition_referents(predicate(_, _, Ref, O1, O2)-_, toplevel(R-R, S-S, O-[O1, O2 | O], N-N)) :-
117 | nonvar(Ref), var(O1), var(O2),
118 | !.
119 |
120 | condition_referents(predicate(_, _, Ref, O1, O2)-_, toplevel(R-R, S-[Ref | S], O-[O2 | O], N-N)) :-
121 | var(Ref), nonvar(O1), var(O2),
122 | !.
123 |
124 | condition_referents(predicate(_, _, Ref, O1, O2)-_, toplevel(R-R, S-[Ref | S], O-[O1 | O], N-N)) :-
125 | var(Ref), var(O1), nonvar(O2),
126 | !.
127 |
128 | condition_referents(predicate(_, _, Ref, O1, O2)-_, toplevel(R-R, S-S, O-[O2 | O], N-N)) :-
129 | nonvar(Ref), nonvar(O1), var(O2),
130 | !.
131 |
132 | condition_referents(predicate(_, _, Ref, O1, O2)-_, toplevel(R-R, S-S, O-[O1 | O], N-N)) :-
133 | nonvar(Ref), var(O1), nonvar(O2),
134 | !.
135 |
136 | condition_referents(predicate(_, _, Ref, O1, O2)-_, toplevel(R-R, S-[Ref | S], O-O, N-N)) :-
137 | var(Ref), nonvar(O1), nonvar(O2),
138 | !.
139 |
140 | condition_referents(_, toplevel(R-R, S-S, O-O, N-N)).
141 |
--------------------------------------------------------------------------------
/prolog/utils/owlswrl/README.md:
--------------------------------------------------------------------------------
1 | Translating Attempto DRS into OWL and SWRL
2 | ==========================================
3 |
4 | Introduction
5 | ------------
6 |
7 | Translating an Attempto DRS into Web Ontology Language (OWL 2),
8 | or if this fails then to Semantic Web Rule Language (SWRL).
9 | Various serializations are provided by:
10 |
11 | - `owlfss`: Prolog term based on [OWL 2 Web Ontology Language Structural Specification and Functional-Style Syntax](http://www.w3.org/TR/2009/REC-owl2-syntax-20091027/), e.g. OWL lists and sets are denoted by Prolog lists
12 | - `owlxml`: [OWL 2 Web Ontology Language XML Serialization](http://www.w3.org/TR/2009/REC-owl2-xml-serialization-20091027/)
13 | - `owlfsspp`: [OWL 2 Web Ontology Language Structural Specification and Functional-Style Syntax](http://www.w3.org/TR/2009/REC-owl2-syntax-20091027/), useful for pretty-printing, but also understood by e.g. the Manchester OWL API
14 |
15 | For SWRL rules we use the functional and XML-based syntaxes that are described in
16 | .
17 |
18 |
19 | Documentation
20 | -------------
21 |
22 | For the documentation see:
23 |
24 | > Kaarel Kaljurand.
25 | > Attempto Controlled English as a Semantic Web Language.
26 | > PhD thesis, Faculty of Mathematics and Computer Science, University of Tartu, 2007.
27 | >
28 | > (Printable version: )
29 |
30 | Note that this thesis uses the label "OWL 1.1" to discuss OWL 2.
31 | This is because OWL 1.1 used to be the name of OWL 2 until April 2008.
32 |
33 | Also, see the PlDoc documentation inside the translator files.
34 |
35 | Some examples of sentences that the OWL/SWRL translator supports are available at
36 | .
37 |
38 |
39 | Usage
40 | -----
41 |
42 | Processing an ACE sentence `Every man likes Mary.` using the APE commandline:
43 |
44 | ape.exe \
45 | -uri "http://www.example.com/default" \
46 | -noclex \
47 | -ulextext "pn_sg('Mary', iri('http://www.example.com/names#Mary'), fem). noun_sg(man, man, masc). tv_finsg(likes, like)." \
48 | -text "Every man likes Mary." \
49 | -solo owlfsspp
50 |
51 | results in:
52 |
53 | Prefix(:=)
54 | Ontology(
55 | SubClassOf(
56 | :man
57 | ObjectSomeValuesFrom(
58 | :like
59 | ObjectOneOf(
60 |
61 | )
62 | )
63 | )
64 | )
65 |
66 | Note that by using the `iri`-term in the lexicon one can assign the complete
67 | IRI to the surface word. Otherwise, the default namespace is assumed.
68 |
--------------------------------------------------------------------------------
/prolog/utils/owlswrl/get_owl_output.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2010, Kaarel Kaljurand .
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(get_owl_output, [
17 | get_owl_output/6
18 | ]).
19 |
20 |
21 | /** Interface for the OWL outputs
22 |
23 | @author Kaarel Kaljurand
24 | @version 2010-11-26
25 |
26 | */
27 |
28 | :- use_module(drs_to_owlswrl).
29 | :- use_module(owlfss_owlrdfxml).
30 | :- use_module(owlswrl_to_xml).
31 | :- use_module(owlswrl_to_fss).
32 | :- use_module('../../logger/error_logger').
33 |
34 | :- use_module('../xmlterm_to_xmlatom', [
35 | xmlterm_to_xmlatom/2
36 | ]).
37 |
38 | :- use_module('../serialize_term', [
39 | serialize_term_into_atom/2
40 | ]).
41 |
42 |
43 | %% get_owl_output(+OwlOutputType:atom, +Comment:atom, +Drs:term, +Uri:atom, -ContentType:atom, -Output:atom) is det.
44 | %
45 | % @param OwlOutputType is one of {owlfss, owlfsspp, owlxml}
46 | % @param Comment is a comment to be included in the ontology (currently ignored)
47 | % @param Drs is an Attempto DRS
48 | % @param Uri is the name of the ontology to be created
49 | % @param ContentType is the content type of the result, one of {text/xml, text/plain}
50 | % @param Output is the output of the conversion to OWL
51 | %
52 | get_owl_output(owlrdf, Comment, Drs, Uri, 'text/xml', Output) :-
53 | ignore(drs_to_owlswrl:drs_to_owlswrl(Drs, Uri, Comment, OwlFss)),
54 | (
55 | get_messages_with_type(owl, [])
56 | ->
57 | owlfss_owlrdfxml:owlfss_owlrdfxml(OwlFss, OwlRdfxml),
58 | xmlterm_to_xmlatom(OwlRdfxml, Output)
59 | ;
60 | Output = ''
61 | ).
62 |
63 | get_owl_output(owlfss, Comment, Drs, Uri, 'text/plain', Output) :-
64 | ignore(drs_to_owlswrl:drs_to_owlswrl(Drs, Uri, Comment, OwlFss)),
65 | (
66 | get_messages_with_type(owl, [])
67 | ->
68 | serialize_term_into_atom(OwlFss, Output)
69 | ;
70 | Output = ''
71 | ).
72 |
73 | get_owl_output(owlfsspp, Comment, Drs, Uri, 'text/plain', Output) :-
74 | ignore(drs_to_owlswrl:drs_to_owlswrl(Drs, Uri, Comment, OwlFss)),
75 | (
76 | get_messages_with_type(owl, [])
77 | ->
78 | owlswrl_to_fss:owlswrl_to_fss(OwlFss, Output)
79 | ;
80 | Output = ''
81 | ).
82 |
83 | get_owl_output(owlxml, Comment, Drs, Uri, 'text/xml', Output) :-
84 | ignore(drs_to_owlswrl:drs_to_owlswrl(Drs, Uri, Comment, OwlFss)),
85 | (
86 | get_messages_with_type(owl, [])
87 | ->
88 | owlswrl_to_xml:owlswrl_to_xml(OwlFss, OwlXml),
89 | xmlterm_to_xmlatom(OwlXml, Output)
90 | ;
91 | Output = ''
92 | ).
93 |
--------------------------------------------------------------------------------
/prolog/utils/owlswrl/illegal_conditions.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2010, Kaarel Kaljurand .
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 | :- module(illegal_conditions, [
16 | illegal_conditions/1,
17 | illegal_condition/1
18 | ]).
19 |
20 | /** DRS checker for DRS-to-OWL/SWRL
21 |
22 | Setting some error messages for conditions which ACE->OWL/SWRL cannot handle.
23 |
24 | @author Kaarel Kaljurand
25 | @version 2010-12-14
26 |
27 | TODO
28 |
29 | * add more detailed messages in case of property/[4,5,7]
30 |
31 | * paraphrase the DRS to deliver a nicer error message.
32 | DRS->ACE needs to support this though (i.e. the situation when the
33 | the DRS contains referents which are defined on the upper level).
34 |
35 | * Should error messages be given on the ACE level or on the DRS level?
36 | For the end user the ACE level is better, but on the other hand the input
37 | to ACE->OWL is the DRS (i.e. the module is actually doing DRS->OWL).
38 |
39 | */
40 |
41 | :- use_module(ape('logger/error_logger'), [
42 | add_error_message/4
43 | ]).
44 |
45 | :- use_module(ape('utils/drs_ops'), [
46 | unary_drs_operator/1,
47 | binary_drs_operator/1
48 | ]).
49 |
50 |
51 | % Operators used in the DRS.
52 | :- op(400, fx, -).
53 | :- op(500, xfx, v).
54 | :- op(500, xfx, =>).
55 |
56 |
57 | %% illegal_conditions(+Conditions:list) is det.
58 | %
59 | %
60 | illegal_conditions([]).
61 |
62 | illegal_conditions([Cond | CondList]) :-
63 | illegal_condition(Cond),
64 | !,
65 | illegal_conditions(CondList).
66 |
67 |
68 | %% illegal_condition(BoxId, Cond, NewCond) is det.
69 | %
70 | %
71 |
72 | illegal_condition(relation(_, of, _)-SId/TId) :-
73 | add_error_message(owl, SId-TId, of, 'Possessive constructions not supported (in this particular case).').
74 |
75 | illegal_condition(modifier_adv(_, Adverb, _)-SId/TId) :-
76 | add_error_message(owl, SId-TId, Adverb, 'Adverbs not supported.').
77 |
78 | illegal_condition(modifier_pp(_, Preposition, _)-SId/TId) :-
79 | add_error_message(owl, SId-TId, Preposition, 'Prepositional phrases not supported.').
80 |
81 | % property/4 (comp adjective)
82 | illegal_condition(property(_, Adjective, comp)-SId/TId) :-
83 | add_error_message(owl, SId-TId, Adjective, 'Comparative adjective not supported.').
84 |
85 | % property/4 (sup adjective)
86 | illegal_condition(property(_, Adjective, sup)-SId/TId) :-
87 | add_error_message(owl, SId-TId, Adjective, 'Superlative adjective not supported.').
88 |
89 | % property/5 (comp_than adjective)
90 | illegal_condition(property(_, Adjective, _, _)-SId/TId) :-
91 | add_error_message(owl, SId-TId, Adjective, 'Adjective not supported.').
92 |
93 | % property/7 (comp_than + subj/obj adjective)
94 | illegal_condition(property(_, Adjective, _, _, _, _)-SId/TId) :-
95 | add_error_message(owl, SId-TId, Adjective, 'Adjective not supported.').
96 |
97 | illegal_condition(query(_, QueryWord)-SId/TId) :-
98 | add_error_message(owl, SId-TId, QueryWord, 'Query not supported.').
99 |
100 | illegal_condition(predicate(_, Verb, _)-SId/TId) :-
101 | add_error_message(owl, SId-TId, Verb, 'Intransitive verbs not supported.').
102 |
103 | illegal_condition(predicate(_, Verb, _, _, _)-SId/TId) :-
104 | add_error_message(owl, SId-TId, Verb, 'Ditransitive verbs not supported.').
105 |
106 | illegal_condition(must(Drs)) :-
107 | conds_sid(Drs, SId),
108 | add_error_message(owl, SId, 'must/1', 'Necessity not supported.').
109 |
110 | illegal_condition(can(Drs)) :-
111 | conds_sid(Drs, SId),
112 | add_error_message(owl, SId, 'can/1', 'Possibility not supported.').
113 |
114 | illegal_condition(_:Drs) :-
115 | conds_sid(Drs, SId),
116 | add_error_message(owl, SId, ':/2', 'Sentence subordination not supported.').
117 |
118 | illegal_condition('~'(Drs)) :-
119 | conds_sid(Drs, SId),
120 | add_error_message(owl, SId, '~/1', 'Negation-as-failure not supported.').
121 |
122 | illegal_condition(should(Drs)) :-
123 | conds_sid(Drs, SId),
124 | add_error_message(owl, SId, 'should/1', 'Recommendation not supported.').
125 |
126 | illegal_condition(may(Drs)) :-
127 | conds_sid(Drs, SId),
128 | add_error_message(owl, SId, 'may/1', 'Admissibility not supported.').
129 |
130 | % Note: do not do anything, NP conjunction ('na' as 2nd argument) is handled by the object-rule
131 | illegal_condition(has_part(_, _)-_).
132 |
133 | illegal_condition(predicate(_, Value, _, _)-SId/TId) :-
134 | add_error_message(owl, SId-TId, Value, 'Subject or object of this verb makes an illegal reference.').
135 |
136 | illegal_condition(object(_, na, _, na, _, _)-SId/TId) :-
137 | !,
138 | add_error_message(owl, SId-TId, and, 'Noun phrase conjunctions not supported.').
139 |
140 | illegal_condition(object(_, Value, _, na, _, _)-SId/TId) :-
141 | Value \= na,
142 | !,
143 | add_error_message(owl, SId-TId, Value, 'A reference to this noun either does not exist or is illegal.').
144 |
145 | illegal_condition(object(_, _, _, Unit, _, _)-SId/TId) :-
146 | Unit \= na,
147 | add_error_message(owl, SId-TId, Unit, 'Measurement nouns are not supported.').
148 |
149 |
150 | %% conds_sid(+Conditions:list, -SentenceId:integer) is det.
151 | %
152 | % Finds the shared sentence ID of the conditions.
153 | %
154 | conds_sid([], _).
155 |
156 | conds_sid([_-SId/_TId | _], SId) :- !.
157 |
158 | conds_sid([C | Cs], SId) :-
159 | cond_sid(C, SId),
160 | conds_sid(Cs, SId).
161 |
162 |
163 | cond_sid(Cond, SId) :-
164 | functor(Cond, F, 1),
165 | unary_drs_operator(F),
166 | !,
167 | arg(1, Cond, Drs),
168 | conds_id(Drs, SId).
169 |
170 | cond_id(_Label:Drs, SId) :-
171 | !,
172 | conds_id(Drs, SId).
173 |
174 | cond_id(Drs1 v Drs2, SId) :-
175 | !,
176 | conds_id(Drs1, SId),
177 | conds_id(Drs2, SId).
178 |
179 | cond_id(Drs1 => Drs2, SId) :-
180 | !,
181 | conds_id(Drs1, SId),
182 | conds_id(Drs2, SId).
183 |
--------------------------------------------------------------------------------
/prolog/utils/owlswrl/owlswrl_iri.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2013, Kaarel Kaljurand .
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 | :- module(owlswrl_iri, [
16 | iri_to_prefix/2,
17 | builtin_iri/2
18 | ]).
19 |
20 | /** Some helper predicates related to IRIs
21 |
22 | @author Kaarel Kaljurand
23 | @version 2013-06-03
24 |
25 | */
26 |
27 |
28 | %% iri_to_prefix(+Iri:atom, -Prefix:atom) is det.
29 | %
30 | % Attaches the #-character to the given IRI, unless
31 | % it already has it.
32 | %
33 | iri_to_prefix(Iri, Iri) :-
34 | sub_atom(Iri, _, 1, 0, '#'),
35 | !.
36 |
37 | iri_to_prefix(Iri, Prefix) :-
38 | atom_concat(Iri, '#', Prefix).
39 |
40 |
41 | %% builtin_iri
42 | %
43 | % Lists all the builtin / hardcoded IRI prefixes,
44 | % and their abbreviations.
45 | %
46 | builtin_iri(ace, 'http://attempto.ifi.uzh.ch/ace#').
47 |
--------------------------------------------------------------------------------
/prolog/utils/owlswrl/owlswrl_to_fss.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Kaarel Kaljurand .
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 | :- module(owlswrl_to_fss, [
16 | owlswrl_to_fss/1,
17 | owlswrl_to_fss/2
18 | ]).
19 |
20 | :- use_module(owlswrl_iri, [
21 | iri_to_prefix/2,
22 | builtin_iri/2
23 | ]).
24 |
25 |
26 | /** OWL/SWRL serializer into OWL/SWRL Functional-Style Syntax
27 |
28 | @author Kaarel Kaljurand
29 | @version 2013-06-03
30 |
31 | @tbd Escaping
32 |
33 | @tbd Test on the regression test set if OWL-API can load the output produced here
34 |
35 | */
36 |
37 | %% owlswrl_to_fss(+Ontology)
38 | %% owlswrl_to_fss(+Ontology, -Atom)
39 | %
40 | % Writes the OWL/SWRL ontology in Functional-Style Syntax into the current stream.
41 | %
42 | owlswrl_to_fss('Ontology'(OntologyIri, Axioms)) :-
43 | iri_to_prefix(OntologyIri, Prefix),
44 | format("Prefix(:=<~w>)~n", [Prefix]),
45 | forall(
46 | builtin_iri(Abbr, IriPrefix),
47 | format("Prefix(~w:=<~w>)~n", [Abbr, IriPrefix])
48 | ),
49 | format("Ontology(<~w>~n", [OntologyIri]),
50 | print_list(Axioms, 1),
51 | format(")~n").
52 |
53 | %
54 | owlswrl_to_fss(Ontology, OntologyFss) :-
55 | with_output_to(atom(OntologyFss), owlswrl_to_fss(Ontology)).
56 |
57 |
58 | %% print_compound
59 | %
60 | %
61 | print_compound(OwlFss, Level) :-
62 | OwlFss =.. [Name | Args],
63 | PrettyIndent is Level * 3,
64 | writef('%r%w(\n', [' ', PrettyIndent, Name]),
65 | NewLevel is Level + 1,
66 | print_list(Args, NewLevel),
67 | writef('%r)\n', [' ', PrettyIndent]).
68 |
69 |
70 | %% print_list
71 | %
72 | % Don't change the order, e.g. an empty list should
73 | % not be "mistaken" for an atom.
74 | %
75 | print_list([], _).
76 |
77 | print_list([Head | Tail], Level) :-
78 | is_list(Head),
79 | !,
80 | print_list(Head, Level),
81 | print_list(Tail, Level).
82 |
83 | print_list([Expression | Tail], Level) :-
84 | print_terminal(Expression, Level),
85 | !,
86 | print_list(Tail, Level).
87 |
88 | print_list([Head | Tail], Level) :-
89 | compound(Head),
90 | !,
91 | print_compound(Head, Level),
92 | print_list(Tail, Level).
93 |
94 |
95 | %% print_terminal
96 | %
97 | %
98 | print_terminal(Number, Level) :-
99 | number(Number),
100 | !,
101 | PrettyIndent is Level * 3,
102 | writef('%r%w\n', [' ', PrettyIndent, Number]).
103 |
104 | print_terminal(Iri, Level) :-
105 | atom(Iri),
106 | !,
107 | PrettyIndent is Level * 3,
108 | writef('%r<%w>\n', [' ', PrettyIndent, Iri]).
109 |
110 | print_terminal('Variable'(Iri), Level) :-
111 | PrettyIndent is Level * 3,
112 | writef('%rVariable(<%w>)\n', [' ', PrettyIndent, Iri]).
113 |
114 | print_terminal('BuiltInAtom'(Iri, DArgList), Level) :-
115 | PrettyIndent is Level * 3,
116 | writef('%rBuiltInAtom(<%w>\n', [' ', PrettyIndent, Iri]),
117 | NewLevel is Level + 1,
118 | print_list(DArgList, NewLevel),
119 | writef('%r)\n', [' ', PrettyIndent]).
120 |
121 | print_terminal('^^'(DataValue, DataType), Level) :-
122 | PrettyIndent is Level * 3,
123 | writef('%r"%w"^^<%w>\n', [' ', PrettyIndent, DataValue, DataType]).
124 |
125 | print_terminal(Terminal, Level) :-
126 | pretty_print(Terminal, PrettyExpression),
127 | !,
128 | PrettyIndent is Level * 3,
129 | writef('%r%w\n', [' ', PrettyIndent, PrettyExpression]).
130 |
131 |
132 | pretty_print(nodeID(Number), '_':Number).
133 | pretty_print(NS:Name, NS:Name).
134 |
--------------------------------------------------------------------------------
/prolog/utils/owlswrl/simplify_axiom.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Kaarel Kaljurand .
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(simplify_axiom, [
17 | simplify_axiom/2
18 | ]).
19 |
20 |
21 | /** Maps the given axiom to a syntactically simpler form
22 |
23 | The given axiom is mapped to a syntactically simpler form
24 | in order to achieve better compatibility with OWL tools
25 | and OWL fragments (which are defined based on syntax).
26 | In most cases the axiom is preserved as it is, we only target the
27 | following forms:
28 |
29 | - ObjectPropertyDomain
30 | - ObjectPropertyRange
31 | - DisjointClasses
32 |
33 | @author Kaarel Kaljurand
34 | @version 2013-04-07
35 | @license LGPLv3
36 |
37 | */
38 |
39 |
40 | %% simplify_axiom(+Axiom:term, -SimplerAxiom:term) is det.
41 | %
42 | % Note: rule order is important
43 | %
44 | % @param Axiom is an OWL axiom
45 | % @param SimplerAxiom is the same axiom possibly in a simpler form
46 | %
47 |
48 | % object property assertion
49 | simplify_axiom(
50 | 'ClassAssertion'('ObjectSomeValuesFrom'(OPE, 'ObjectOneOf'([I2])), I1),
51 | 'ObjectPropertyAssertion'(OPE, I1, I2)
52 | ) :- !.
53 |
54 | % data property assertion
55 | simplify_axiom(
56 | 'ClassAssertion'('DataHasValue'(DPE, Data), I1),
57 | 'DataPropertyAssertion'(DPE, I1, Data)
58 | ) :- !.
59 |
60 | % same individual
61 | simplify_axiom(
62 | 'ClassAssertion'('ObjectOneOf'([I2]), I1),
63 | 'SameIndividual'([I1, I2])
64 | ) :- !.
65 |
66 | % disjoint classes
67 | simplify_axiom(
68 | 'SubClassOf'(CE1, 'ObjectComplementOf'(CE2)),
69 | 'DisjointClasses'([CE1, CE2])
70 | ) :- !.
71 |
72 | % range
73 | simplify_axiom(
74 | 'SubClassOf'('ObjectIntersectionOf'([owl:'Thing', 'ObjectSomeValuesFrom'('ObjectInverseOf'(OPE), owl:'Thing')]), CE),
75 | 'ObjectPropertyRange'(OPE, CE)
76 | ) :- !.
77 |
78 | simplify_axiom(
79 | 'SubClassOf'('ObjectSomeValuesFrom'('ObjectInverseOf'(OPE), owl:'Thing'), CE),
80 | 'ObjectPropertyRange'(OPE, CE)
81 | ) :- !.
82 |
83 | % domain
84 | simplify_axiom(
85 | 'SubClassOf'('ObjectIntersectionOf'([owl:'Thing', 'ObjectSomeValuesFrom'(OPE, owl:'Thing')]), CE),
86 | 'ObjectPropertyDomain'(OPE, CE)
87 | ) :- !.
88 |
89 | simplify_axiom(
90 | 'SubClassOf'('ObjectSomeValuesFrom'(OPE, owl:'Thing'), CE),
91 | 'ObjectPropertyDomain'(OPE, CE)
92 | ) :- !.
93 |
94 | % Converts OWL 2 property axioms into a semantically equivalent yet
95 | % syntactically simplified form, so that the resulting axiom is more
96 | % backwards compatible with OWL 1. E.g. in case a property chain stands
97 | % for a transitivity then we represent it with the TransitiveObjectProperty-axiom.
98 | simplify_axiom(
99 | 'SubObjectPropertyOf'('ObjectPropertyChain'(['ObjectInverseOf'(R)]), 'ObjectInverseOf'(S)),
100 | 'SubObjectPropertyOf'(R, S)
101 | ) :- !.
102 |
103 | simplify_axiom(
104 | 'SubObjectPropertyOf'('ObjectPropertyChain'(['ObjectInverseOf'(R)]), S),
105 | 'SubObjectPropertyOf'(R, 'ObjectInverseOf'(S))
106 | ) :- !.
107 |
108 | simplify_axiom(
109 | 'SubObjectPropertyOf'('ObjectPropertyChain'([R]), S),
110 | 'SubObjectPropertyOf'(R, S)
111 | ) :- !.
112 |
113 | simplify_axiom(
114 | 'SubObjectPropertyOf'('ObjectPropertyChain'([R, R]), R),
115 | 'TransitiveObjectProperty'(R)
116 | ) :- !.
117 |
118 |
119 | % no change
120 | simplify_axiom(Axiom, Axiom).
121 |
--------------------------------------------------------------------------------
/prolog/utils/owlswrl/transform_anonymous.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(transform_anonymous, [
17 | transform_anonymous/2 % +TermIn, -TermOut
18 | ]).
19 |
20 | /** Transform Anonymous Individuals
21 |
22 | @author Tobias Kuhn
23 | @version 2007-10-29
24 | */
25 |
26 |
27 | %% transform_anonymous(+TermIn, -TermOut)
28 |
29 | transform_anonymous(TermIn, TermOut) :-
30 | transform_anonymous(TermIn, TermOut, [], _).
31 |
32 |
33 | transform_anonymous(Var, Var, Map, Map) :-
34 | var(Var),
35 | !.
36 |
37 | transform_anonymous(nodeID('$VAR'(LocalID)), nodeID(GlobalID), MapIn, MapOut) :-
38 | !,
39 | ( member((LocalID, GID), MapIn) ->
40 | GlobalID = GID,
41 | MapOut = MapIn
42 | ;
43 | GlobalID is random(1000000000000000000),
44 | MapOut = [(LocalID, GlobalID)|MapIn]
45 | ).
46 |
47 | transform_anonymous([], [], Map, Map) :-
48 | !.
49 |
50 | transform_anonymous([H1|T1], [H2|T2], MapIn, MapOut) :-
51 | !,
52 | transform_anonymous(H1, H2, MapIn, MapTemp),
53 | transform_anonymous(T1, T2, MapTemp, MapOut).
54 |
55 | transform_anonymous(Term, Term, Map, Map) :-
56 | Term =.. [Term],
57 | !.
58 |
59 | transform_anonymous(Term1, Term2, MapIn, MapOut) :-
60 | !,
61 | Term1 =.. List1,
62 | transform_anonymous(List1, List2, MapIn, MapOut),
63 | Term2 =.. List2.
64 |
--------------------------------------------------------------------------------
/prolog/utils/serialize_term.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(serialize_term, [
17 | serialize_term/1, % +Term
18 | serialize_term/2, % +Stream, +Term
19 | serialize_term_into_atom/2 % +Term, -Atom
20 | ]).
21 |
22 | /** Term serializer
23 |
24 | The purpose of this module is to provide a single official
25 | predicate for serializing Prolog terms that the Attempto
26 | tools produce (DRSs, token lists, OWL FSS, etc.).
27 |
28 | Serialized terms can be stored in files, sent over HTTP, etc.,
29 | so that they can be later read back into the exact same term.
30 |
31 | Essentially we provide a customized version of Prolog built-ins
32 | like write_canonical/[1,2] and writeq/[1,2].
33 |
34 | @author Kaarel Kaljurand
35 | @version 2009-03-20
36 |
37 | TODO:
38 |
39 | * test how \= (ACE non-equality) is serialized, maybe check character_escapes(bool, changeable)
40 | * find a way to print terms which contain variables so that the output
41 | has nice variable names (A vs _G123) but without the detour of numbervars,
42 | maybe check: print, portray
43 | * should we serialize singletons as '_'
44 | * we make an extra effort to locally undefine some operators, there must be a cleaner way
45 |
46 | */
47 |
48 | %% serialize_term(+Stream:stream, +Term:term) is det.
49 | %% serialize_term(+Term:term) is det.
50 | %
51 | % @param Stream is the output stream
52 | % @param Term is a term to be serialized
53 | %
54 | serialize_term(Stream, Term) :-
55 | numbervars(Term, 0, _),
56 | op(0, fy, -),
57 | op(0, fy, ~),
58 | op(0, xfx, =>),
59 | op(0, xfx, v),
60 | op(0, xfx, &),
61 | write_term(Stream, Term, [numbervars(true), quoted(true)]),
62 | fail ; true.
63 |
64 |
65 | serialize_term(Term) :-
66 | numbervars(Term, 0, _),
67 | op(0, fy, -),
68 | op(0, fy, ~),
69 | op(0, xfx, =>),
70 | op(0, xfx, v),
71 | op(0, xfx, &),
72 | write_term(Term, [numbervars(true), quoted(true)]),
73 | fail ; true.
74 |
75 |
76 | %% serialize_term_into_atom(+Term:term, -SerializedTerm:atom) is det.
77 | %
78 | % @param Term is a term to be serialized
79 | % @param SerializedTerm is the term serialized as an atom
80 | %
81 | serialize_term_into_atom(Term, SerializedTerm) :-
82 | with_output_to(atom(SerializedTerm), serialize_term(Term)).
83 |
--------------------------------------------------------------------------------
/prolog/utils/tree_utils.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(tree_utils, [
17 | unsplit_pronouns_in_tree/2, % +TreeIn, -TreeOut
18 | remove_gaps_in_tree/2, % +TreeIn, -TreeOut
19 | unify_coords_in_tree/2 % +TreeIn, -TreeOut
20 | ]).
21 |
22 | /** Tree Utils
23 |
24 | @author Tobias Kuhn
25 | */
26 |
27 | :- use_module(ace_niceace, [
28 | pronoun_split/2
29 | ]).
30 |
31 |
32 | %% unsplit_pronouns_in_tree(+TreeIn, -TreeOut)
33 |
34 | unsplit_pronouns_in_tree([], []).
35 |
36 | unsplit_pronouns_in_tree([np, [det, T1], [nbar, [n, T2]|RestIn]], [np, [pn, T]|RestOut]) :-
37 | pronoun_split(T, (T1, T2)),
38 | !,
39 | unsplit_pronouns_in_tree(RestIn, RestOut).
40 |
41 | unsplit_pronouns_in_tree([HeadIn|TailIn], [HeadOut|TailOut]) :-
42 | !,
43 | unsplit_pronouns_in_tree(HeadIn, HeadOut),
44 | unsplit_pronouns_in_tree(TailIn, TailOut).
45 |
46 | unsplit_pronouns_in_tree(Term, Term).
47 |
48 |
49 | %% remove_gaps_in_tree(+TreeIn, -TreeOut)
50 |
51 | remove_gaps_in_tree([], []).
52 |
53 | remove_gaps_in_tree([HeadIn|TailIn], TailOut) :-
54 | empty_branch(HeadIn),
55 | !,
56 | remove_gaps_in_tree(TailIn, TailOut).
57 |
58 | remove_gaps_in_tree([HeadIn|TailIn], [HeadOut|TailOut]) :-
59 | !,
60 | remove_gaps_in_tree(HeadIn, HeadOut),
61 | remove_gaps_in_tree(TailIn, TailOut).
62 |
63 | remove_gaps_in_tree(Term, Term).
64 |
65 |
66 | %% empty_branch(+Branch)
67 |
68 | empty_branch([]).
69 |
70 | empty_branch([_|Tail]) :-
71 | empty_branches(Tail).
72 |
73 |
74 | %% empty_branches(+BranchList)
75 |
76 | empty_branches([]).
77 |
78 | empty_branches([Head|Tail]) :-
79 | empty_branch(Head),
80 | empty_branches(Tail).
81 |
82 |
83 | %% unify_coords_in_tree(TreeIn, -TreeOut)
84 |
85 | unify_coords_in_tree(Leaf, Leaf) :-
86 | atomic(Leaf).
87 |
88 | unify_coords_in_tree(TreeIn, TreeOut) :-
89 | TreeIn = [Node, VP1, Coord, [Node|VP2Rest]],
90 | member(Node, [np_coord, vp_coord, s_coord, ap_coord]),
91 | !,
92 | unify_coords_in_tree(VP1, VP1T),
93 | unify_coords_in_tree([Node|VP2Rest], [Node|VP2RestT]),
94 | TreeOut = [Node, VP1T, Coord|VP2RestT].
95 |
96 | unify_coords_in_tree([Node|ChildrenIn], [Node|ChildrenOut]) :-
97 | atom(Node),
98 | !,
99 | unify_coords_in_tree(ChildrenIn, ChildrenOut).
100 |
101 | unify_coords_in_tree([FirstIn|RestIn], [FirstOut|RestOut]) :-
102 | unify_coords_in_tree(FirstIn, FirstOut),
103 | unify_coords_in_tree(RestIn, RestOut).
104 |
--------------------------------------------------------------------------------
/prolog/utils/trees_to_ascii.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(trees_to_ascii, [
17 | trees_to_ascii/2 % +SyntaxLists, -Ascii
18 | ]).
19 |
20 | /** ASCII trees
21 |
22 | This module creates ASCII graphics for syntax trees.
23 |
24 | @author Tobias Kuhn
25 | @version 2008-03-17
26 | */
27 |
28 |
29 | %% trees_to_ascii(+SyntaxLists, -Ascii)
30 | %
31 | % Returns the trees described by the syntax list as an atom (ASCII graphics).
32 |
33 | trees_to_ascii([], '').
34 |
35 | trees_to_ascii([FirstAndOnly], Ascii) :-
36 | tree_to_ascii(FirstAndOnly, Ascii),
37 | !.
38 |
39 | trees_to_ascii([First | Rest], Ascii) :-
40 | tree_to_ascii(First, AsciiFirst),
41 | trees_to_ascii(Rest, AsciiRest),
42 | format(atom(Ascii), '~w~n~w', [AsciiFirst, AsciiRest]).
43 |
44 |
45 | %% tree_to_ascii(+SyntaxList, -Ascii)
46 |
47 | tree_to_ascii(Tree, Ascii) :-
48 | retractall(char(_,_,_)),
49 | retractall(final_line(_)),
50 | depth(Tree, Depth),
51 | FinalLine is Depth * 2,
52 | assert(final_line(FinalLine)),
53 | draw_tree(Tree, 0, 0, _, _),
54 | get_ascii(0, Ascii).
55 |
56 |
57 | %% char(+Line, +Pos, -Char)
58 |
59 | :- dynamic(char/3).
60 |
61 |
62 | %% final_line(-FinalLine)
63 |
64 | :- dynamic(final_line/1).
65 |
66 |
67 | %% get_ascii(+Line, -Ascii)
68 |
69 | get_ascii(Line, Ascii) :-
70 | setof(P, C^char(Line,P,C), Ps),
71 | !,
72 | last(Ps, MaxPos),
73 | get_line(Line, 0, MaxPos, Atom),
74 | NewLine is Line + 1,
75 | get_ascii(NewLine, AsciiRest),
76 | atom_concat(Atom, '\n', AtomT),
77 | atom_concat(AtomT, AsciiRest, Ascii).
78 |
79 | get_ascii(_, '').
80 |
81 |
82 | %% get_line(+Line, +Pos, +End, -Ascii)
83 |
84 | get_line(_, Pos, End, '') :-
85 | Pos > End,
86 | !.
87 |
88 | get_line(Line, Pos, End, Ascii) :-
89 | ( char(Line, Pos, Char) ; Char = ' ' ),
90 | !,
91 | NewPos is Pos + 1,
92 | get_line(Line, NewPos, End, AsciiRest),
93 | atom_concat(Char, AsciiRest, Ascii).
94 |
95 |
96 | %% draw_tree(+Tree, +Line, +Start, -Head, -End)
97 |
98 | draw_tree(Tree, Line, Start, Start, End) :-
99 | (Tree = [Atom] ; Tree = Atom),
100 | atomic(Atom),
101 | !,
102 | atom_chars(Atom, AtomChars),
103 | final_line(FinalLine),
104 | draw_vertical_line(Start, Line, FinalLine-1),
105 | draw_chars(FinalLine, Start, AtomChars),
106 | length(AtomChars, Length),
107 | End is Start + Length.
108 |
109 | draw_tree([Parent|Children], Line, Start, Head, End) :-
110 | draw_children(Children, Line + 2, Start, ChildrenEnd, [FirstHead|HeadList]),
111 | last([FirstHead|HeadList], LastHead),
112 | draw_horizontal_line(Line + 1, FirstHead, LastHead),
113 | Head is (FirstHead + LastHead) // 2,
114 | atom_chars(Parent, ParentChars),
115 | draw_chars(Line, Head, ParentChars),
116 | draw_char(Line + 1, Head, '|'),
117 | length(ParentChars, Length),
118 | (ChildrenEnd > Head + Length -> End = ChildrenEnd ; End is Head + Length).
119 |
120 |
121 | %% draw_children(+Children, +Line, +Start, -End, -HeadList)
122 |
123 | draw_children([Child], Line, Start, End, [Head]) :-
124 | !,
125 | draw_tree(Child, Line, Start, Head, End).
126 |
127 | draw_children([Child|Rest], Line, Start, End, [Head|HeadList]) :-
128 | draw_tree(Child, Line, Start, Head, TempPos),
129 | draw_children(Rest, Line, TempPos + 1, End, HeadList).
130 |
131 |
132 | %% draw_chars(+Line, +Pos, -CharList)
133 |
134 | draw_chars(_, _, []).
135 |
136 | draw_chars(Line, Pos, [Char|Rest]) :-
137 | draw_char(Line, Pos, Char),
138 | NewPos is Pos + 1,
139 | draw_chars(Line, NewPos, Rest).
140 |
141 |
142 | %% draw_horizontal_line(+Line, +Start, +End)
143 |
144 | draw_horizontal_line(_, Start, End) :-
145 | Start > End,
146 | !.
147 |
148 | draw_horizontal_line(Line, Start, End) :-
149 | draw_char(Line, Start, '_'),
150 | draw_horizontal_line(Line, Start + 1, End).
151 |
152 |
153 | %% draw_vertical_line(+Pos, +LineStart, +LineEnd)
154 |
155 | draw_vertical_line(_, LineStart, LineEnd) :-
156 | LineStart > LineEnd,
157 | !.
158 |
159 | draw_vertical_line(Pos, LineStart, LineEnd) :-
160 | draw_char(LineStart, Pos, '|'),
161 | draw_vertical_line(Pos, LineStart + 1, LineEnd).
162 |
163 |
164 | %% draw_char(+Line, +Pos, +Char)
165 |
166 | draw_char(Line, Pos, Char) :-
167 | LineE is Line,
168 | PosE is Pos,
169 | asserta(char(LineE, PosE, Char)).
170 |
171 |
172 | %% depth(+List, -Depth)
173 |
174 | depth(Atom, 0) :-
175 | atomic(Atom).
176 |
177 | depth([Atom], 0) :-
178 | atomic(Atom),
179 | !.
180 |
181 | depth([H|T], D) :-
182 | depth(H, HD),
183 | depth(T, TD),
184 | (HD + 1 > TD -> D is HD + 1 ; D = TD).
185 |
--------------------------------------------------------------------------------
/prolog/utils/xmlterm_to_xmlatom.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- module(xmlterm_to_xmlatom, [
17 | xmlterm_to_xmlatom/2, % +XMLTerm, -XMLAtom
18 | xmlterm_to_xmlatom/3 % +XMLTerm, +Options, -XMLAtom
19 | ]).
20 |
21 | /** XML term to XML atom converter
22 |
23 | @author Tobias Kuhn
24 | @author Kaarel Kaljurand
25 | @version 2008-03-26
26 | */
27 |
28 | %% xmlterm_to_xmlatom(+XMLTerm, -XMLAtom) is det.
29 | %% xmlterm_to_xmlatom(+XMLTerm, +Options, -XMLAtom) is det.
30 | %
31 | % Transforms the term representation of an XML structure (using
32 | % element/3) into an atom.
33 | %
34 | % @param XMLTerm is an XML document as SWI's XML term
35 | % @param Options is a list of options for xml_write/3
36 | % @param XMLAtom is an XML document as an atom
37 | %
38 | xmlterm_to_xmlatom(XMLTerm, XMLAtom) :-
39 | xmlterm_to_xmlatom(XMLTerm, [], XMLAtom).
40 |
41 | xmlterm_to_xmlatom(XMLTerm, Options, XMLAtom) :-
42 | new_memory_file(MemHandle),
43 | open_memory_file(MemHandle, write, S),
44 | xml_write(S, XMLTerm, Options),
45 | close(S),
46 | memory_file_to_atom(MemHandle, XMLAtom).
47 |
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | prolog=swipl
2 |
3 | $prolog -g "working_directory(_, 'prolog/parser'), [fit_to_plp], halt."
4 | $prolog -g "[runape]."
5 |
--------------------------------------------------------------------------------
/runape.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 |
16 | :- use_module(prolog/utils/drs_to_drslist).
17 |
18 | :- use_module(prolog/parser/ace_to_drs).
19 | :- use_module(prolog/parser/ape_utils).
20 | :- use_module(prolog/parser/tokenizer).
21 | :- use_module(prolog/utils/morphgen, [
22 | acesentencelist_pp/2
23 | ]).
24 | :- use_module(prolog/utils/is_wellformed, [
25 | is_wellformed/1
26 | ]).
27 | :- use_module(prolog/utils/drs_to_ascii).
28 | :- use_module(prolog/utils/trees_to_ascii).
29 | :- use_module(prolog/utils/drs_to_ace, [
30 | drs_to_ace/2
31 | ]).
32 | :- use_module(prolog/logger/error_logger, [
33 | clear_messages/0,
34 | get_messages/1,
35 | is_error_message/4
36 | ]).
37 |
38 | :- set_prolog_flag(float_format, '%.11g').
39 |
40 | % Import the lexicons
41 | :- style_check(-singleton).
42 | :- style_check(-discontiguous).
43 | :- use_module(prolog/lexicon/clex).
44 | :- use_module(prolog/lexicon/ulex).
45 | :- style_check(+discontiguous).
46 | :- style_check(+singleton).
47 |
48 |
49 | %% ape is det.
50 | %
51 | %
52 | ape :-
53 | format('
54 | Attempto Parsing Engine for ACE 6.7~nCopyright 2008-2013, Attempto Group, University of Zurich
55 | This program comes with ABSOLUTELY NO WARRANTY.
56 | This is free software, and you are welcome to redistribute it under certain conditions.
57 | Please visit http://attempto.ifi.uzh.ch for details.
58 |
59 | For help, enter "help".~n~n', []),
60 | ape_input.
61 |
62 |
63 | %% ape_input is det.
64 | %
65 | %
66 | ape_input :-
67 | prompt(Old, 'APE> '),
68 | clear_messages,
69 | ape_utils:read_text_from_commandline(Text),
70 | prompt(_, Old),
71 | tokenizer:tokenize(Text, TokenList),
72 | !,
73 | call_parser(Text, TokenList).
74 |
75 |
76 | %% call_parser(Text:atom, Tokens:list) is det.
77 | %
78 | % @param Text is an ACE text or a commandline command
79 | % @param Tokens is a list of tokens (either of the ACE text or the command)
80 | %
81 | call_parser(_, [Quit]) :-
82 | (
83 | Quit = quit
84 | ;
85 | Quit = q
86 | ),
87 | !,
88 | nl, write('*** APE has been quit. ***'), nl.
89 |
90 | call_parser(_, [help]) :-
91 | nl, write('APE Prolog-commandline client\'s commands:'),
92 | nl, write(' spy X - spy predicate X'),
93 | nl, write(' gr - (re)compile grammar and contentwords'),
94 | nl, write(' trace - switch Prolog trace-mode on'),
95 | nl, write(' notrace - switch Prolog trace-mode off'),
96 | nl, write(' help - show this help'),
97 | nl, write(' quit/q - quit APE interface (relaunch with "ape.")'),
98 | nl, nl,
99 | !,
100 | ape_input.
101 |
102 | call_parser(_, [gr]) :-
103 | style_check(-discontiguous),
104 | style_check(-singleton),
105 | compile('prolog/parser/grammar.plp'),
106 | compile('prolog/parser/grammar_functionwords.plp'),
107 | compile('prolog/parser/grammar_contentwords.plp'),
108 | style_check(+discontiguous),
109 | style_check(+singleton),
110 | !,
111 | ape_input.
112 |
113 | call_parser(_, [trace]) :-
114 | trace,
115 | !,
116 | ape_input.
117 |
118 | call_parser(_, [notrace]) :-
119 | notrace,
120 | !,
121 | ape_input.
122 |
123 | call_parser(_, [spy, X]) :-
124 | spy(X),
125 | !,
126 | ape_input.
127 |
128 | call_parser(AceTextCodes, _) :-
129 | atom_codes(AceText, AceTextCodes),
130 | parse_and_format(AceText),
131 | !,
132 | ape_input.
133 |
134 | call_parser(_, _) :-
135 | ape_input.
136 |
137 |
138 | parse_and_format(AceText) :-
139 | ace_to_drs:aceparagraph_to_drs(AceText, Sentences, Syntaxtrees, UnresolvedDrs, Drs, Messages),
140 | format('~w~n~n', [Sentences]),
141 | format('Unresolved DRS:~n~n'),
142 | drs_to_ascii(UnresolvedDrs, UnresolvedDrsAscii),
143 | format('~w~n~n', [UnresolvedDrsAscii]),
144 | format('DRS:~n~n'),
145 | drs_to_ascii(Drs, DrsAscii),
146 | format('~w~n~n', [DrsAscii]),
147 |
148 | format('DRS List:~n~n'),
149 | drs_to_drslist:drs_to_drslist(Drs, DrsList),
150 | maplist(drs_to_ascii, DrsList, DrsAsciiList),
151 | maplist(writeln, DrsAsciiList),
152 |
153 | trees_to_ascii(Syntaxtrees, SyntaxtreesAscii),
154 | format('~w~n~n', [SyntaxtreesAscii]),
155 | (
156 | is_wellformed(Drs)
157 | ->
158 | true
159 | ;
160 | format("WARNING: The DRS is not well-formed!!!~n~n", [])
161 | ),
162 | drs_to_ace(Drs, AceSentenceList),
163 | acesentencelist_pp(AceSentenceList, Paraphrase),
164 | format('~w~n~n', [Paraphrase]),
165 | print_messages(Messages).
166 |
167 |
168 | %% print_messages(+MessageList:list) is det.
169 | %
170 | % @param MessageList is a list of messages
171 | %
172 | print_messages([]) :- nl.
173 |
174 | print_messages([H | T]) :-
175 | format('~w~n~n', [H]),
176 | print_messages(T).
177 |
178 | %%
179 | %
180 | %
181 | %
182 | make_ape :-
183 | working_directory(Old, 'prolog/parser'),
184 | compile(fit_to_plp),
185 | working_directory(_, Old),
186 | make.
187 |
188 |
189 | % Note: we load the interface at startup
190 | :- ape.
191 |
--------------------------------------------------------------------------------
/tests/.gitignore:
--------------------------------------------------------------------------------
1 | /tmp
2 |
--------------------------------------------------------------------------------
/tests/README.md:
--------------------------------------------------------------------------------
1 | Testing APE
2 | ===========
3 |
4 | Author: Kaarel Kaljurand
5 |
6 | Version: 2019-08-09
7 |
8 | Introduction
9 | ------------
10 |
11 | This document explains how to test APE including the various DRS translators
12 | that APE contains.
13 |
14 | All the test scripts in this directory depend on a larger lexicon than included
15 | with APE. In order to download the required lexicon, first run
16 |
17 | swipl -f none -g ensure_clex -t halt -s downloader.pl
18 |
19 |
20 | ### APE Regression test
21 |
22 | To regression test APE, just run:
23 |
24 | bash rtest.bash
25 |
26 | or if you want to download the latest regression testset first
27 | then run:
28 |
29 | swipl -f none -g download_acetexts -t halt -s downloader.pl
30 |
31 | A file with a timestamp containing the regression test results
32 | along with APE's output is stored into the `testruns`-directory.
33 |
34 | In order to get a digest of the testrun, grep the file
35 | for regression tester messages, e.g.:
36 |
37 | cat testruns/rtest_050601-1310.txt | grep "^0"
38 |
39 | or cat an already filtered file:
40 |
41 | cat tmp/now.txt
42 |
43 | In order to explore the erronous DRSes, open the file and search
44 | for the strings
45 |
46 | - `0000` (Correctly generated an empty DRS)
47 | - `----` (Correctly generated a DRS which is not empty)
48 | - `0->#` (Failed to generate an empty DRS)
49 | - `#->0` (Incorrectly generated an empty DRS)
50 | - `####` (DRSs which are not empty do not match.)
51 |
52 | To get a listing of all the regressions:
53 |
54 | cat tmp/now.txt | grep "\[.*#.*\]"
55 |
56 | Note: the regression testing is only tested with SWI-Prolog.
57 | It is assumed that SWI-Prolog is called `swipl`,
58 | if it is not the case then modify `rtest.bash` accordingly
59 | or set a symbolic link, e.g.:
60 |
61 | ln -s `which pl` swipl
62 |
63 | Runtime of the complete test run on different machines:
64 |
65 | - Mac OS X G4: ~25 seconds (~3000 testcases)
66 | - Intel i3, 2011-06-20: ~11 seconds (3613 test cases, excluding bug reports)
67 | - Intel i7, 2016-04-02: ~9 seconds (3733 test cases, excluding bug reports, including loading the large lexicon from a flat file)
68 |
69 |
70 | ### Testing Drace Core and Drace NP
71 |
72 | Running the test:
73 |
74 | echo "[test_drace]. test_drace(core)." | swipl > testruns/drace_test_results.txt
75 | echo "[test_drace]. test_drace(np)." | swipl > testruns/dracenp_test_results.txt
76 |
77 | Getting an overview of the problems by filtering out certain testcases
78 | that point to pseudo-problems.
79 |
80 | cat testruns/drace_test_results.txt | grep "FAIL" | grep -v ":" | grep -v "ach of" | wc
81 |
82 |
83 | ### Running all the tests
84 |
85 | time bash test_everything.sh > out.txt 2> err.txt
86 |
87 | This takes about
88 |
89 | - 55 seconds on an i3 Linux laptop with SWI-Prolog v6.
90 | - 45 seconds on an i7 Linux laptop with SWI-Prolog v7.
91 |
--------------------------------------------------------------------------------
/tests/bugs_and_requests.pl:
--------------------------------------------------------------------------------
1 | /**
2 | * Convert all bug reports / feature requests to HTML.
3 | * Two types of HTML output are supported
4 | *
5 | * "linear" (default) is simple linear output where reports follow each other
6 | * in a linear fashion
7 | *
8 | * "table" is a sortable HTML-table with columns for bug ID, report date, text, DRS, ...
9 | *
10 | * Usage:
11 | *
12 | * swipl -f bugs_and_requests.pl -g main -t halt > report.html
13 | * swipl -f bugs_and_requests.pl -g "main(table)" -t halt > report.html
14 | *
15 | * @author Kaarel Kaljurand
16 | * @version 2011-06-22
17 | *
18 | * @tbd Escape HTML special symbols (< and &)
19 | */
20 |
21 |
22 | % We point to the directory where APE modules and the lexicons are located.
23 | :- assert(user:file_search_path(ape, '../prolog')).
24 |
25 | % We point to the directory where the regression test set is located.
26 | :- assert(user:file_search_path(rt, '.')).
27 |
28 |
29 | :- use_module(ape(utils/drs_to_html), [
30 | drs_to_html_nocontainer/2,
31 | footer/1
32 | ]).
33 |
34 |
35 | % Consult the regression test set.
36 | :- style_check(-singleton).
37 | :- consult(rt(acetexts)).
38 | :- style_check(+singleton).
39 |
40 | :- style_check(-atom).
41 |
42 | main :-
43 | main(linear).
44 |
45 | main(Type) :-
46 | current_stream(1, write, Stream),
47 | set_stream(Stream, encoding(utf8)),
48 | header('APE bugs and ACE feature requests', Header),
49 | footer(Footer),
50 | write(Header),
51 | write('APE bugs and ACE feature requests'),
52 | make_another_header(Type),
53 | forall(
54 | text_drs_eval(1, Id, Text, Drs, _Syntax, Date, Author, Comment),
55 | ignore((
56 | drs_to_html_nocontainer(Drs, HtmlDrs),
57 | display(Type, Id, Text, Date, Author, Comment, HtmlDrs)
58 | ))
59 | ),
60 | make_another_footer(Type),
61 | write(Footer).
62 |
63 |
64 | display(linear, Id, Text, Date, Author, Comment, HtmlDrs) :-
65 | format(' ~n~d~n~w ~nComment: ~w ~n~w~nSubmitted: ~w by ~w ~n', [Id, Text, Comment, HtmlDrs, Date, Author]).
66 |
67 | display(table, Id, Text, Date, Author, Comment, HtmlDrs) :-
68 | concat_atom([Year, Month, Day | _], '-', Date),
69 | format('
70 | ~d |
71 | ~w |
72 | ~w |
73 | ~w |
74 | ~w |
75 | ~w | ', [Id, Year-Month-Day, Text, Comment, HtmlDrs, Author]).
76 |
77 | make_another_header(table) :-
78 | !,
79 | write('Click on a column header to sort by that column.
80 |
81 | ID |
82 | Date |
83 | ACE text |
84 | Comment |
85 | DRS |
86 | Author |
87 | ').
88 |
89 | make_another_header(_).
90 |
91 |
92 | make_another_footer(table) :-
93 | !,
94 | write(' ').
95 |
96 | make_another_footer(_).
97 |
98 |
99 | %% header(+Title:atom, -Header:atom) is det.
100 | %
101 | % Generate an HTML-header.
102 | %
103 | % @param Title is the content for the title-element in the HTML-header
104 | % @param Header is an HTML header
105 | %
106 | header(Title, Header) :-
107 | with_output_to(atom(Header), format('
108 |
109 |
110 |
111 | ~w
112 |
113 |
114 |
115 |
120 |
135 |
136 | ', [Title])).
137 |
--------------------------------------------------------------------------------
/tests/downloader.pl:
--------------------------------------------------------------------------------
1 | % Usage:
2 | % $ swipl -f none -g ensure_clex -t halt -s downloader.pl
3 | % $ swipl -f none -g download_acetexts -t halt -s downloader.pl
4 |
5 | clex_remote_local('https://raw.github.com/Attempto/Clex/master/clex_lexicon.pl', 'clex_lexicon.pl').
6 | acetexts_remote_local('http://attempto.ifi.uzh.ch/cgi-bin/acetextset/get_acetexts.cgi', 'acetexts.pl').
7 |
8 | %! ensure_clex
9 | %
10 | % Download the CLex lexicon if not already present.
11 |
12 | ensure_clex :-
13 | clex_remote_local(Url, Filename),
14 | (exists_file(Filename) -> true ; download(Url, Filename)).
15 |
16 | %! download_acetexts
17 | %
18 | % Download the APE regression testsuite.
19 |
20 | download_acetexts :-
21 | acetexts_remote_local(Url, Filename),
22 | download(Url, Filename).
23 |
24 | download(Url, Filename) :-
25 | format(user_error, "Saving ~w as ~w~n", [Url, Filename]),
26 | use_module(library(http/http_open)),
27 | setup_call_cleanup(
28 | (
29 | http_open(Url, In, []),
30 | set_stream(In, encoding(utf8))
31 | ),
32 | setup_call_cleanup(
33 | open(Filename, write, Out),
34 | copy_stream_data(In, Out),
35 | close(Out)
36 | ),
37 | close(In)
38 | ).
39 |
--------------------------------------------------------------------------------
/tests/make_acetext_drs.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2010-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 | /**
16 | This program outputs
17 |
18 | ==
19 | acetext_drs(Id, ACEText, DRS).
20 | ==
21 |
22 | for every ACE text in the regression test set that passes the test.
23 |
24 | Configuration: change user:file_search_path/2 (first two rules in this program)
25 | to specify the path to APE and to the regression test set.
26 |
27 |
28 | BUG: there is a lot of code overlap with test_ape.pl.
29 |
30 |
31 | Usage:
32 |
33 | ==
34 | swipl -f make_acetext_drs.pl -g main -t halt -q > acetext_drs.pl
35 | ==
36 |
37 | @author Kaarel Kaljurand
38 | @version 2011-07-21
39 |
40 | */
41 |
42 | % We point to the directory where APE modules and the lexicons are located.
43 | :- assert(user:file_search_path(ape, '../prolog')).
44 |
45 | % We point to the directory where the regression test set is located.
46 | :- assert(user:file_search_path(rt, '.')).
47 |
48 |
49 | :- use_module(ape(parser/ace_to_drs), [
50 | acetext_to_drs/5
51 | ]).
52 |
53 | :- use_module(ape(utils/are_equivalent), [
54 | are_equivalent/2
55 | ]).
56 |
57 | :- use_module(ape(utils/serialize_term), [
58 | serialize_term/1
59 | ]).
60 |
61 | % Consult the regression test set.
62 | :- style_check(-singleton).
63 | :- consult(rt(acetexts)).
64 | :- style_check(+singleton).
65 |
66 | % Everything which takes longer than 1 second is considered a bug.
67 | time_limit(1).
68 |
69 | %% main is det.
70 | %
71 | main :-
72 | time_limit(TimeLimit),
73 | catch(set_stream(user_output, encoding(utf8)), _, true),
74 | writeln(':- encoding(utf8).'),
75 | forall(
76 | text_drs_eval(0, Number, Text, DrsPre, _Syntax, _TestDate, _Author, _Comment),
77 | (
78 | remove_pn_conditions(DrsPre, Drs),
79 | run_test(TimeLimit, Number, Text, Drs)
80 | )
81 | ).
82 |
83 |
84 | % Removes the object conditions for proper names from the old DRSs of the test set.
85 | % BUG: This should be done at a different place!
86 | remove_pn_conditions(drs(DomIn,CondsIn), drs(DomOut,CondsOut)) :-
87 | exclude(is_named, CondsIn, CondsOut),
88 | exclude(ground, DomIn, DomOut).
89 |
90 | is_named(object(named(Name), Name, named, _, _, _)-_).
91 |
92 |
93 | run_test(TimeLimit, Number, Text, Drs) :-
94 | catch(
95 | call_with_time_limit(
96 | TimeLimit,
97 | (
98 | acetext_to_drs(Text, _, _, RealDrs, _),
99 | result(Drs, RealDrs, Result)
100 | )
101 | ),
102 | CatchType,
103 | Result = CatchType
104 | ),
105 | show_result(Result, Number, Text, RealDrs).
106 |
107 |
108 | %% result(+Drs1:term, +Drs2:term, -ResultCode:atom) is det.
109 | %
110 | % Compares two DRSs and returns a ResultCode which is to be interpreted as follows:
111 | %
112 | % * =|0000|= - parsing fails as it should
113 | % * =|0->#|= - parsing should fail but instead a non-empty DRS is produced
114 | % * =|#->0|= - parsing should produce a non-empty DRS but instead it fails
115 | % * =|####|= - parsing produces a non-empty DRS but it is different from what it should be
116 | % * =|----|= - parsing produces a DRS that is equivalent to the one stored in the regression test set
117 | %
118 | % Note: it is important that Drs1 and Drs2 contain variables for discourse referents.
119 | %
120 | % @param Drs1 is Attempto DRS
121 | % @param Drs2 is Attempto DRS
122 | % @param ResultCode is one of {=|0000|=, =|0->#|=, =|#->0|=, =|####|=, =|----|=}
123 | %
124 | result(drs([], []), drs([], []), '0000') :- !.
125 |
126 | result(drs([], []), Drs, '0->#') :- Drs \= drs([], []), !.
127 |
128 | result(Drs, drs([], []), '#->0') :- Drs \= drs([], []), !.
129 |
130 | result(Drs1, Drs2, '----') :-
131 | are_equivalent(Drs1, Drs2),
132 | !.
133 |
134 | result(_, _, '####').
135 |
136 |
137 | %
138 | %
139 | show_result('####', _Number, _Text, _Drs) :- !.
140 | show_result('0->#', _Number, _Text, _Drs) :- !.
141 | show_result('#->0', _Number, _Text, _Drs) :- !.
142 |
143 | show_result(_, Number, Text, Drs) :-
144 | serialize_term(acetext_drs(Number, Text, Drs)), writeln('.').
145 |
--------------------------------------------------------------------------------
/tests/rtest.bash:
--------------------------------------------------------------------------------
1 | # APE regression tester
2 | #
3 | # Usage:
4 | #
5 | # bash rtest.bash
6 | #
7 | # @author Kaarel Kaljurand
8 | # @version 2019-08-10
9 |
10 | prolog=swipl
11 | #prolog=`which swipl`
12 |
13 | echo "Using: `$prolog --version`"
14 |
15 | # Generate a timestamp.
16 | timestamp=`date '+%y%m%d-%H%M'`
17 |
18 | # Ensures a directory for the test results.
19 | mkdir -p testruns/
20 |
21 | # Convert fit-files into plp-files.
22 | $prolog -g "working_directory(_, '../prolog/parser'), [fit_to_plp], halt."
23 |
24 | # Run the regression test.
25 | #time echo "[test_ape]. main. halt." | $prolog -q > testruns/rtest_$timestamp.txt
26 | time $prolog -f test_ape.pl -g main -t halt -q > testruns/rtest_$timestamp.txt
27 |
28 | echo ""
29 | echo "Regression tester finished."
30 | echo "The results of the regression test were saved into testruns/rtest_$timestamp.txt"
31 |
32 | echo ""
33 | echo "Diff with the previous version:"
34 | echo ""
35 |
36 | mkdir -p tmp/
37 | ls testruns/rtest*.txt | tail -2 | head -1 | xargs grep "^0" > tmp/before.txt
38 | ls testruns/rtest*.txt | tail -1 | xargs grep "^0" > tmp/now.txt
39 | diff tmp/before.txt tmp/now.txt
40 |
41 | echo ""
42 | echo "Finished."
43 |
--------------------------------------------------------------------------------
/tests/test_ape.pl:
--------------------------------------------------------------------------------
1 | % This file is part of the Attempto Parsing Engine (APE).
2 | % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
3 | %
4 | % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it
5 | % under the terms of the GNU Lesser General Public License as published by the Free Software
6 | % Foundation, either version 3 of the License, or (at your option) any later version.
7 | %
8 | % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT
9 | % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | % PURPOSE. See the GNU Lesser General Public License for more details.
11 | %
12 | % You should have received a copy of the GNU Lesser General Public License along with the Attempto
13 | % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/.
14 |
15 | /**
16 | APE regression tester
17 |
18 | This program compares a stored and manually checked DRS (taken from the APE regression test set)
19 | with an automatically generated DRS for the same ACE text.
20 | If they do not match then a failure message along with both DRSs are displayed.
21 | The matching algorithm is defined in the APE module =|utils/are_equivalent.pl|=.
22 |
23 | Configuration:
24 |
25 | * change the first line of this program to match your SWI-Prolog installation
26 | * change user:file_search_path/2 (first two rules in this program)
27 | to specify the path to APE and to the regression test set
28 |
29 |
30 | Usage:
31 |
32 | ==
33 | swipl -f test_ape.pl -g main -t halt -q
34 | ==
35 |
36 | Documentation:
37 |
38 | Read the PlDoc comments in the source code to find out how to interpret the result codes
39 | that this program outputs.
40 |
41 | @author Kaarel Kaljurand
42 | @version 2011-07-28
43 |
44 | */
45 |
46 | % We point to the directory where APE modules and the lexicons are located.
47 | :- assert(user:file_search_path(ape, '../prolog')).
48 |
49 | % We point to the directory where the regression test set is located.
50 | :- assert(user:file_search_path(rt, '.')).
51 |
52 |
53 | :- use_module(ape(parser/ace_to_drs), [
54 | acetext_to_drs/5
55 | ]).
56 |
57 | :- use_module(ape(utils/are_equivalent), [
58 | are_equivalent/2
59 | ]).
60 |
61 | :- use_module(ape(utils/drs_to_ascii)).
62 |
63 | % Import the lexicons.
64 | :- style_check(-discontiguous).
65 | :- consult(clex:clex_lexicon).
66 | :- style_check(+discontiguous).
67 |
68 | % Consult the regression test set.
69 | :- style_check(-singleton).
70 | :- consult(rt(acetexts)).
71 | :- style_check(+singleton).
72 |
73 |
74 | % Everything which takes longer than 1 second is considered a bug.
75 | time_limit(1).
76 |
77 | %
78 | % Applies APE to every ACE text that is a part of a positive regression test case,
79 | % and compares the resulting DRS to the DRS that is stored in the regression test set.
80 | %
81 | main :-
82 | time_limit(TimeLimit),
83 | get_time(Timestamp),
84 | format_time(atom(FormattedTimestamp), 'Timestamp: %F %T%z', Timestamp),
85 | writeln(FormattedTimestamp),
86 | forall(
87 | text_drs_eval(0, Number, Text, DrsPre, _Syntax, _TestDate, _Author, _Comment),
88 | (
89 | remove_pn_conditions(DrsPre, Drs),
90 | run_test(TimeLimit, Number, Text, Drs)
91 | )
92 | ).
93 |
94 |
95 | % Removes the object conditions for proper names from the old DRSs of the test set.
96 | % BUG: This should be done at a different place!
97 | remove_pn_conditions(drs(DomIn,CondsIn), drs(DomOut,CondsOut)) :-
98 | exclude(is_named, CondsIn, CondsOut),
99 | exclude(ground, DomIn, DomOut).
100 |
101 | is_named(object(named(Name), Name, named, _, _, _)-_).
102 |
103 |
104 | run_test(TimeLimit, Number, Text, Drs) :-
105 | catch(
106 | call_with_time_limit(
107 | TimeLimit,
108 | (
109 | acetext_to_drs(Text, _, _, RealDrs, Messages),
110 | result(Drs, RealDrs, Result)
111 | )
112 | ),
113 | CatchType,
114 | Result = CatchType
115 | ),
116 | display_result(Result, Number, Text, Messages),
117 | (
118 | Result = '####'
119 | ->
120 | display_drs(Drs), nl,
121 | display_drs(RealDrs)
122 | ;
123 | true
124 | ).
125 |
126 |
127 |
128 | %% result(+Drs1:term, +Drs2:term, -ResultCode:atom) is det.
129 | %
130 | % Compares two DRSs and returns a ResultCode which is to be interpreted as follows:
131 | %
132 | % * =|0000|= - parsing fails as it should
133 | % * =|0->#|= - parsing should fail but instead a non-empty DRS is produced
134 | % * =|#->0|= - parsing should produce a non-empty DRS but instead it fails
135 | % * =|####|= - parsing produces a non-empty DRS but it is different from what it should be
136 | % * =|----|= - parsing produces a DRS that is equivalent to the one stored in the regression test set
137 | %
138 | % Note: it is important that Drs1 and Drs2 contain variables for discourse referents.
139 | %
140 | % @param Drs1 is Attempto DRS
141 | % @param Drs2 is Attempto DRS
142 | % @param ResultCode is one of {=|0000|=, =|0->#|=, =|#->0|=, =|####|=, =|----|=}
143 | %
144 | result(drs([], []), drs([], []), '0000') :- !.
145 |
146 | result(drs([], []), Drs, '0->#') :- Drs \= drs([], []), !.
147 |
148 | result(Drs, drs([], []), '#->0') :- Drs \= drs([], []), !.
149 |
150 | result(Drs1, Drs2, '----') :-
151 | are_equivalent(Drs1, Drs2),
152 | !.
153 |
154 | result(_, _, '####').
155 |
156 |
157 | %% display_results(+ResultCode:atom, +Number:number, +Text:atom, +Messages:list) is det.
158 | %
159 | % Pretty-prints the result of DRS comparison.
160 | % Note: Messages are currently not output.
161 | %
162 | % @param ResultCode is one of {=|0000|=, =|0->#|=, =|#->0|=, =|####|=, =|----|=}
163 | % @param Number is the ID-number of the test case
164 | % @param Text is the ACE text
165 | % @param Messages is a list of possible parser error messages
166 | %
167 | display_result(Result, Number, Text, _) :-
168 | format('~n~*t~d~6| [~w] ~q~n', [0'0, Number, Result, Text]).
169 |
170 | %display_result(Result, Number, Text, [Message | Messages]) :-
171 | % format('~n~*t~d~6| [~w] ~q ~w~n', [0'0, Number, Result, Text, [Message | Messages]]).
172 |
--------------------------------------------------------------------------------
/tests/test_apeexe.sh:
--------------------------------------------------------------------------------
1 |
2 | ape=../ape.exe
3 |
4 | # This test should print out 9 times:
5 | #
6 | # If there is a user X1 then Attempto_Parsing_Engine helps the user X1.
7 | #
8 |
9 | file_file1=../../web/site/acetexts/example1.ace.txt
10 | file_url1=http://attempto.ifi.uzh.ch/site/acetexts/example1.ace.txt
11 | ulexfile_file1=../../web/site/acetexts/example1.ulex.pl
12 | ulexfile_url1=http://attempto.ifi.uzh.ch/site/acetexts/example1.ulex.pl
13 |
14 | $ape -text "APE helps every user." -ulextext "pn_sg('APE', 'Attempto_Parsing_Engine', neutr). pn_pl('APEs', 'Attempto_Parsing_Engines', neutr)." -solo paraphrase1
15 | $ape -text "APE helps every user." -ulexfile $ulexfile_file1 -solo paraphrase1
16 | $ape -text "APE helps every user." -ulexfile $ulexfile_url1 -solo paraphrase1
17 |
18 | $ape -file $file_file1 -ulextext "pn_sg('APE', 'Attempto_Parsing_Engine', neutr). pn_pl('APEs', 'Attempto_Parsing_Engines', neutr)." -solo paraphrase1
19 | $ape -file $file_file1 -ulexfile $ulexfile_file1 -solo paraphrase1
20 | $ape -file $file_file1 -ulexfile $ulexfile_url1 -solo paraphrase1
21 |
22 | $ape -file $file_url1 -ulextext "pn_sg('APE', 'Attempto_Parsing_Engine', neutr). pn_pl('APEs', 'Attempto_Parsing_Engines', neutr)." -solo paraphrase1
23 | $ape -file $file_url1 -ulexfile $ulexfile_file1 -solo paraphrase1
24 | $ape -file $file_url1 -ulexfile $ulexfile_url1 -solo paraphrase1
25 |
26 |
27 | # This test should preserve the Unicode characters.
28 |
29 | file_file2=../../web/site/acetexts/example2.ace.txt
30 |
31 | $ape -file $file_file2 -solo paraphrase1
32 |
--------------------------------------------------------------------------------
/tests/test_drace.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/swipl -f none -g test_drace(core) -t halt -s
2 |
3 | /**
4 | * @title Test Drace Core or Drace NP
5 | * @author Kaarel Kaljurand
6 | * @version 2009-04-08
7 | *
8 | * This program tests the module drs_to_coreace.pl (or drs_to_npace.pl)
9 | * by applying the composition
10 | *
11 | * ace_to_drs o drs_to_coreace (or drs_to_npace)
12 | *
13 | * to all the correct DRSs in the regression testset.
14 | *
15 | * The test on a given DRS is correct if the composition acts as identity.
16 | *
17 | *
18 | * Usage:
19 | *
20 | * echo "[test_drace]. test_drace(core)." | swipl > drace_test_results.txt
21 | * echo "[test_drace]. test_drace(np)." | swipl > dracenp_test_results.txt
22 | *
23 | * and then compare the results by diff, e.g.:
24 | *
25 | * diff testruns/drace_test_results.txt drace_test_results.txt
26 | * diff testruns/dracenp_test_results.txt dracenp_test_results.txt
27 | *
28 | * Note that the files in the directory testruns/ are under version control.
29 | * They reflect a stable state of the verbalizer. Comparing against them helps
30 | * to detect regression in the verbalizer.
31 | */
32 |
33 | % We point to the directory where APE modules and the lexicons are located.
34 | :- assert(user:file_search_path(ape, '../prolog')).
35 |
36 | % We point to the directory where the regression test set is located.
37 | :- assert(user:file_search_path(rt, '.')).
38 |
39 | % Consult the regression test set.
40 | :- style_check(-singleton).
41 | :- consult(rt(acetexts)).
42 | :- style_check(+singleton).
43 |
44 | :- use_module(ape('parser/ace_to_drs'), [
45 | acetext_to_drs/5
46 | ]).
47 |
48 | :- use_module(ape('utils/morphgen'), [
49 | acesentencelist_pp/2
50 | ]).
51 |
52 | :- use_module(ape('utils/are_equivalent')).
53 | :- use_module(ape('utils/drs_to_coreace')).
54 | :- use_module(ape('utils/drs_to_npace')).
55 | :- use_module(ape('utils/drs_to_ascii')).
56 |
57 | % Import the lexicons
58 | :- style_check(-discontiguous).
59 | :- consult(clex:clex_lexicon).
60 | :- style_check(+discontiguous).
61 |
62 | :- set_prolog_flag(float_format, '%.11g').
63 |
64 | time_limit(3).
65 |
66 | test_drace(DraceType) :-
67 | time_limit(TimeLimit),
68 | set_stream(user_output, encoding(utf8)),
69 | forall(
70 | text_drs_eval(0, Number, Text, PreDrs, _Syntax, _Date, _Author, _Comment),
71 | (
72 | remove_pn_conditions(PreDrs, Drs),
73 | run_test(TimeLimit, DraceType, Number, Text, Drs)
74 | )
75 | ).
76 |
77 |
78 | % Removes the object conditions for proper names from the old DRSs of the test set.
79 | % BUG: This should be done at a different place!
80 | remove_pn_conditions(drs(DomIn,CondsIn), drs(DomOut,CondsOut)) :-
81 | exclude(is_named, CondsIn, CondsOut),
82 | exclude(ground, DomIn, DomOut).
83 |
84 | is_named(object(named(Name), Name, named, _, _, _)-_).
85 |
86 |
87 | run_test(TimeLimit, DraceType, Number, Text1, Drs1) :-
88 | catch(
89 | call_with_time_limit(
90 | TimeLimit,
91 | (
92 | execute_test(DraceType, Drs1, Text2, Drs2),
93 | compare_results(Drs1, Drs2, Result)
94 | )
95 | ),
96 | CatchType,
97 | (
98 | Result = CatchType,
99 | Text2 = ''
100 | )),
101 | display_result(Result, Number, Text1, Text2).
102 |
103 |
104 | execute_test(core, Drs1, AceText, Drs2) :-
105 | bigdrs_to_coreace(Drs1, AceSentenceList),
106 | get_acetext_or_error(AceSentenceList, AceText),
107 | acetext_to_drs(AceText, _, _, Drs2, _Messages).
108 |
109 | execute_test(np, Drs1, AceText, Drs2) :-
110 | drs_to_npace(Drs1, AceSentenceList),
111 | get_acetext_or_error(AceSentenceList, AceText),
112 | acetext_to_drs(AceText, _, _, Drs2, _Messages).
113 |
114 |
115 | % In case the DRS (correctly) fails, we do not report it as ----.
116 | compare_results(drs([], []), _, 'ZERO') :-
117 | !.
118 |
119 | compare_results(Drs1, Drs2, '----') :-
120 | are_equivalent(Drs1, Drs2, [ignore_sid(true)]),
121 | !.
122 |
123 | compare_results(_, _, 'FAIL').
124 |
125 |
126 | %% display_result(+Result:atom, +Number:integer, +Text1:atom, +Text2:atom)
127 | %
128 | %
129 | display_result('ZERO', Number, Text1, _) :-
130 | !,
131 | format('~*t~d~6| [~w] ~w~n', [0'0, Number, 'ZERO', Text1]).
132 |
133 | display_result('----', Number, Text1, Text2) :-
134 | Text1 = Text2,
135 | !,
136 | format('~*t~d~6| [~w] ~w~n', [0'0, Number, 'SAME', Text1]).
137 |
138 | display_result(Result, Number, Text1, Text2) :-
139 | format('~*t~d~6| [~w] ~w --> ~w~n', [0'0, Number, Result, Text1, Text2]).
140 |
141 |
142 | %%
143 | %
144 | %
145 | get_acetext_or_error([], 'NOT IMPLEMENTED') :-
146 | !.
147 |
148 | get_acetext_or_error(AceSentenceList, AceText) :-
149 | acesentencelist_pp(AceSentenceList, AceText).
150 |
--------------------------------------------------------------------------------
/tests/test_drs_to_x.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/swipl -f none -g main -t halt -s
2 |
3 | /**
4 | *
5 | * @title Test the conversion of DRS to other formats
6 | * @author Kaarel Kaljurand
7 | * @version 2009-06-24
8 | *
9 | * This is an attempt to write a more general testing framework
10 | * for testing DRS->X converters on the APE regression test set.
11 | * Currently it just tests the TPTP converter.
12 | *
13 | * TODO: Integrate result codes into the header.
14 | *
15 | */
16 |
17 | % We point to the directory where APE modules and the lexicons are located.
18 | :- assert(user:file_search_path(ape, '../prolog')).
19 |
20 | % We point to the directory where the regression test set is located.
21 | :- assert(user:file_search_path(rt, '.')).
22 |
23 | % Consult the regression test set.
24 | :- style_check(-singleton).
25 | :- consult(rt(acetexts)).
26 | :- style_check(+singleton).
27 |
28 | :- use_module(ape('parser/ace_to_drs'), [
29 | acetext_to_drs/5
30 | ]).
31 |
32 | :- use_module(ape('utils/drs_to_tptp'), [
33 | drs_to_tptp/2,
34 | drs_to_tptplist/2,
35 | tptp_pp/1,
36 | tptplist_pp/1
37 | ]).
38 |
39 | % Import the lexicons
40 | :- style_check(-discontiguous).
41 | :- consult(clex:clex_lexicon).
42 | :- style_check(+discontiguous).
43 |
44 | :- set_prolog_flag(float_format, '%.11g').
45 |
46 | time_limit(1).
47 | drs_converter(drs_to_tptplist, tptplist_pp).
48 |
49 | main :-
50 | time_limit(TimeLimit),
51 | drs_converter(Converter, Pp),
52 | set_stream(user_output, encoding(utf8)),
53 | forall(
54 | text_drs_eval(0, Number, Text, DrsPre, _Syntax, _Date, _Author, _Comment),
55 | (
56 | remove_pn_conditions(DrsPre, Drs),
57 | run_test(TimeLimit, Converter, Pp, Number, Text, Drs)
58 | )
59 | ).
60 |
61 | % Removes the object conditions for proper names from the old DRSs of the test set.
62 | % BUG: This should be done at a different place!
63 | remove_pn_conditions(drs(DomIn,CondsIn), drs(DomOut,CondsOut)) :-
64 | exclude(is_named, CondsIn, CondsOut),
65 | exclude(ground, DomIn, DomOut).
66 |
67 | is_named(object(named(Name), Name, named, _, _, _)-_).
68 |
69 |
70 | run_test(TimeLimit, Converter, Pp, Number, Text, Drs) :-
71 | display_header(Number, Text),
72 | catch(
73 | call_with_time_limit(TimeLimit, apply_converter(Converter, Drs, Result)),
74 | Catcher,
75 | Result = Catcher
76 | ),
77 | display_result(Pp, Result).
78 |
79 |
80 | apply_converter(_Converter, drs(Dom, []), _) :-
81 | throw(error('DRS is empty', context(apply_converter/2, drs(Dom, [])))).
82 |
83 | apply_converter(Converter, Drs, Result) :-
84 | call(Converter, Drs, Result),
85 | !.
86 |
87 | apply_converter(_, Drs, _) :-
88 | throw(error('Converter failed', context(apply_converter/2, Drs))).
89 |
90 |
91 | display_header(Number, Text) :-
92 | format('~*t~d~6| ~w~n', [0'0, Number, Text]).
93 |
94 |
95 | display_result(_, Result) :-
96 | check_and_output_error(Result),
97 | !.
98 |
99 | display_result(Pp, Result) :-
100 | call(Pp, Result),
101 | nl.
102 |
103 | display_result(_, Result) :-
104 | format("ERROR\tWrong exception-term or non-printable result\t~w~n", [Result]).
105 |
106 |
107 | check_and_output_error(time_limit_exceeded) :-
108 | format("ERROR\t~w~n", ['Time limit exceeded']).
109 |
110 | check_and_output_error(error(Message, context(Pred, Arg))) :-
111 | \+ \+ ( numbervars(Arg, 0, _, [singletons(true)]),
112 | format("ERROR\t~w\t~w\t~w~n", [Message, Pred, Arg])
113 | ).
114 |
--------------------------------------------------------------------------------
/tests/test_duration.pl:
--------------------------------------------------------------------------------
1 | /**
2 | * @title Test the duration of APE, Refres, Drace.
3 | * @author Kaarel Kaljurand
4 | * @version 2008-02-15
5 | *
6 | * echo "[test_duration]. test_duration." | swipl -q > testruns/duration_051013-2000.txt
7 | *
8 | * TODO:
9 | * - recover from situations where the automatic generation of the DRS loops or craches
10 | * - better formatting of results
11 | * - benchmark all the main components separately
12 | */
13 |
14 | % We point to the directory where APE modules and the lexicons are located.
15 | :- assert(user:file_search_path(ape, '../prolog')).
16 |
17 | % We point to the directory where the regression test set is located.
18 | :- assert(user:file_search_path(rt, '.')).
19 |
20 | :- use_module(ape('parser/ace_to_drs'), [
21 | acetext_to_drs/5
22 | ]).
23 |
24 | :- use_module(ape('parser/ape_utils'), [
25 | cpu_time/2
26 | ]).
27 |
28 | % Consult the regression test set.
29 | :- style_check(-singleton).
30 | :- consult(rt(acetexts)).
31 | :- style_check(+singleton).
32 |
33 | % Import the lexicons
34 | :- style_check(-discontiguous).
35 | :- consult(clex:clex_lexicon).
36 | :- style_check(+discontiguous).
37 |
38 | :- set_prolog_flag(float_format, '%.11g').
39 |
40 | test_duration :-
41 | forall(
42 | text_drs_eval(0, Number, Text, DRS, _Syntax, _Date, _Author, _Comment),
43 | execute_test(Number, Text, DRS, _TimeOutLimit)
44 | ).
45 |
46 | execute_test(Number, Text, _Drs1, _TimeOutLimit) :-
47 | cpu_time(acetext_to_drs(Text, _, _, _Drs2, _Messages), Duration),
48 | display_result(Number, Text, Duration).
49 |
50 | display_result(Number, Text, Duration) :-
51 | format('~f\t~d\t~w~n', [Duration, Number, Text]).
52 |
--------------------------------------------------------------------------------
/tests/test_everything.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Runs all the APE tests in one go.
4 | #
5 | # Note that these tests overwrite files that are under version
6 | # control. In case the only change in the test results is random
7 | # variable names or IDs, then revert the change by
8 | #
9 | # git checkout .
10 | #
11 |
12 | pl=swipl
13 |
14 | dir=testruns
15 |
16 | results_coreace="${dir}/drace_test_results.txt"
17 | results_npace="${dir}/dracenp_test_results.txt"
18 | results_owlswrl="${dir}/owlswrl_test_results.txt"
19 | results_tptp="${dir}/test_drs_to_tptp_out.txt"
20 |
21 | echo
22 | echo "ACE -> DRS"
23 | echo
24 |
25 | time (bash rtest.bash)
26 |
27 |
28 | echo
29 | echo "DRS -> Core ACE"
30 | echo
31 |
32 | time (echo "[test_drace]. test_drace(core)." | $pl > ${results_coreace})
33 |
34 |
35 | echo
36 | echo "DRS -> NP ACE"
37 | echo
38 |
39 | time (echo "[test_drace]. test_drace(np)." | $pl > ${results_npace})
40 |
41 |
42 | echo
43 | echo "DRS -> OWL/SWRL"
44 | echo
45 |
46 | time ($pl -f none -g main -t halt -s test_owlswrl.pl > ${results_owlswrl})
47 |
48 |
49 | echo
50 | echo "DRS -> TPTP"
51 | echo
52 |
53 | time (echo "[test_drs_to_x]. main." | $pl > ${results_tptp})
54 |
--------------------------------------------------------------------------------
/tests/test_ruleml.sh:
--------------------------------------------------------------------------------
1 | #==============================================================================
2 | # This script validates the RuleML output of APE.
3 | #
4 | # Author: Tobias Kuhn
5 | #
6 | # The programs 'xmllint' and 'trang' need to be installed.
7 | #
8 | # THIS SCRIPT CURRENTLY DOES NOT WORK:
9 | # I tried different XML validation tools like xmllint and xerces and different
10 | # schema files, but I failed to validate even the official RuleML examples.
11 | #==============================================================================
12 |
13 |
14 | # Location of APE executable:
15 | ape=../ape.exe
16 |
17 | # Temporary directory:
18 | tempdir=tmp/ruleml
19 |
20 | echo "=== Create clean temporary directory: $tempdir ==="
21 | mkdir -p $tempdir/output
22 | mkdir -p $tempdir/schema
23 |
24 | echo "=== Create RuleML output for test sentences ==="
25 | $ape -text "Every customer is important." -solo ruleml > $tempdir/output/1.xml
26 | $ape -text "John is a man." -solo ruleml > $tempdir/output/2.xml
27 | $ape -text "Nobody waits." -solo ruleml > $tempdir/output/3.xml
28 |
29 | echo "=== Get XML schema ==="
30 | if [ -e $tempdir/schema/folog_normal.rng ]
31 | then
32 | echo "Use cached schema file: $tempdir/schema/folog_normal.rng"
33 | else
34 | echo "Download and convert schema file..."
35 | trang http://ruleml.org/1.0/relaxng/folog_normal.rnc $tempdir/schema/folog_normal.rng
36 | fi
37 |
38 | echo "=== Validate RuleML output with schema ==="
39 | xmllint --noout --relaxng $tempdir/schema/folog_normal.rng $tempdir/output/1.xml
40 | xmllint --noout --relaxng $tempdir/schema/folog_normal.rng $tempdir/output/2.xml
41 | xmllint --noout --relaxng $tempdir/schema/folog_normal.rng $tempdir/output/3.xml
42 |
43 | echo "=== Finished ==="
44 |
--------------------------------------------------------------------------------
/tests/testruns/.gitignore:
--------------------------------------------------------------------------------
1 | /rtest_*.txt
2 |
--------------------------------------------------------------------------------
/tests/testruns/README.drace:
--------------------------------------------------------------------------------
1 | #Drace test results on 2006-08-05.
2 |
3 | cat drace_test_results.txt | grep FAIL | wc -l
4 | # 216
5 |
6 | cat drace_test_results.txt | grep FAIL | grep -v "Paraphrase not supported" | wc -l
7 | # 52
8 |
9 | cat drace_test_results.txt | grep FAIL | grep -v "Paraphrase not supported" | grep -v ":" | wc -l
10 | # 31
11 |
12 |
13 |
14 | #Some bugs discovered on 2007-11-14:
15 |
16 | #1) A man's man waits. The man is happy. (APE bug)
17 |
18 | #2) Not less than 5 men wait. (Maybe APE bug)
19 |
20 | #3) 001110 [FAIL] A man sees his own dog and his own cat. --> A man X1 sees a dog of the man X1 and a cat of the man X1. (Paraphraser bug)
21 |
22 |
23 |
24 | # Drace test results on 2007-12-15.
25 |
26 | cat drace_test_results.txt | grep FAIL | wc -l
27 | 227
28 |
29 | cat drace_test_results.txt | grep FAIL | grep -v "NOT IMPLEMENTED" | wc -l
30 | 85
31 |
32 | cat drace_test_results.txt | grep FAIL | grep -v "NOT IMPLEMENTED" | grep -v "each of" | wc -l
33 | 63
34 |
35 |
36 | # Drace test results on 2007-12-17.
37 |
38 | cat drace_test_results.txt | grep FAIL | wc -l
39 | 216
40 |
41 | cat drace_test_results.txt | grep FAIL | grep -v "NOT IMPLEMENTED" | wc -l
42 | 88
43 |
44 | cat drace_test_results.txt | grep FAIL | grep -v "NOT IMPLEMENTED" | grep -v "each of" | wc -l
45 | 66
46 |
47 |
48 | # Drace test results on 2008-02-27
49 |
50 | cat drace_test_results.txt | grep FAIL | wc -l
51 | 279
52 |
53 | cat drace_test_results.txt | grep FAIL | grep -v "NOT IMPLEMENTED" | wc -l
54 | 53
55 |
56 | cat drace_test_results.txt | grep FAIL | grep -v "NOT IMPLEMENTED" | grep -v "each of" | wc -l
57 | 53
58 |
59 |
60 | # Core ACE verbalizer test results on 2008-08-19
61 | # (Test case count, FAIL count, buggy paraphrase count.)
62 |
63 | cat drace_test_results.txt | grep "^00" | wc -l
64 | 3094
65 |
66 | cat drace_test_results.txt | grep FAIL | wc -l
67 | 284
68 |
69 | cat drace_test_results.txt | grep FAIL | grep -v "NOT IMPLEMENTED" | wc -l
70 | 46
71 |
72 |
73 | # Core ACE verbalizer test results on 2008-10-07
74 | # (Test case count, FAIL count, buggy paraphrase count.)
75 |
76 | cat drace_test_results.txt | grep "^00" | wc -l
77 | 3135
78 | cat drace_test_results.txt | grep FAIL | wc -l
79 | 270
80 | cat drace_test_results.txt | grep FAIL | grep -v "NOT IMPLEMENTED" | wc -l
81 | 46
82 |
83 | # Core ACE verbalizer test results on 2008-12-04
84 | # (Test case count, FAIL count, buggy paraphrase count.)
85 |
86 | cat drace_test_results.txt | grep "^00" | wc -l
87 | 3151
88 | cat drace_test_results.txt | grep FAIL | wc -l
89 | 256
90 | cat drace_test_results.txt | grep FAIL | grep -v "NOT IMPLEMENTED" | wc -l
91 | 47
92 |
--------------------------------------------------------------------------------
/tests/testruns/sum.perl:
--------------------------------------------------------------------------------
1 | my $s = 0;
2 | my $c = 0;
3 |
4 | while() {
5 | $s += $_;
6 | $c++;
7 | }
8 |
9 | print $c, "\t", $s, "\n";
10 |
--------------------------------------------------------------------------------
/tools/create_zip.sh:
--------------------------------------------------------------------------------
1 | #
2 | # Packages the main contents of the repository as a zip-file.
3 | # Includes the jar-file and Javadoc for the Java interface for APE.
4 | #
5 | # Note: For a new release you probably need to update the version number
6 | # in 'ape-6.7'.
7 | #
8 | echo Compiling APE...
9 | cd ../prolog/parser
10 | bash compile.sh
11 | cd ../..
12 |
13 | echo Building the Java Interface for APE...
14 | cd java
15 | mvn package site -DskipTests
16 | cd ..
17 |
18 | echo "Generating public regression test set..."
19 | cd tests
20 | swipl -f make_acetext_drs.pl -g main -t halt -q > ../acetext_drs.pl
21 | cd ..
22 |
23 | echo Creating ZIP file...
24 | rm ape-*.zip
25 |
26 | timestamp=`date '+%y%m%d'`
27 |
28 | zip -r \
29 | ape-6.7.$timestamp.zip \
30 | ape.pl \
31 | pack.pl \
32 | CHANGES.md \
33 | get_ape_results.pl \
34 | LICENSE.txt \
35 | make_exe.bat \
36 | Makefile \
37 | README.md \
38 | runape.pl \
39 | run.sh \
40 | acetext_drs.pl \
41 | examples/ \
42 | java/install-jpl.sh \
43 | java/pom.xml \
44 | java/README.md \
45 | java/src/ \
46 | java/target/*.jar \
47 | java/target/site \
48 | prolog/ape.pl \
49 | prolog/lexicon/ \
50 | prolog/logger/ \
51 | prolog/parser/ \
52 | prolog/utils/ \
53 | -x \
54 | \*.gitignore \*.plp
55 |
56 | rm acetext_drs.pl
57 |
58 | echo Finished.
59 |
--------------------------------------------------------------------------------
/tools/extract_words.perl:
--------------------------------------------------------------------------------
1 |
2 | # Extracts words from an ACE text.
3 |
4 | # TODO
5 | # * Show also multi-word units. Useful for detecting repeated phrases.
6 |
7 | use strict;
8 | use warnings;
9 |
10 | $/ = undef;
11 | $_ = ;
12 |
13 | # Remove comments
14 | s{/\*\*[^*]*\*/}{}sg;
15 | s{/\*[^*]*\*/}{}sg;
16 | s{#.*}{}g;
17 |
18 | s{\.}{ \. }g;
19 | s{,}{ , }g;
20 | s{'s}{ 's }g;
21 | s{\s+}{ }g;
22 | s{^\s+}{};
23 | s{\s+$}{};
24 |
25 | my @words = split /\s+/;
26 |
27 | my $words = {};
28 |
29 | foreach (@words) {
30 | $words->{$_}++;
31 | }
32 |
33 | foreach (sort keys %{$words}) {
34 | print $words->{$_}, "\t", $_, "\n";
35 | }
36 |
--------------------------------------------------------------------------------
/tools/search.sh:
--------------------------------------------------------------------------------
1 | # Looks for a certain sequence of characters () from all the
2 | # pl-files in the current directory and its subdirectories.
3 | # @author Kaarel Kaljurand
4 | # @version 2008-04-16
5 |
6 | if [ $# -eq 1 ]
7 | then
8 | find . -name "*.pl" | xargs grep $1
9 | else
10 | echo "Usage: search.sh "
11 | fi
12 |
--------------------------------------------------------------------------------
|