24:- module(prodlr, [declare_concept/1, declare_concept/2, add_to_concept/2,
25 declare_relation/3, add_to_relation/3,
26 concept_select/3, forall_select/4, atleast_select/5, atmost_select/5, self_select/3,
27 relation_path/3, relation_path/1, concept_name/1, concept_name_or_not/1, num/1,
28 concept/3,
29 legitimate_literal/1, thread_itemfunctor/1]). 30
31:- assert_if_new(user:use_algebra(alg_lukasiewicz)). 32
33:- use_module( fuzzyutils ). 34
35:- use_module( library(lists) ). 36
37:- dynamic concept_name/1, concept_assert/3, concept_sub/3, concept_sub/2. 38:- dynamic relation_name/3, relation_assert/4, relation_sub/4. 39
42
43init_engine(swi) :-!.
46
47init_engine(yap) :-
48 use_module( library(dialect/swi) ).
49
50
52:- init_engine(swi). 53
56concept_name(thing).
57
61
62declare_concept(Concept, Super) :-
63 atom(Concept),
64 atom(Super),
65 assert_if_new(concept_name(Concept)),
66 assert_if_new(concept_sub(Concept,Super)),
67 assert_if_new((concept_sub(Super, I, Deg) :- concept(Concept, I, Deg))).
68
69declare_concept(Concept) :- declare_concept(Concept, thing).
70
74assert_instance(Concept, Instance, Deg) :-
75 atom(Concept), atom(Instance),
76 concept_name(Concept), is_fuzzy_degree(Deg),
77 78 retractall(concept_assert(Concept, Instance, _)),
79 asserta(concept_assert(Concept, Instance, Deg)).
80
81
83add_to_concept(Concept, []) :- concept_name(Concept).
84
85add_to_concept(Concept, [(Instance, Deg) | Rest]) :-
86 !,
87 assert_instance(Concept, Instance, Deg),
88 add_to_concept(Concept, Rest),
89 !.
90
91add_to_concept(Concept, [Instance | Rest]) :-
92 add_to_concept(Concept, [(Instance, 1.0) | Rest]).
93
94
98
102
104concept_complement(compl(C), C) :- !.
105concept_complement(C, compl(C)).
106
108concept_degrees(Concept, Instance, Degrees) :-
109 findall(D, concept_assert(Concept, Instance, D), DegAsserted),
110 findall(D, concept_sub(Concept, Instance, D), DegSubsumed),
111 append(DegAsserted, DegSubsumed, Degrees).
112
113is_instance_of_concept(Concept, Instance) :-
114 concept_assert(Concept, Instance, _).
115is_instance_of_concept(Concept, Instance) :-
116 concept_sub(Concept, Instance, _).
117
119concept_degree(Concept, Instance, Deg) :-
120 atom(Concept), atom(Instance),
121 (Concept = thing ->
122 equally_fuzzy(Deg, 1.0) ;
123 concept_degrees(Concept, Instance, Degrees),
124 (Degrees = [] -> equally_fuzzy(Deg, 0.0) ; tnorms(disjunction, Degrees, Deg))).
125
127concept(Concept, Instance, Deg) :-
128 concept_degree(Concept, Instance, Deg).
129
130concept(Concept, Instance, Deg) :-
131 atom(Concept), var(Instance),
132 is_instance_of_concept(Concept, Instance),
133 concept_degree(Concept, Instance, Deg).
134
139
144
145concept(compl(C), I, Deg) :-
146 concept_name(C), 147 concept(C, I, Deg1),
148 tnorm( complement, Deg1, Deg).
149
150concept_name_or_not(C) :- concept_name(C).
151concept_name_or_not(compl(C)) :- concept_name(C).
152
153concept_subsumed(C,C) :- !.
154
155concept_subsumed(C1, C2) :-
156 concept_name_or_not(C1),
157 concept_name_or_not(C2),
158 findall( (I1, D1), concept(C1, I1, D1), C1List ),
159 set_subsumed( C1List, C2 ).
160
161set_subsumed( [], _ ).
162set_subsumed( [(I,D)|Rest], C) :-
163 concept(C, I, D1), !,
164 tnorm( implication, D, D1, Result),
165 equally_fuzzy( Result, 1.0 ),
166 set_subsumed( Rest, C ).
167
168relation_name(uni, thing, thing).
169relation_name(Relation) :- relation_name(Relation, _, _).
170
171declare_relation(Relation, Domain, Range) :- declare_relation(Relation, uni, Domain, Range).
172declare_relation(Relation, Super, Domain, Range) :-
173 atom(Relation), atom(Super),
174 atom(Domain), atom(Range),
175 assert_if_new(relation_name(Relation, Domain, Range)),
176 assert_if_new((relation_sub(Super, X, Y, Deg) :- relation(Relation, X, Y, Deg))).
177
178
179assert_role(Relation, Inst1, Inst2, Deg) :-
180 atom(Relation), atom(Inst1), atom(Inst2),
181 182 relation_name(Relation),
183 184 185 186 retractall(relation_assert(Relation, Inst1, Inst2, _)),
187 asserta(relation_assert(Relation, Inst1, Inst2, Deg)).
188
190add_to_relation(Relation, X, []) :- atom(Relation), atom(X).
191add_to_relation(Relation, X, [(Y, Deg) | R]) :-
192 assert_role(Relation, X, Y, Deg),
193 add_to_relation(Relation, X, R).
194
195relation_degrees(Rel, X, Y, Degrees) :-
196 atom(Rel), atom(X), atom(Y),
197 findall(D, relation_assert(Rel, X, Y, D), DegAsserted),
198 findall(D, relation_sub(Rel, X, Y, D), DegSubsumed),
199 append(DegAsserted, DegSubsumed, Degrees).
200
201relation_degree(Rel, X, Y, Deg) :-
202 atom(Rel), atom(X), atom(Y),
203 (Rel = uni ->
204 equally_fuzzy(Deg, 1.0) ;
205 relation_degrees(Rel, X, Y, Degrees),
206 (Degrees = [] -> equally_fuzzy(Deg, 0.0); tnorms( disjunction, Degrees, Deg))).
207
208is_relation_instance(Rel, X, Y) :-
209 relation_assert(Rel, X, Y, _).
210is_relation_instance(Rel, X, Y) :-
211 relation_sub(Rel, X, Y, _).
212
213relation(Rel, X, Y, Degree) :-
214 relation_degree(Rel, X, Y, Degree).
215
216relation(Rel, X, Y, Degree) :-
217 atom(Rel), (var(X) | var(Y)), !,
218 is_relation_instance(Rel, X, Y),
219 relation_degree(Rel, X, Y, Degree).
220
221relation_composition([Relation], Inst1, Inst2, Deg) :-
222 relation_name(Relation),
223 relation(Relation, Inst1, Inst2, Deg).
224
225relation_composition([Rel1, Rel2 | Rest], Inst1, Inst2, Deg) :-
226 relation_path([Rel1, Rel2 | Rest], Inst1, Inst2, _), 227 228 findall(DegOut, relation_path([Rel1, Rel2|Rest], Inst1, Inst2, DegOut), Degrees),
229 (Degrees = [] -> equally_fuzzy(Deg, 0.0) ; sup_degree(Degrees, Deg)).
230
231relation_path([Rel], Inst1, Inst2, DegOut) :- relation_name(Rel), relation(Rel, Inst1, Inst2, DegOut).
232relation_path([Rel1, Rel2 | Rest], Inst1, Inst2, DegOut):-
233 relation_name(Rel1), relation_name(Rel2),
234 relation(Rel1, Inst1, Y, Deg2),
235 relation_composition([Rel2 | Rest], Y, Inst2, Deg3),
236 tnorm( conjunction, Deg2, Deg3, DegOut ).
237
238
239relation_path_arb([Rel], Domain, Range) :-
240 relation_name(Rel, Domain, Range).
241
242relation_path_arb([Rel1, Rel2 |Rest], Domain, Range) :-
243 relation_name(Rel1, Domain, _),
244 relation_name(Rel2, Domain2, _),
245 relation_range([Rel1], Domain2),
246 relation_path_arb([Rel2|Rest], Domain2, Range).
247
248relation_path(Path, Domain, Range) :-
249 var(Path), !,
250 between(1, 4, N),
251 length(Path, N),
252 relation_path_arb(Path, Domain, Range),
253 \+ member(uni, Path).
254
255relation_path(Path, Domain, Range) :-
256 relation_path_arb(Path, Domain, Range).
257
258
259relation_range(RelationPath, Range) :-
260 relation_path(RelationPath, _, Range).
261
262relation_range(RelationPath, Range) :-
263 relation_path(RelationPath, _, Range2),
264 265 concept_sub(Range2, Range).
266
267relation_path(Path) :- relation_path(Path, _, _).
268
271
273concept_select( InList, Concept, OutList ) :-
274 concept_name_or_not(Concept),
275 concept_select_rec(InList, Concept, OutList).
276
277concept_select_rec( [], _, [] ).
278concept_select_rec( [(Instance, InDeg)|InList], Concept, [(Instance, OutDeg) | OutList] ) :-
279 concept(Concept, Instance, Deg),
280 tnorm( conjunction, InDeg, Deg, OutDeg1 ),
281 (var(OutDeg) -> OutDeg = OutDeg1 ; check_less_fuzzy(OutDeg1, OutDeg)),
282 concept_select_rec( InList, Concept, OutList ).
290forall_select([], _, _, []).
291forall_select([(A, D) | InList], Relation, Concept, [(A, OutDeg) | OutList]) :-
292 relation_path(Relation),
293 concept_name_or_not(Concept),
294 forall(A, Relation, Concept, DegF),
295 tnorm(conjunction, D, DegF, OutDeg1),
296 (var(OutDeg) -> OutDeg = OutDeg1 ; check_less_fuzzy(OutDeg1, OutDeg)),
297 forall_select(InList, Relation, Concept, OutList).
299
300forall_each(A, Relation, Concept, Deg) :-
301 relation_composition(Relation, A, B, DegRel),
302 concept(Concept, B, DegC),
303 tnorm(implication, DegRel, DegC, Deg).
304
305forall(A, Relation, Concept, Deg) :-
306 atom(A), !,
307 findall(D, forall_each(A, Relation, Concept, D), Degrees),
308 (Degrees = [] -> Deg = 0.0; inf_degree(Degrees, Deg)).
309
310forall(A, Relation, Concept, Deg) :-
311 var(A), !,
312 concept(thing, A, _),
313 forall(A, Relation, Concept, Deg).
314
315
318atleast_once(Degrees, P, Deg) :-
319 length(ParyDegrees, P),
320 comb(Degrees, ParyDegrees),
321 tnorms(weakconjunction, ParyDegrees, Deg).
322
323exists_each(A, B, Relation, Concept, Deg) :-
324 relation_composition(Relation, A, B, DegRel),
325 concept(Concept, B, DegC),
326 tnorm(conjunction, DegRel, DegC, Deg).
327
328exists_many(A, Relation, Concept, Degrees, Many) :-
329 atom(A), !,
330 findall((B,D), exists_each(A, B, Relation, Concept, D), OutList),
331 332 remove_duplicates(OutList, OutSet),
333 unzip(OutSet, _, Degrees1),
334 335 Degrees = Degrees1,
336 length(Degrees, Many),
337 !.
338
339exists_many(A, Relation, Concept, Degrees, Many) :-
340 var(A), !,
341 concept(thing, A, _),
342 exists_many(A, Relation, Concept, Degrees, Many).
343
346atleast_select([], _, _, _, []).
347atleast_select([(A, InDeg) | Rest], Relation, Concept, Min, [(A, OutDeg) | OutList]) :-
348 integer(Min), !,
349 relation_path(Relation),
350 concept_name_or_not(Concept),
351 exists_many(A, Relation, Concept, Degrees, N),
352 (N >= Min ->
353 findall(Deg, (atleast_once(Degrees, Min, Deg1), tnorm(conjunction, Deg1, 1.0, Deg)), CompDegrees),
354 sup_degree(CompDegrees, CompDeg)
355 ;
356 equally_fuzzy(CompDeg, 0.0)
357 ),
358 tnorm(conjunction, InDeg, CompDeg, OutDeg1),
359 (var(OutDeg) -> OutDeg = OutDeg1 ; check_less_fuzzy(OutDeg1, OutDeg)),
360 atleast_select(Rest, Relation, Concept, Min, OutList).
361
362atleast_select(InList, Relation, Concept, Min, OutList) :-
363 var(Min), !,
364 relation_path(Relation),
365 concept_name_or_not(Concept),
366 atleast_select_MaxMin(InList, Relation, Concept, MaxMin, OutList),
367 MaxMin >= 1,
368 between(1, MaxMin, Min),
369 atleast_select(InList, Relation, Concept, Min, OutList).
370
371atleast_select_MaxMin(InList, Relation, Concept, MaxMin, OutList) :-
372 atleast_select_MaxMin_rec(InList, Relation, Concept, OutList, MaxMin).
373
374atleast_select_MaxMin_rec([(Instance, InDeg)], R, C, [(Instance, OutDeg)], Max) :-
375 376 atleast_find_max([(Instance, InDeg)], R, C, [(Instance, OutDeg)], 1, Max).
377
378atleast_select_MaxMin_rec([(Instance, InDeg)|InList], Relation, Concept, [(Instance, OutDeg)|OutList], MaxMin) :-
379 380 atleast_find_max([(Instance, InDeg)], Relation, Concept, [(Instance, OutDeg)], 1, N),
381 atleast_select_MaxMin_rec(InList, Relation, Concept, OutList, MaxMin2),
382 ( N >= MaxMin2 -> MaxMin = MaxMin2 ; MaxMin = N ).
383
384atleast_find_max([(Instance, _)], Relation, Concept, [(Instance, OutDeg)], _, N) :-
385 var(OutDeg), !,
386 exists_many(Instance, Relation, Concept, _, N).
387
388atleast_find_max([(Instance,InDeg)], Relation, Concept, [(Instance, _)], K, K2) :-
389 K2 is K + 1,
390 atleast_select( [(Instance,InDeg)], Relation, Concept, K2, [(Instance, OutDeg2)]),
391 equally_fuzzy(OutDeg2,0.0),
392 !.
393
394atleast_find_max(InList, Relation, Concept, OutList, K, Max) :-
395 K2 is K + 1,
396 atleast_find_max(InList, Relation, Concept, OutList, K2, Max).
397
398
400
401atmost_select([], _, _,_, []).
402
403atmost_select([(A, InDeg) | Rest], Relation, Concept, Max, [(A, OutDeg) | OutList]) :-
404 integer(Max), !,
405 relation_path(Relation),
406 concept_name_or_not(Concept),
407 exists_many(A, Relation, Concept, Degrees, N),
408 MaxPlusOne is Max + 1,
409 findall(Deg,
410 (atleast_once(Degrees, MaxPlusOne, Deg1), tnorm(implication, Deg1, 0.0, Deg)),
411 CompDegrees),
412 inf_degree(CompDegrees, CompDeg),
413 tnorm(conjunction, InDeg, CompDeg, OutDeg1),
414 (var(OutDeg) -> OutDeg = OutDeg1 ; check_less_fuzzy(OutDeg1, OutDeg)),
415 atmost_select(Rest, Relation, Concept, Max, OutList).
416
417atmost_select(InList, Relation, Concept, Max, OutList) :-
418 var(Max), !,
419 relation_path(Relation),
420 concept_name_or_not(Concept),
421 atmost_select_MaxMin(InList, Relation, Concept, MaxMin, OutList),
422 MaxMin >= 0,
423 between(0, MaxMin, Max),
424 atmost_select(InList, Relation, Concept, Max, OutList).
425
426atmost_select_MaxMin(InList, Relation, Concept, MaxMin, OutList) :-
427 atmost_select_MaxMin_rec(InList, Relation, Concept, OutList, MaxMin).
428
429atmost_select_MaxMin_rec([(Instance, InDeg)], R, C, [(Instance, OutDeg)], Max) :-
430 431 atmost_find_max([(Instance, InDeg)], R, C, [(Instance, OutDeg)], 1, Max).
432
433atmost_select_MaxMin_rec([(Instance, InDeg)|InList], Relation, Concept, [(Instance, OutDeg)|OutList], MaxMin) :-
434 435 atmost_find_max([(Instance, InDeg)], Relation, Concept, [(Instance, OutDeg)], 1, N),
436 atmost_select_MaxMin_rec(InList, Relation, Concept, OutList, MaxMin2),
437 ( N >= MaxMin2 -> MaxMin = N ; MaxMin = MaxMin2 ).
438
439atmost_find_max([(Instance, _)], Relation, Concept, [(Instance, OutDeg)], _, N) :-
440 var(OutDeg), !,
441 exists_many(Instance, Relation, Concept, _, N).
442
443atmost_find_max([(Instance, InDeg)], Relation, Concept, [(Instance, _)], K, K2) :-
444 K2 is K + 1,
445 atmost_select( [(Instance, InDeg)], Relation, Concept, K2, [(Instance, OutDeg2)]),
446 equally_fuzzy(InDeg, OutDeg2),
447 !.
448
449atmost_find_max(InList, Relation, Concept, OutList, K, Max) :-
450 K2 is K + 1,
451 atmost_find_max(InList, Relation, Concept, OutList, K2, Max).
452
453
455
456self_select( InList, Rel, OutList ) :-
457 relation_path( Rel ),
458 self_select_rec( InList, Rel, OutList ).
459
460self_select_rec( [], _, [] ).
461
462self_select_rec( [(Instance, InDeg)|InList], Rel, [(Instance, OutDeg) | OutList] ) :-
463 relation_composition(Rel, Instance, Instance, Deg),
464 tnorm( conjunction, InDeg, Deg, OutDeg1 ),
465 (var(OutDeg) -> OutDeg = OutDeg1 ; check_less_fuzzy(OutDeg1, OutDeg)),
466 self_select_rec( InList, Rel, OutList ).
467
468
469
473
474unzip([], [], []).
475unzip([(A, B) | R], [A | RA], [B | RB]) :- unzip(R, RA, RB).
476
477
478comb([], []).
479comb([X|A], [X|B]) :- comb(A, B).
480comb([_|A], B) :- comb(A, B).
481
482
483remove_zeros([],[]).
484remove_zeros([Degree|Rest], Rest2) :-
485 check_equally_fuzzy(Degree, 0.0),
486 remove_zeros(Rest, Rest2), !.
487remove_zeros([Degree|Rest], [Degree|Rest2]):-
488 remove_zeros(Rest, Rest2).
489
490num(0).
491num(1).
492num(2).
493num(3).
494num(4).
495num(5).
496
497thread_itemfunctor(concept_select/3).
498thread_itemfunctor(forall_select/4).
499thread_itemfunctor(atleast_select/5).
500thread_itemfunctor(atmost_select/5).
501thread_itemfunctor(self_select/3).
502
503inout_lit(Term, Input, Output) :-
504 Term =.. List,
505 length(List, N),
506 N >= 3,
507 List = [ _, Input | _ ],
508 last(List, Output).
509
510inout_thread(','(A, B), Input, Output) :-
511 inout_lit(A, Input, FirstOut),
512 inout_thread(B, FirstOut, Output), !.
513
514inout_thread(Atom, Input, Output) :- inout_lit(Atom, Input, Output), !.
515
518has_pieces(true, []) :- !.
519has_pieces(','(A, R), [A|Z]) :- has_pieces(R, Z), !.
520has_pieces(A, [A]) :- !.
521
524concat_thread([A], A) :- !.
525concat_thread([A|Z], ','(A, Z1)) :-
526 concat_thread(Z, Z1),
527 inout_lit(A, _, Out),
528 inout_thread(Z1, Out, _).
529
531count_literals(Lits, Count) :- has_pieces(Lits, LitList), length(LitList, Count).
532
535connect_thread((Head:-Body)) :-
536 inout_lit(Head, Input, Output),
537 inout_thread(Body, Input, Output), !.
538
541append_thread(Lit, Body, BodyWith) :-
542 has_pieces(Body, Atoms),
543 append(Atoms, [Lit], Atoms2),
544 concat_thread(Atoms2, BodyWith), !.
545
546concept_r(C, C).
547concept_r(C, R) :- concept_sub(C, R).
548
553legitimate_literal(concept_select(_,C,_)) :- concept_name_or_not(C).
554
555legitimate_literal(forall_select(_, R, C, _)) :- relation_path(R, _, Range), concept_r(C, Range).
556
557legitimate_literal(atleast_select(_, R, C, N, _)) :- num(N), relation_path(R, _, Range), concept_r(C, Range).
558
559legitimate_literal(atmost_select(_, R, C, N, _)) :- num(N), relation_path(R, _, Range), concept_r(C, Range).
560
561legitimate_literal(self_select(_, R, B)) :- relation_path(R).
562
566
567yadlr_init( KB ) :-
568 retractKB( KB ).
569
571yadlr_concept( KB, ConceptName ) :-
572 declare_concept(ConceptName),
573 db_recordz( KB, yconcept(ConceptName), _ ).
574
575yadlr_relation( KB, RelationName ) :-
576 declare_relation(RelationName, thing, thing),
577 db_recordz( KB, yrelation(RelationName), _ ).
578
579yadlr_instance( KB, InstanceName ) :-
580 db_recordz( KB, yinstance(InstanceName), _ ).
581
582yadlr_concept_name( KB, ConceptName ) :-
583 db_recorded( KB, yconcept(ConceptName), _ ).
584
585yadlr_relation_name( KB, RelationName ) :-
586 db_recorded( KB, yrelation(RelationName), _ ).
587
588yadlr_instance_name( KB, InstanceName ) :-
589 db_recorded( KB, yinstance(InstanceName), _ ).
590
591yadlr_assert( KB, Formula, FuzzyDegree ) :-
592 clausify_abstract( Formula, FuzzyDegree, Clauses ),
593 yadlr_assert_many( KB, Clauses ).
594
604
605yadlr_assert_one(KB, dla(concept, Assertion, Degree)) :-
606 is_concept(Assertion, Concept, Instance),
607 yadlr_concept_name(KB, Concept),
608 609 !,
610 add_to_concept(Concept, [(Instance, Degree)]).
611
612yadlr_assert_one(KB, dla(relation, Assertion, Degree)) :-
613 is_relation(Assertion, Relation, X, Y),
614 yadlr_relation_name(KB, Relation),
615 616 617 !,
618 add_to_relation(Relation, X, [(Y, Degree)]).
619
620yadlr_assert_one(_, DLClause) :-
621 mkplclause(DLClause, Clause),
622 assert_if_new(Clause),
623 !.
624
625yadlr_assert_many( _, []).
626yadlr_assert_many( KB, [Head|Rest] ) :-
627 yadlr_assert_one(KB, Head),
628 yadlr_assert_many(KB, Rest).
629
630retractKB( KB ) :-
631 prolog_engine(swi),
632 db_recorded( KB, _, Ref ),
633 erase( Ref ),
634 fail.
635retractKB( _ ) :-
636 prolog_engine(swi),
637 !.
640
641yadlr_retrieve_concept( KB, ConceptName ) :-
642 db_recorded( KB, yconcept(ConceptName), _ ).
643
644yadlr_retrieve_relation( KB, RelationName ) :-
645 db_recorded( KB, yrelation(RelationName), _ ).
646
647yadlr_retrieve_instance( KB, InstanceName ) :-
648 db_recorded( KB, yinstance(InstanceName), _ ).
649
651
652clausify_abstract(Formula, FuzzyDegree, Clauses ) :-
653 clausify_concept(Formula, FuzzyDegree, Clauses).
654
655clausify_abstract(Formula, FuzzyDegree, Clauses ) :-
656 clausify_role(Formula, FuzzyDegree, Clauses).
657
658clausify_abstract(Formula, FuzzyDegree, Clauses ) :-
659 clausify_assertion(Formula, FuzzyDegree, Clauses).
660
661clausify_concept(all(X, dlimplies(Body, Head)), FuzzyDegree, Clauses) :-
662 is_concept(Head, H, X),
663 norm_concept(X, Body, DLBody),
664 dlclausify(concept, (H :- DLBody), FuzzyDegree, Clauses).
665
666clausify_concept(all(X, dlequiv(B1, B2)), FuzzyDegree, Clauses) :-
667 is_concept(B2, _, _) ->
668 clausify_concept(all(X, dlimplies(B1, B2)), FuzzyDegree, Clauses);
669 clausify_concept(all(X, dlimplies(B2, B1)), FuzzyDegree, Clauses).
670
671clausify_role(all(X, all(Y, dlimplies(Body, Head))), FuzzyDegree, Clauses) :-
672 is_relation(Head, R, X, Y),
673 norm_relation(X, Y, Body, DLBody),
674 dlclausify(relation, (R :- DLBody), FuzzyDegree, Clauses).
675
676clausify_assertion(Fmt, FuzzyDegree, [dla(concept, Fmt, FuzzyDegree)]) :-
677 is_concept(Fmt, C, X),
678 atom(C), atom(X), !.
679
680clausify_assertion(Fmt, FuzzyDegree, [dla(relation, Fmt, FuzzyDegree)]) :-
681 is_relation(Fmt, R, X, Y),
682 atom(R), atom(X), atom(Y),
683 !.
684
685dlclausify(T, (H :- DLBody), Degree, Clauses) :-
686 dlnnf(DLBody, NNF),
687 dldnf(NNF, DNF),
688 dlor_to_list(DNF, ListOfBodies),
689 dlclausify_attach(T, H, ListOfBodies, Degree, Clauses).
690
692dlclausify_attach(T, H, [B], Deg, [dlc(T, H, B, Deg)]).
693dlclausify_attach(T, H, [B|R], Deg, [dlc(T, H, B, Deg)|R0]) :- dlclausify_attach(T, H, R, Deg, R0).
694
695
696dlor_to_list(dlor(A, B), List) :- !,
697 dlor_to_list(A, LA),
698 dlor_to_list(B, LB),
699 append(LA, LB, List).
700dlor_to_list(X, [X]).
701
702is_concept(Fmt, C, X) :-
703 functor(Fmt, C, 1),
704 arg(1, Fmt, X).
705
706is_relation(R, Relation, X, Y) :- !,
707 functor(R, Relation, 2),
708 arg(1, R, X),
709 arg(2, R, Y).
710
712mkplclause(dlc(concept, Head, Body, _), (PlHead:-PlBody)) :-
713 mkplhead(Head, (I,D), PlHead),
714 mkplbody(Body, [(I,1.0)], [(I,D)], PlBody).
715
716mkplhead(Head, (I,D), concept_sub(Head,I,D)).
717mkplbody(dland(A, B), Input, Output, ','(P,Q)) :-
718 mkplbody(A, Input, Pipe, P),
719 mkplbody(B, Pipe, Output, Q).
720mkplbody(dlconcept(C), I, O, concept_select(I, C0, O)) :- mkplconcept(dlconcept(C), C0).
721mkplbody(dlnot(C), I, O, concept_select(I, C0, O)) :- mkplconcept(dlnot(C), C0).
722mkplbody(forall(Rp, C), I, O, forall_select(I, Rp, C0, O)) :- mkplconcept(C, C0).
723mkplbody(exists(Rp, C), I, O, atleast_select(I, Rp, C0, 1, O)) :- mkplconcept(C, C0).
724mkplbody(atleast(N, Rp, C), I, O, atleast_select(I, Rp, C0, N, O)) :- mkplconcept(C, C0).
725mkplbody(atmost(N, Rp, C), I, O, atmost_select(I, Rp, C0, N, O)) :- mkplconcept(C, C0).
726
727mkplconcept(dlconcept(C), C).
728mkplconcept(dlnot(dlconcept(C)), compl(C)).
729
730
743
744
746
747norm_concept(X, all(Y, dlimplies(R, F)), all(Rel, NC)) :- !,
748 is_relation(R, Rel, X, Y),
749 norm_concept(Y, F, NC),
750 (Nrm = all(R1, NC1) -> Rel = [R0|R1], NC = NC1 ;
751 Rel = [R0], NC = Nrm).
752
753norm_concept(X, exists(Y, dland(R, F)), exists(Rel, NC)) :- !,
754 is_relation(R, R0, X, Y),
755 norm_concept(Y, F, Nrm),
756 (Nrm = exists(R1, NC1) -> Rel = [R0|R1], NC = NC1 ;
757 Rel = [R0], NC = Nrm).
758
759norm_concept(X, exists(Y, Fmt), atleast(N, [Relation], Concept)) :- !,
760 collectexists(exists(Y, Fmt), [], Fmt1, Vars),
761 length(Vars, N),
762 groupN(X, Vars, Fmt1, dland(R, C)),
763 is_relation(R, Relation, X, Y),
764 norm_concept(Y, C, Concept).
765
766norm_concept(X, dlnot(Fmt), dlnot(Fmt1)) :- norm_concept(X, Fmt, Fmt1).
767
768norm_concept(X, Fmt, dlconcept(C)) :- is_concept(Fmt, C, X).
769
770norm_concept(X, dland(F, G), dland(F0, G0)) :-
771 norm_concept(X, F, F0), norm_concept(X, G, G0).
772
773norm_concept(X, dlor(F, G), dlor(F0, G0)) :-
774 norm_concept(X, F, F0), norm_concept(X, G, G0).
775
776
777norm_relation(X, Y, dlor(F, G), dlor(F0, G0)) :- !,
778 norm_relation(X, Y, F, F0),
779 norm_relatin(X, Y, G, G0).
780
781norm_relation(X, Y, dland(F, G), dland(F0, G0)) :- !,
782 norm_relation(X, Y, F, F0),
783 norm_relation(X, Y, G, G0).
784
785norm_relation(X, Y, R, dlrel(Relname)) :- !,
786 is_relation(R, Relname, X, Y).
787
788
790
792groupN(_, [_], Fmt, Fmt) :- !.
793groupN(X, Vars, Fmt, FmtGrp) :- groupN_rec(X, [], Vars, Fmt, _, FmtGrp).
794
795groupN_rec(_, V, [], dlalldifferent(V), FmtGrp, FmtGrp).
796
797groupN_rec(_, _, [_], Fmt, Fmt, Fmt).
798
799groupN_rec(X, [], V, dland(Fmt, dlalldifferent(V)), FmtGrp, FmtGrp) :- !,
800 groupN_rec(X, [], V, Fmt, _, FmtGrp).
801
802groupN_rec(X, V, [Y|R], dland(Fmt, RFmt), FmtGrp, FmtGrp) :-
803 groupN_rec(X, [Y|V], R, RFmt, Fmt, FmtGrp).
804
805
806collectexists(exists(Y, Formula), VarsSoFar, FormulaWithoutExists, Vars) :-
807 !, collectexists(Formula, [Y|VarsSoFar], FormulaWithoutExists, Vars).
808collectexists(Formula, Vars, Formula, Vars).
809
810
812
813dlnnf(X, Y) :- dlnnf(X, _, Y, _).
814
815dlnnf(all(X,F),FreeV,all(X,NNF),Paths) :- !,
816 dlnnf(F,[X|FreeV],NNF,Paths).
817
818dlnnf(exists(X,Fml),FreeV,exists(X,NNF),Paths) :- !,
819 dlnnf(Fml,[X|FreeV],NNF,Paths).
820
821dlnnf(atleast(N, X,Fml),FreeV,atleast(N,X,NNF),Paths) :- !,
822 dlnnf(Fml,[X|FreeV],NNF,Paths).
823
824dlnnf(atmost(N, X,Fml),FreeV,atmost(N,X,NNF),Paths) :- !,
825 dlnnf(Fml,[X|FreeV],NNF,Paths).
826
827dlnnf(dland(A,B),FreeV,NNF,Paths) :- !,
828 dlnnf(A,FreeV,NNF1,Paths1),
829 dlnnf(B,FreeV,NNF2,Paths2),
830 Paths is Paths1 * Paths2,
831 (Paths1 > Paths2 -> NNF = dland(NNF2,NNF1);
832 NNF = dland(NNF1,NNF2)).
833
834dlnnf(dlor(A,B),FreeV,NNF,Paths) :- !,
835 dlnnf(A,FreeV,NNF1,Paths1),
836 dlnnf(B,FreeV,NNF2,Paths2),
837 Paths is Paths1 + Paths2,
838 (Paths1 > Paths2 -> NNF = dlor(NNF2,NNF1);
839 NNF = dlor(NNF1,NNF2)).
840
841dlnnf(Fml,FreeV,NNF,Paths) :-
842 (Fml = dlnot(dlnot(A)) -> Fml1 = A;
843 Fml = dlnot(all(X,F)) -> Fml1 = exists(X,dlnot(F));
844 Fml = dlnot(exists(X,F)) -> Fml1 = all(X,dlnot(F));
845 Fml = dlnot(atleast(N,X,F)) -> N1 is N - 1, Fml1 = atmost(N1,X,F);
846 Fml = dlnot(atmost(N,X,F)) -> N1 is N + 1, Fml1 = atleast(N1,X,F);
847 Fml = dlnot(dlor(A,B)) -> Fml1 = dland( dlnot(A), dlnot(B) );
848 Fml = dlnot(dland(A,B)) -> Fml1 = dlor( dlnot(A), dlnot(B) );
849 Fml = dlimplies(A,B) -> Fml1 = dlor( dlnot(A), B );
850 Fml = dlnot(dlimplies(A,B)) -> Fml1 = dland( A, dlnot(B) );
851 Fml = dlequiv(A,B) -> Fml1 = dlor( dland(A, B), dland(dlnot(A), dlnot(B)) );
852 Fml = dlnot(dlequiv(A,B)) -> Fml1 = dlor( dland(A, dlnot(B)) , dland(dlnot(A), B) )
853 ),!,
854 dlnnf(Fml1,FreeV,NNF,Paths).
855
856dlnnf(Lit,_,Lit,1).
857
858
860dldnf(A, B) :- dnf(A, B).
861
862dnf( dlor(P,Q), dlor(P1,Q1) ) :- !, dnf(P, P1), dnf(Q, Q1).
863dnf( dland(P,Q), DNF) :- !, dnf(P, P1), dnf(Q, Q1), dnf1( dland(P1,Q1), DNF).
864dnf(DNF, DNF).
865
866dnf1( dland(P, dlor(Q,R)), dlor(P1,Q1) ):- !, dnf1( dland(P,Q), P1), dnf1( dland(P,R), Q1).
867dnf1( dland( dlor(P,Q), R), dlor(P1,Q1) ):- !, dnf1( dland(P,R), P1), dnf1( dland(Q,R), Q1).
868dnf1( DNF, DNF ).
869
872
873dlnpf(all(X, dland(A, B)), dland(all(X,A0), all(X,B0))) :- !,
874 dlnpf(A, A0), dlnpf(B, B0).
875
876dlnpf(all(X, dlor(A, B)), dlor(all(X,A0), all(X,B0))) :- !,
877 dlnpf(A, A0), dlnpf(B, B0).
878
879dlnpf(exists(X, dland(A, B)), dland(exists(X, A0), exists(X, B0))) :- !,
880 dlnpf(A, A0), dlnpf(B, B0).
881
882dlnpf(exists(X, dlor(A, B)), dlor(exists(X, A0), exists(X, B0))) :- !,
883 dlnpf(A, A0), dlnpf(B, B0).
884
885dlnpf(NPF, NPF)