kibi-core 0.22.5 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/schema/entities.pl +6 -0
- package/schema/validation.pl +4 -1
- package/src/certificate_check.pl +783 -0
- package/src/certificates.pl +245 -0
- package/src/checks.pl +23 -5
- package/src/claim_obligations.pl +378 -0
- package/src/code_certificates.pl +297 -0
- package/src/discovery.pl +176 -9
- package/src/intervals.pl +11 -0
- package/src/kb.pl +7 -0
- package/src/kb_consistency.pl +213 -0
- package/src/requirement_proof.pl +628 -33
- package/src/rule_registry.pl +20 -0
- package/src/semantic_quality.pl +1 -1
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
% Module: certificates
|
|
2
|
+
% implements REQ-kibi-kb-certificates
|
|
3
|
+
%
|
|
4
|
+
% Finds a certificate for every KB theorem that certificate_check.pl states:
|
|
5
|
+
% a model for each consistent property context, predicate atom and decision
|
|
6
|
+
% key, an irreducible core (with a model per dropped fact) for each
|
|
7
|
+
% contradiction, and a stratum assignment (or a negation cycle) for the
|
|
8
|
+
% stored rules. This module may search; certificate_check.pl re-checks
|
|
9
|
+
% everything it emits without trusting it.
|
|
10
|
+
|
|
11
|
+
:- module(certificates, [
|
|
12
|
+
kb_certificates/1,
|
|
13
|
+
kb_write_certificates/2
|
|
14
|
+
]).
|
|
15
|
+
|
|
16
|
+
:- encoding(utf8).
|
|
17
|
+
|
|
18
|
+
:- use_module(library(http/json)).
|
|
19
|
+
:- use_module(library(apply)).
|
|
20
|
+
:- use_module(library(lists)).
|
|
21
|
+
:- use_module(library(aggregate)).
|
|
22
|
+
:- use_module('kb.pl', []).
|
|
23
|
+
:- use_module('intervals.pl', [numeric_constraint_holds/3]).
|
|
24
|
+
:- use_module('certificate_check.pl', [
|
|
25
|
+
certificate_property_contexts/1,
|
|
26
|
+
certificate_predicate_groups/1,
|
|
27
|
+
certificate_decision_groups/1,
|
|
28
|
+
certificate_rule_edges/1,
|
|
29
|
+
certificate_member_holds/3,
|
|
30
|
+
certificate_members_satisfiable/2,
|
|
31
|
+
set_texts/2
|
|
32
|
+
]).
|
|
33
|
+
|
|
34
|
+
%% kb_write_certificates(+Path, -JsonString)
|
|
35
|
+
% Write the certificate bundle for the current KB to Path and return a
|
|
36
|
+
% summary (certificate count per kind) as a JSON string.
|
|
37
|
+
kb_write_certificates(Path, JsonString) :-
|
|
38
|
+
kb_certificates(Bundle),
|
|
39
|
+
setup_call_cleanup(
|
|
40
|
+
open(Path, write, Stream, [encoding(utf8)]),
|
|
41
|
+
( json_write_dict(Stream, Bundle, [width(0)]), nl(Stream) ),
|
|
42
|
+
close(Stream)),
|
|
43
|
+
findall(Kind, (member(Certificate, Bundle.certificates), get_dict(kind, Certificate, Kind)), Kinds0),
|
|
44
|
+
msort(Kinds0, Kinds),
|
|
45
|
+
clumped(Kinds, Counts),
|
|
46
|
+
findall(Kind-Count, member(Kind-Count, Counts), Pairs),
|
|
47
|
+
dict_pairs(ByKind, _, Pairs),
|
|
48
|
+
length(Bundle.certificates, Total),
|
|
49
|
+
with_output_to(string(JsonString),
|
|
50
|
+
json_write_dict(current_output, _{path: Path, certificates: Total, byKind: ByKind}, [width(0)])).
|
|
51
|
+
|
|
52
|
+
%% kb_certificates(-Bundle)
|
|
53
|
+
kb_certificates(_{version: 'kibi.certificates.v1', certificates: Certificates}) :-
|
|
54
|
+
certificate_property_contexts(Contexts),
|
|
55
|
+
convlist(property_certificate, Contexts, PropertyCertificates),
|
|
56
|
+
certificate_predicate_groups(AtomGroups),
|
|
57
|
+
convlist(group_certificate(predicate), AtomGroups, PredicateCertificates),
|
|
58
|
+
certificate_decision_groups(DecisionGroups),
|
|
59
|
+
convlist(group_certificate(decision), DecisionGroups, DecisionCertificates),
|
|
60
|
+
certificate_rule_edges(Edges),
|
|
61
|
+
rule_certificates(Edges, RuleCertificates),
|
|
62
|
+
append([PropertyCertificates, PredicateCertificates, DecisionCertificates, RuleCertificates], Certificates).
|
|
63
|
+
|
|
64
|
+
% ------------------------------------------------------------------
|
|
65
|
+
% Property contexts
|
|
66
|
+
% ------------------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
property_certificate(context(Subject, Property, Scope, Domain, Members), Certificate) :-
|
|
69
|
+
Base = _{subjectKey: Subject, propertyKey: Property, scope: Scope, domain: Domain},
|
|
70
|
+
( members_model(Domain, Members, Value)
|
|
71
|
+
-> findall(Fact, member(m(Fact, _, _, _, _), Members), Facts),
|
|
72
|
+
Certificate = Base.put(_{kind: property_model, value: Value, facts: Facts})
|
|
73
|
+
; irreducible_core(Domain, Members, Core),
|
|
74
|
+
findall(_{factId: Fact, value: Value},
|
|
75
|
+
( member(Dropped, Core),
|
|
76
|
+
Dropped = m(Fact, _, _, _, _),
|
|
77
|
+
exclude(==(Dropped), Core, Rest),
|
|
78
|
+
members_model(Domain, Rest, Value)
|
|
79
|
+
),
|
|
80
|
+
DropModels),
|
|
81
|
+
findall(Fact, member(m(Fact, _, _, _, _), Core), CoreFacts),
|
|
82
|
+
( core_windows_overlap(Core)
|
|
83
|
+
-> Kind = property_contradiction
|
|
84
|
+
; Kind = property_unresolved
|
|
85
|
+
),
|
|
86
|
+
Certificate = Base.put(_{kind: Kind, core: CoreFacts, dropModels: DropModels})
|
|
87
|
+
).
|
|
88
|
+
|
|
89
|
+
%% members_model(+Domain, +Members, -Value)
|
|
90
|
+
% A value satisfying every member, found among finitely many candidates that
|
|
91
|
+
% meet every region the members' bounds cut the line into.
|
|
92
|
+
members_model(Domain, Members, Value) :-
|
|
93
|
+
model_candidates(Domain, Members, Candidates),
|
|
94
|
+
member(Value, Candidates),
|
|
95
|
+
forall(member(Member, Members), certificate_member_holds(Domain, Member, Value)),
|
|
96
|
+
!.
|
|
97
|
+
|
|
98
|
+
model_candidates(Domain, Members, Candidates) :-
|
|
99
|
+
memberchk(Domain, [int, number]),
|
|
100
|
+
!,
|
|
101
|
+
findall(Bound, member(m(_, _, Bound, _, _), Members), Bounds0),
|
|
102
|
+
sort(Bounds0, Bounds),
|
|
103
|
+
( Domain == int
|
|
104
|
+
-> findall(Candidate,
|
|
105
|
+
( member(Bound, Bounds),
|
|
106
|
+
member(Base, [floor(Bound), ceiling(Bound)]),
|
|
107
|
+
member(Offset, [-1, 0, 1]),
|
|
108
|
+
Candidate is Base + Offset
|
|
109
|
+
),
|
|
110
|
+
Candidates0)
|
|
111
|
+
; findall(Candidate,
|
|
112
|
+
( member(Bound, Bounds), member(Offset, [-1, 0, 1]), Candidate is Bound + Offset
|
|
113
|
+
; nextto(Low, High, Bounds), Candidate is (Low + High) / 2
|
|
114
|
+
),
|
|
115
|
+
Candidates0)
|
|
116
|
+
),
|
|
117
|
+
sort([0|Candidates0], Candidates).
|
|
118
|
+
model_candidates(bool, _Members, [true, false]) :- !.
|
|
119
|
+
model_candidates(string, Members, Candidates) :-
|
|
120
|
+
findall(Bound, member(m(_, _, Bound, _, _), Members), Bounds0),
|
|
121
|
+
sort(Bounds0, Bounds),
|
|
122
|
+
fresh_text(Bounds, 0, Fresh),
|
|
123
|
+
append(Bounds, [Fresh], Candidates).
|
|
124
|
+
|
|
125
|
+
model_candidates(set, Members, Candidates) :-
|
|
126
|
+
findall(Set, (member(m(_, _, Bound, _, _), Members), set_texts(Bound, Set)), Sets0),
|
|
127
|
+
sort(Sets0, Sets),
|
|
128
|
+
findall(Text, (member(Set, Sets), member(Text, Set)), Texts),
|
|
129
|
+
fresh_text(Texts, 0, Fresh),
|
|
130
|
+
append(Sets, [[Fresh]], Candidates).
|
|
131
|
+
|
|
132
|
+
fresh_text(Bounds, Index, Fresh) :-
|
|
133
|
+
format(string(Candidate), "kibi:model:~w", [Index]),
|
|
134
|
+
( member(Bound, Bounds), text_value(Bound, Candidate)
|
|
135
|
+
-> Next is Index + 1,
|
|
136
|
+
fresh_text(Bounds, Next, Fresh)
|
|
137
|
+
; Fresh = Candidate
|
|
138
|
+
).
|
|
139
|
+
|
|
140
|
+
text_value(Value, Text) :- atom(Value), !, atom_string(Value, Text).
|
|
141
|
+
text_value(Value, Text) :- string(Value), !, Text = Value.
|
|
142
|
+
|
|
143
|
+
%% irreducible_core(+Domain, +Members, -Core)
|
|
144
|
+
% Deletion filter: drop each member whose removal keeps the set
|
|
145
|
+
% unsatisfiable. What remains admits no value, and every proper subset
|
|
146
|
+
% does.
|
|
147
|
+
irreducible_core(Domain, Members, Core) :-
|
|
148
|
+
foldl(core_step(Domain), Members, Members, Core).
|
|
149
|
+
|
|
150
|
+
core_step(Domain, Member, Current, Next) :-
|
|
151
|
+
exclude(==(Member), Current, Without),
|
|
152
|
+
( Without \== [],
|
|
153
|
+
\+ certificate_members_satisfiable(Domain, Without)
|
|
154
|
+
-> Next = Without
|
|
155
|
+
; Next = Current
|
|
156
|
+
).
|
|
157
|
+
|
|
158
|
+
core_windows_overlap(Core) :-
|
|
159
|
+
forall((member(m(_, _, _, FromA, ToA), Core), member(m(_, _, _, FromB, ToB), Core)),
|
|
160
|
+
kb:intervals_overlap(FromA, ToA, FromB, ToB)).
|
|
161
|
+
|
|
162
|
+
% ------------------------------------------------------------------
|
|
163
|
+
% Predicate atoms and decision keys
|
|
164
|
+
% ------------------------------------------------------------------
|
|
165
|
+
|
|
166
|
+
group_certificate(Prefix, group(Label, Members), Certificate) :-
|
|
167
|
+
atom_concat(Prefix, '_model', ModelKind),
|
|
168
|
+
atom_concat(Prefix, '_contradiction', ContradictionKind),
|
|
169
|
+
findall(Value, member(p(_, Value), Members), Values0),
|
|
170
|
+
sort(Values0, Values),
|
|
171
|
+
( Values = [Value]
|
|
172
|
+
-> findall(Fact, member(p(Fact, _), Members), Facts),
|
|
173
|
+
Certificate = Label.put(_{kind: ModelKind, value: Value, facts: Facts})
|
|
174
|
+
; Members = [p(FactA, ValueA)|_],
|
|
175
|
+
member(p(FactB, ValueB), Members),
|
|
176
|
+
ValueB \== ValueA,
|
|
177
|
+
!,
|
|
178
|
+
Certificate = Label.put(_{kind: ContradictionKind, core: [FactA, FactB]})
|
|
179
|
+
).
|
|
180
|
+
|
|
181
|
+
% ------------------------------------------------------------------
|
|
182
|
+
% Rule stratification
|
|
183
|
+
% ------------------------------------------------------------------
|
|
184
|
+
|
|
185
|
+
rule_certificates([], []) :- !.
|
|
186
|
+
rule_certificates(Edges, [Certificate]) :-
|
|
187
|
+
findall(Signature, (member(edge(Head, Body, _), Edges), member(Signature, [Head, Body])), Signatures0),
|
|
188
|
+
sort(Signatures0, Signatures),
|
|
189
|
+
findall(Signature-0, member(Signature, Signatures), Initial),
|
|
190
|
+
length(Signatures, Count),
|
|
191
|
+
Rounds is Count + 1,
|
|
192
|
+
( relax_strata(Rounds, Edges, Initial, Strata)
|
|
193
|
+
-> findall(_{namespace: Namespace, name: Name, arity: Arity, stratum: Stratum},
|
|
194
|
+
member(predicate(Namespace, Name, Arity)-Stratum, Strata),
|
|
195
|
+
Entries),
|
|
196
|
+
Certificate = _{kind: rule_strata, strata: Entries}
|
|
197
|
+
; negation_cycle(Edges, Cycle),
|
|
198
|
+
findall(_{head: HeadDict, body: BodyDict, sign: Sign},
|
|
199
|
+
( member(edge(Head, Body, Sign), Cycle),
|
|
200
|
+
signature_dict(Head, HeadDict),
|
|
201
|
+
signature_dict(Body, BodyDict)
|
|
202
|
+
),
|
|
203
|
+
Entries),
|
|
204
|
+
Certificate = _{kind: rule_negation_cycle, cycle: Entries}
|
|
205
|
+
).
|
|
206
|
+
|
|
207
|
+
signature_dict(predicate(Namespace, Name, Arity), _{namespace: Namespace, name: Name, arity: Arity}).
|
|
208
|
+
|
|
209
|
+
% Raise each head to at least its body's stratum (one more across a negated
|
|
210
|
+
% edge) until nothing changes. Without a negation cycle that happens within
|
|
211
|
+
% one round per predicate; a cycle keeps raising, and relaxation fails.
|
|
212
|
+
relax_strata(0, _Edges, _Strata, _Final) :- !, fail.
|
|
213
|
+
relax_strata(Rounds, Edges, Strata, Final) :-
|
|
214
|
+
foldl(relax_edge, Edges, Strata, Next),
|
|
215
|
+
( Next == Strata
|
|
216
|
+
-> Final = Strata
|
|
217
|
+
; Remaining is Rounds - 1,
|
|
218
|
+
relax_strata(Remaining, Edges, Next, Final)
|
|
219
|
+
).
|
|
220
|
+
|
|
221
|
+
relax_edge(edge(Head, Body, Sign), Strata, Next) :-
|
|
222
|
+
memberchk(Head-HeadStratum, Strata),
|
|
223
|
+
memberchk(Body-BodyStratum, Strata),
|
|
224
|
+
( Sign == negative -> Required is BodyStratum + 1 ; Required = BodyStratum ),
|
|
225
|
+
( HeadStratum < Required
|
|
226
|
+
-> selectchk(Head-HeadStratum, Strata, Head-Required, Next)
|
|
227
|
+
; Next = Strata
|
|
228
|
+
).
|
|
229
|
+
|
|
230
|
+
% A negated edge Head -> Body with a dependency path from Body back to Head.
|
|
231
|
+
negation_cycle(Edges, [edge(Head, Body, negative)|Path]) :-
|
|
232
|
+
member(edge(Head, Body, negative), Edges),
|
|
233
|
+
dependency_path(Body, Head, Edges, [Body], Path),
|
|
234
|
+
!.
|
|
235
|
+
|
|
236
|
+
dependency_path(Current, Target, _Edges, _Seen, []) :-
|
|
237
|
+
Current == Target,
|
|
238
|
+
!.
|
|
239
|
+
dependency_path(Current, Target, Edges, Seen, [edge(Current, Next, Sign)|Path]) :-
|
|
240
|
+
member(edge(Current, Next, Sign), Edges),
|
|
241
|
+
( Next == Target
|
|
242
|
+
-> Path = []
|
|
243
|
+
; \+ memberchk(Next, Seen),
|
|
244
|
+
dependency_path(Next, Target, Edges, [Next|Seen], Path)
|
|
245
|
+
).
|
package/src/checks.pl
CHANGED
|
@@ -50,6 +50,8 @@
|
|
|
50
50
|
check_subject_key_identity/1,
|
|
51
51
|
check_subject_key_shape/1,
|
|
52
52
|
check_ontology_quality/1,
|
|
53
|
+
check_kb_consistency/1,
|
|
54
|
+
check_kb_consistency_unresolved/1,
|
|
53
55
|
run_checks_json/0, % Entry point for JSON output
|
|
54
56
|
violation_id_text/2 % Extract text from entity ID term (exported for testing)
|
|
55
57
|
]).
|
|
@@ -75,6 +77,7 @@
|
|
|
75
77
|
:- use_module('logic_ir.pl', [logic_rule_safety/2, logic_rule_from_props/2, logic_rule_render/2, logic_rule_conflict/3, logic_rule_conflict_witness/4, logic_rules_stratified/1, logic_rule_missing_keys/4, functional_predicate_declarations/1, logic_rule_property_form/2]).
|
|
76
78
|
% GENERATED registry facts; single source is schema/rule-registry.json.
|
|
77
79
|
:- use_module('rule_registry.pl', [known_rule/1]).
|
|
80
|
+
:- use_module('kb_consistency.pl', [check_kb_consistency/1, check_kb_consistency_unresolved/1]).
|
|
78
81
|
|
|
79
82
|
% Required fields for all entities
|
|
80
83
|
required_fields([id, title, status, created_at, updated_at, source]).
|
|
@@ -125,6 +128,8 @@ check_all(ViolationsDict) :-
|
|
|
125
128
|
check_subject_key_identity(SubjectKeyIdentity),
|
|
126
129
|
check_subject_key_shape(SubjectKeyShape),
|
|
127
130
|
check_ontology_quality(OntologyQuality),
|
|
131
|
+
check_kb_consistency(KbConsistency),
|
|
132
|
+
check_kb_consistency_unresolved(KbConsistencyUnresolved),
|
|
128
133
|
ViolationsDict = _{
|
|
129
134
|
must_priority_coverage: MustPriority,
|
|
130
135
|
symbol_coverage: SymbolCoverage,
|
|
@@ -159,7 +164,9 @@ check_all(ViolationsDict) :-
|
|
|
159
164
|
domain_implication: DomainImplication,
|
|
160
165
|
subject_key_identity: SubjectKeyIdentity,
|
|
161
166
|
subject_key_shape: SubjectKeyShape,
|
|
162
|
-
ontology_quality: OntologyQuality
|
|
167
|
+
ontology_quality: OntologyQuality,
|
|
168
|
+
kb_consistency: KbConsistency,
|
|
169
|
+
kb_consistency_unresolved: KbConsistencyUnresolved
|
|
163
170
|
}.
|
|
164
171
|
|
|
165
172
|
%% check_must_priority_coverage(-Violations)
|
|
@@ -2370,7 +2377,7 @@ property_value_shape_error(Props, "Property value fact missing required field: o
|
|
|
2370
2377
|
property_value_shape_error(Props, "Property value fact missing required field: value_type") :-
|
|
2371
2378
|
memberchk(operator=_, Props),
|
|
2372
2379
|
\+ memberchk(value_type=_, Props).
|
|
2373
|
-
property_value_shape_error(Props, "Property value fact missing value field (value_string, value_int, value_number, or
|
|
2380
|
+
property_value_shape_error(Props, "Property value fact missing value field (value_string, value_int, value_number, value_bool, or value_set)") :-
|
|
2374
2381
|
memberchk(value_type=_, Props),
|
|
2375
2382
|
\+ has_value_field(Props).
|
|
2376
2383
|
property_value_shape_error(Props, "Property value fact has multiple value fields (should have exactly one)") :-
|
|
@@ -2387,17 +2394,20 @@ is_value_field(value_string).
|
|
|
2387
2394
|
is_value_field(value_int).
|
|
2388
2395
|
is_value_field(value_number).
|
|
2389
2396
|
is_value_field(value_bool).
|
|
2397
|
+
is_value_field(value_set).
|
|
2390
2398
|
|
|
2391
2399
|
has_value_field(Props) :- memberchk(value_string=_, Props), !.
|
|
2392
2400
|
has_value_field(Props) :- memberchk(value_int=_, Props), !.
|
|
2393
2401
|
has_value_field(Props) :- memberchk(value_number=_, Props), !.
|
|
2394
2402
|
has_value_field(Props) :- memberchk(value_bool=_, Props), !.
|
|
2403
|
+
has_value_field(Props) :- memberchk(value_set=_, Props), !.
|
|
2395
2404
|
|
|
2396
2405
|
% value_type_matches_field(+ValueType, +Props)
|
|
2397
2406
|
value_type_matches_field(string, Props) :- memberchk(value_string=_, Props), !.
|
|
2398
2407
|
value_type_matches_field(int, Props) :- memberchk(value_int=_, Props), !.
|
|
2399
2408
|
value_type_matches_field(number, Props) :- memberchk(value_number=_, Props), !.
|
|
2400
2409
|
value_type_matches_field(bool, Props) :- memberchk(value_bool=_, Props), !.
|
|
2410
|
+
value_type_matches_field(set, Props) :- memberchk(value_set=_, Props), !.
|
|
2401
2411
|
|
|
2402
2412
|
predicate_schema_shape_error(Props, "Predicate schema fact missing required field: predicate_name") :-
|
|
2403
2413
|
\+ memberchk(predicate_name=_, Props).
|
|
@@ -3663,7 +3673,9 @@ check_selected_dispatch(Rules, _{
|
|
|
3663
3673
|
domain_implication: DomainImplication,
|
|
3664
3674
|
subject_key_identity: SubjectKeyIdentity,
|
|
3665
3675
|
subject_key_shape: SubjectKeyShape,
|
|
3666
|
-
ontology_quality: OntologyQuality
|
|
3676
|
+
ontology_quality: OntologyQuality,
|
|
3677
|
+
kb_consistency: KbConsistency,
|
|
3678
|
+
kb_consistency_unresolved: KbConsistencyUnresolved
|
|
3667
3679
|
}) :-
|
|
3668
3680
|
selected_rule(Rules, 'must-priority-coverage', check_must_priority_coverage, MustPriority),
|
|
3669
3681
|
selected_rule(Rules, 'symbol-coverage', check_symbol_coverage, SymbolCoverage),
|
|
@@ -3698,7 +3710,9 @@ check_selected_dispatch(Rules, _{
|
|
|
3698
3710
|
selected_rule(Rules, 'domain-implication', check_domain_implication, DomainImplication),
|
|
3699
3711
|
selected_rule(Rules, 'subject-key-identity', check_subject_key_identity, SubjectKeyIdentity),
|
|
3700
3712
|
selected_rule(Rules, 'subject-key-shape', check_subject_key_shape, SubjectKeyShape),
|
|
3701
|
-
selected_rule(Rules, 'ontology-quality', check_ontology_quality, OntologyQuality)
|
|
3713
|
+
selected_rule(Rules, 'ontology-quality', check_ontology_quality, OntologyQuality),
|
|
3714
|
+
selected_rule(Rules, 'kb-consistency', check_kb_consistency, KbConsistency),
|
|
3715
|
+
selected_rule(Rules, 'kb-consistency-unresolved', check_kb_consistency_unresolved, KbConsistencyUnresolved).
|
|
3702
3716
|
|
|
3703
3717
|
selected_rule(Rules, Name, Goal, Violations) :-
|
|
3704
3718
|
( memberchk(Name, Rules)
|
|
@@ -3770,6 +3784,8 @@ check_all_with_options(ViolationsDict, RequireAdr) :-
|
|
|
3770
3784
|
check_subject_key_identity(SubjectKeyIdentity),
|
|
3771
3785
|
check_subject_key_shape(SubjectKeyShape),
|
|
3772
3786
|
check_ontology_quality(OntologyQuality),
|
|
3787
|
+
check_kb_consistency(KbConsistency),
|
|
3788
|
+
check_kb_consistency_unresolved(KbConsistencyUnresolved),
|
|
3773
3789
|
ViolationsDict = _{
|
|
3774
3790
|
must_priority_coverage: MustPriority,
|
|
3775
3791
|
symbol_coverage: SymbolCoverage,
|
|
@@ -3803,7 +3819,9 @@ check_all_with_options(ViolationsDict, RequireAdr) :-
|
|
|
3803
3819
|
domain_implication: DomainImplication,
|
|
3804
3820
|
subject_key_identity: SubjectKeyIdentity,
|
|
3805
3821
|
subject_key_shape: SubjectKeyShape,
|
|
3806
|
-
ontology_quality: OntologyQuality
|
|
3822
|
+
ontology_quality: OntologyQuality,
|
|
3823
|
+
kb_consistency: KbConsistency,
|
|
3824
|
+
kb_consistency_unresolved: KbConsistencyUnresolved
|
|
3807
3825
|
}.
|
|
3808
3826
|
|
|
3809
3827
|
%% violations_dict_to_json(+ViolationsDict, -JsonDict)
|