-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdataSet.pl
361 lines (296 loc) · 11.2 KB
/
dataSet.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
% Kennis Systemen Opdracht 1.2 Dataset
% 6093906 Inge Becht
% alle attributen en relaties van dieren worden hier beschreven.
% in geval van de attributen is er gekozen om links te maken tussen de waardes
% die een attribuut kan hebben door middel van de value restrictions.
% in het geval van bijvoorbeeld een schildpad is een reptiel een schildpad in het geval
% dat deze tussen de 50-200 eieren legt.
% In geval van attributen met waarheiswaarde betekent 1/1 altijd waar
% en 0/0 altijd false (daar lijkt het KL-ONE representatie zich niet goed
% voor te lenen...
:- dynamic isa/2.
:- dynamic attribute/3.
% isa weergeeft de hierarchische structuur waarbij het linker argument
% onder het rechter argument staat in de structuur
isa(animal, thing).
isa(mammal, animal).
isa(amfibian, animal).
isa(reptile, animal).
isa(fish, animal).
isa(cow, mammal).
isa(platypus, mammal).
isa(dolphin, mammal).
isa(african_green_tree_frog, amfibian).
isa(turtle, reptile).
isa(boomslang, reptile).
isa(stingray, fish).
% attribute geeft het eigenschap(tweede argument
% van het eerste argument aan, waarbij het derde argument
% voor waarheidswaarde of aantal kan staan
% mogelijk staan niet alle vebrindingen er in,
% maar het principe moge duidelijk zijn
attribute(mammal, legs, 0/4).
attribute(amfibian, legs, 0/4).
attribute(reptile, legs, 0/4).
attribute(african_green_tree_frog, legs, 4/4).
attribute(platypus, legs, 4/4).
attribute(dolphins, legs, 0/0).
attribute(boomslang, legs, 0/0).
attribute(cow, legs, 4/4).
attribute(animal, living, 1/1).
attribute(mammal, warmblooded, 1/1).
attribute(amfibian, warmblooded, 0/0).
attribute(reptile, warmblooded, 0/0).
attribute(fish, warmblooded, 0/0).
attribute(reptile, nipples, 0/0).
attribute(fish, nipples, 0/0).
attribute(amfibian, nipples, 0/0).
attribute(mammal, nipples, 0/4).
attribute(cow, nipples, 4/4).
attribute(platypus, nipples, 0/0).
attribute(dolphins, nipples, 2/2).
attribute(mammal, eggs, 0/0).
attribute(amfibian, eggs, 1/200).
attribute(reptile, eggs, 1/200).
attribute(fish, eggs, 1/200).
attribute(boomslang, eggs, 1/1).
attribute(stringray, eggs, 1/1).
attribute(turtle, eggs, 50/200).
attribute(african_green_tree_frog, eggs, 100/200).
% opdracht 1.3
% de prettyprint, verder niks over toe te lichten
show:-
isaprint.
isaprint:-
findall(X, isa(X, _), List1),
findall(Y, isa(_, Y), List2),
only_animals(List1, List2, Animals),
print_animals(Animals).
% we want things only in the first
% list and not in the second one
only_animals([], _, []).
only_animals([H|T], List, [H|Rest]):-
\+member(H, List),
only_animals(T, list, Rest).
only_animals([_|T], List, Rest):-
only_animals(T, List, Rest).
print_animals([]).
print_animals([H|T]):-
writef("%t is a ", [H]),
all_predecessors(H),
write('\nAttributes:\n'),
all_attributes(H, []),
write('\n'),
print_animals(T).
all_predecessors(R):-
isa(R, thing),
write('thing').
all_predecessors(H):-
isa(H, R),
write(R),
write(', is a '),
all_predecessors(R).
all_attributes(H, History):-
isa(H, thing),
findall(X, attribute(H, X, _), List1),
findall(Z, attribute(H, _, Z/_), List2),
findall(W, attribute(H, _, _/W), List3),
print_values(List1, List2, List3, History) .
all_attributes(H, History):-
findall(X, attribute(H, X, _), List1),
findall(Z, attribute(H, _, Z/_), List2),
findall(W, attribute(H, _, _/W), List3),
print_values(List1, List2, List3, History),
isa(H, R),
append(List1, History, NewHistory),
all_attributes(R, NewHistory).
print_values([], [], [], _).
print_values([H|L], [H1|L1], [H2|L2],History):-
print_value(H, H1, H2, History),
print_values(L, L1, L2, History).
print_value(Attr, 1, 1, History):-
\+member(Attr, History),
write(' -'),
write(Attr),
write('\n').
print_value(Attr, 0, 0, History):-
\+member(Attr, History),
write(' -'),
write('not '),
write(Attr),
write('\n').
print_value(Attr, V, V, History):-
\+member(Attr, History),
write(' -'),
write(Attr),
write(' with value '),
writeln(V).
print_value(Attr, V, V2, History):-
\+member(Attr, History),
write(' -'),
write(Attr),
write(' with value '),
write(V),
write(' to '),
writeln(V2).
print_value(_,_,_,_).
% opdracht 4, de functie die nieuwe dingen toevoegt. go chortcuts zijn onderaan
% te vinden. concepten wordt aangeroepen om de loop te verzorgen
%adding new concept works as follows:
% first there is a check if the concept is already found in the tree.
% if so, the user gets a warning that the concept is not addded because it already exists
% In case the concept exists we look at its attributes. All attributes that are already hiher up in the tree
% will be ignored(as well as attributes already contained by the concept himself in the tree.
% after this is done the process terminates
% in the case there is a new concept and no parent is specified,
% we look at all the attributes that are given with the new concept. If sufficient attributes are
% specified for a given parent than we choose that parent to hang the new concept under (for instance,
% if we want something to be classified as a mammal we need at least the attributs warmblooded, eggs, nipples and legs described for our new concept).
% if no such parent can be found we add the new concept to thing.
% if there is a parent given already we just hang it under that parent and add the attributes which are not described by parental nodes.
go1:-
write('Adding concept car to the tree, with value metal 1/1\n'),
add_new_concept(car, [[metal, 1, 1]],[]).
go2:-
write('Adding concept horse with attribute nipples(2/2), legs(4/4), warmblooded, no eggs, 1 tail\n'),
add_new_concept(horse, [[nipples, 2, 2],[legs, 4,4 ],[warmblooded, 1,1],[eggs, 0,0],[tail, 1,1]], []).
go3:-
write('Adding new concept lizzard under amfibian with attribute tail(1/1)\n'),
add_new_concept(lizzard, [[tail, 1, 1]], [amfibian]).
go4:-
write('Adding new attribute horns to cow\n'),
add_new_concept(cow, [[horns, 2,2]], []).
% the first predicate that checks if the concept already is in the tree
add_new_concept(Concept, Attrs, Isa):-
% first check if the Concept is already in the database
((concept_known(Concept),
write('Concept already in tree!\nChecking attributes...\n'),
% if that is the case you add the Attributes
add_attrs(Concept, Attrs));
% else you start the Conceptadder
unknown_concept_adder(Concept, Attrs, Isa)
).
% adding a concept of which no isa relation has been given
unknown_concept_adder(Concept, Attrs, []):-
%if there are no concepts given or no ancestors can be found
((length(Attrs,X),
X =:= 0,
write('There is insufficient information on where to place the concept,
so we place it under thing\n')) ;
(finding_possible_ancestors(Attrs, AttEmpty),
AttEmpty ==[[]],
write('The given attributes do not match with a possible parent, so we place it under thing\n'));
(finding_possible_ancestors(Attrs, Ancestors),
flatten(Ancestors, An),
right_ancestor(An, An2),
An2 == [],
write('The given attributes do not match with a possible parent, so we place it under thing\n'))),
assert(isa(Concept, thing)),
% we still add the attributes
add_attrs(Concept, Attrs).
% in case a parent can be found.
unknown_concept_adder(Concept, Attrs, []):-
finding_possible_ancestors(Attrs, AncestorsPerAttr),
flatten(AncestorsPerAttr, AncestorsPerAttr2),
right_ancestor(AncestorsPerAttr2, An),
writef("Adding %t under %t\n", [Concept, An]),
assert(isa(Concept, An)),
add_attrs(Concept, Attrs).
% adding an unknown concept in the case of having a known parent
unknown_concept_adder(Concept, Attrs, Isa):-
length(Isa, Br),
Br =:= 1,
member(X, Isa),!,
% check if the parent is known in the tree
((isinisa(X),
writef("the parent %t is already in the tree. We place Concept under it\n", [Isa, Concept]),
assert(isa(Concept, X)),
add_attrs(Concept, Attrs)
);
(% if not, add the parent and Concept to the tree under thing
writef("The parent of %t was not recognised and will be inserted at thing level", [Concept]),
assert(isa(X, thing)),
assert(isa(Concept, X)),
write('Adding attributes...\n'),
add_attrs(Concept, Attrs)
)).
% case of assing more than 1 direct parent
unknown_concept_adder(Concept, _, _):-
writef("You are trying to add more than one direct parent to %t. \n This is not possible!\n",[Concept]).
% right ancetor checks if there can be a ancestor found
% with all the given new attributes of the concept
% this succeeds only if all possible attributes of a parent
% is matched with the attributes given by the concept
right_ancestor([], []):-!.
right_ancestor([X|AncestorsPerAttr], X):-
all_occurences(X, AncestorsPerAttr, List),
findall(Y, attribute(X, Y, _) ,List2),
length(List, Bla),
length(List2, Bla2),
(Bla + 1) =:= Bla2,!.
right_ancestor([X|AncestorsPerAttr], R):-
all_occurences(X, AncestorsPerAttr, List),
findall(Y, attribute(X, Y, _) ,List2),
length(List, Bla),
length(List2, Bla2),
\+ (Bla +1)=:= Bla2,
exclude(X, AncestorsPerAttr, AncestorsNew),
right_ancestor(AncestorsNew, R),!.
% exclude X from the output list
exclude(X, [H|T], [H|R]):-
exclude(X, T, R).
exclude(X, [X|T], R):-
exclude(X, T, R).
% output gets all the duplicates of first argument in second list
all_occurences(_, [], []).
all_occurences(X, [X|Ancestors], [X|List]):-
all_occurences(X, Ancestors, List).
all_occurences(X, [_|Ancestors], List):-
all_occurences(X, Ancestors, List).
finding_possible_ancestors([], []).
finding_possible_ancestors([[Attr, Val1, Val2]|Attrs], [List|Ancestors]):-
findall(X, (attribute(X, Attr, Y/Z), Y=<Val1, Z >= Val2), List),
finding_possible_ancestors(Attrs, Ancestors).
% The concept is known if it can be found in the tree
concept_known(Concept):-
(isa(Concept, _);
isa(_, Concept)).
% adds attributes to a concept
add_attrs(_, []).
% Attrs form: lists of [ Attr, Val1, Val2]
add_attrs(Concept, [[Attr, Val1, Val2] |Attrs]):-
%first check if there are ancestors that specify the same attribute
ancestors(Concept, Ancestors),
% if the attribute is not exactly like one of the ancestors
% then add the new attribute. Else just go to the following attribute
((check_attr(Ancestors, Attr, Val1, Val2),
\+attribute(Concept, Attr, _/_),
writef("added new attribute %t to %t with value %t - %t\n", [Attr, Concept, Val1, Val2]),
assert(attribute(Concept, Attr, Val1/Val2)),
add_attrs(Concept, Attrs))
;
writef("Attribute %t was already in another part of the tree and will not be added\n", [Attr]),
(add_attrs(Concept, Attrs))).
%adds all new isa values
add_isa(Concept, [H|Isa]):-
% concruct all already known ancestors
ancestors(Concept, Ancestors),
% we only want to add new attributes so we filter those
((\+member(H, Ancestors),
writef("Added %t as new ancestor of %t\n", [H, Concept]),
assert(isa(Concept, H),
add_isa(Concept, Isa)))
;
(writef("Concept %t alrady has ancestor %t\n", [Concept, H]),
add_isa(Concept, Isa))).
% gives all ancestors of a given Concept MULTIPLE ANCESTORE LINES SHOULD ALSO BE AN OPTION??
ancestors(Concept, []):-
\+isa(Concept, _).
ancestors(Concept, [An|Cestors]):-
isa(Concept, An),
ancestors(An, Cestors).
% chck if any of the ancestors havet his attribute.
check_attr([], _, _, _).
check_attr([H|Ancestors], Attr, Val1, Val2):-
\+attribute(H, Attr, Val1/Val2),
check_attr(Ancestors, Attr, Val1, Val2).