kibi-core 0.6.0 → 0.6.1
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/src/derived_chr.pl +65 -0
- package/src/discovery.pl +3 -3
- package/src/sparql_client.pl +150 -0
package/package.json
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
% Module: derived_chr
|
|
2
|
+
% Internal CHR pilot for bounded derived validation facts.
|
|
3
|
+
|
|
4
|
+
:- module(derived_chr, [
|
|
5
|
+
derive_chr_facts/0,
|
|
6
|
+
clear_chr_facts/0,
|
|
7
|
+
derived_coverage_gap/2,
|
|
8
|
+
derived_symbol_gap/2
|
|
9
|
+
]).
|
|
10
|
+
|
|
11
|
+
:- use_module(library(chr)).
|
|
12
|
+
:- use_module('kb.pl').
|
|
13
|
+
|
|
14
|
+
:- chr_constraint seen_must_req/1, seen_scenario/1, seen_test/1,
|
|
15
|
+
seen_production_symbol/1, seen_symbol_req_coverage/1.
|
|
16
|
+
|
|
17
|
+
:- dynamic derived_coverage_gap/2.
|
|
18
|
+
:- dynamic derived_symbol_gap/2.
|
|
19
|
+
:- dynamic snapshot_must_req/1.
|
|
20
|
+
:- dynamic snapshot_scenario/1.
|
|
21
|
+
:- dynamic snapshot_test/1.
|
|
22
|
+
:- dynamic snapshot_production_symbol/1.
|
|
23
|
+
:- dynamic snapshot_symbol_req_coverage/1.
|
|
24
|
+
|
|
25
|
+
seen_must_req(Req) <=> assertz(snapshot_must_req(Req)).
|
|
26
|
+
seen_scenario(Req) <=> assertz(snapshot_scenario(Req)).
|
|
27
|
+
seen_test(Req) <=> assertz(snapshot_test(Req)).
|
|
28
|
+
seen_production_symbol(Symbol) <=> assertz(snapshot_production_symbol(Symbol)).
|
|
29
|
+
seen_symbol_req_coverage(Symbol) <=> assertz(snapshot_symbol_req_coverage(Symbol)).
|
|
30
|
+
|
|
31
|
+
clear_chr_facts :-
|
|
32
|
+
retractall(derived_coverage_gap(_, _)),
|
|
33
|
+
retractall(derived_symbol_gap(_, _)),
|
|
34
|
+
retractall(snapshot_must_req(_)),
|
|
35
|
+
retractall(snapshot_scenario(_)),
|
|
36
|
+
retractall(snapshot_test(_)),
|
|
37
|
+
retractall(snapshot_production_symbol(_)),
|
|
38
|
+
retractall(snapshot_symbol_req_coverage(_)).
|
|
39
|
+
|
|
40
|
+
derive_chr_facts :-
|
|
41
|
+
clear_chr_facts,
|
|
42
|
+
forall(kb:must_requirement(Req), seen_must_req(Req)),
|
|
43
|
+
forall(kb:has_scenario(Req), seen_scenario(Req)),
|
|
44
|
+
forall(kb:has_test(Req), seen_test(Req)),
|
|
45
|
+
forall(kb:production_symbol(Symbol), seen_production_symbol(Symbol)),
|
|
46
|
+
forall(kb:production_symbol_covered_for_requirement(Symbol, _), seen_symbol_req_coverage(Symbol)),
|
|
47
|
+
derive_coverage_gaps,
|
|
48
|
+
derive_symbol_gaps.
|
|
49
|
+
|
|
50
|
+
derive_coverage_gaps :-
|
|
51
|
+
forall(
|
|
52
|
+
( snapshot_must_req(Req),
|
|
53
|
+
\+ snapshot_scenario(Req),
|
|
54
|
+
\+ snapshot_test(Req)
|
|
55
|
+
),
|
|
56
|
+
assertz(derived_coverage_gap(Req, missing_scenario_and_test))
|
|
57
|
+
).
|
|
58
|
+
|
|
59
|
+
derive_symbol_gaps :-
|
|
60
|
+
forall(
|
|
61
|
+
( snapshot_production_symbol(Symbol),
|
|
62
|
+
\+ snapshot_symbol_req_coverage(Symbol)
|
|
63
|
+
),
|
|
64
|
+
assertz(derived_symbol_gap(Symbol, no_qualifying_production_coverage))
|
|
65
|
+
).
|
package/src/discovery.pl
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
]).
|
|
9
9
|
|
|
10
10
|
:- use_module(library(http/json)).
|
|
11
|
+
:- use_module(library(aggregate)).
|
|
11
12
|
:- use_module('kb.pl').
|
|
12
13
|
:- use_module('status.pl', [status_meta_dict/1]).
|
|
13
14
|
:- use_module('../schema/relationships.pl', [relationship_type/1]).
|
|
@@ -90,10 +91,9 @@ relationship_counts(Id, CountsDict) :-
|
|
|
90
91
|
dict_pairs(CountsDict, relationship_counts, Pairs).
|
|
91
92
|
|
|
92
93
|
relationship_count(Id, Relationship, Count) :-
|
|
93
|
-
|
|
94
|
+
aggregate_all(count,
|
|
94
95
|
(kb_relationship(Relationship, Id, _); kb_relationship(Relationship, _, Id)),
|
|
95
|
-
|
|
96
|
-
length(Matches, Count).
|
|
96
|
+
Count).
|
|
97
97
|
|
|
98
98
|
coverage_rows(req, Tags, IncludePassing, IncludeTransitive, Rows, Summary) :-
|
|
99
99
|
!,
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
% Module: kibi_sparql_client
|
|
2
|
+
% Explicit remote SPARQL client wrapper.
|
|
3
|
+
|
|
4
|
+
:- module(kibi_sparql_client, [
|
|
5
|
+
remote_sparql_select_json/4
|
|
6
|
+
]).
|
|
7
|
+
|
|
8
|
+
:- use_module(library(error)).
|
|
9
|
+
:- use_module(library(http/json)).
|
|
10
|
+
:- use_module(library(semweb/sparql_client)).
|
|
11
|
+
|
|
12
|
+
remote_sparql_select_json(Endpoint, Query, Options, JsonString) :-
|
|
13
|
+
validate_non_empty_atom(endpoint, Endpoint),
|
|
14
|
+
validate_non_empty_atom(query, Query),
|
|
15
|
+
validate_remote_endpoint(Endpoint),
|
|
16
|
+
validate_select_query(Query),
|
|
17
|
+
validate_sparql_options(Options, SparqlOptions),
|
|
18
|
+
sparql_query(Query, Rows, [endpoint(Endpoint), variable_names(Variables)|SparqlOptions]),
|
|
19
|
+
maplist(row_json(Variables), Rows, JsonRows),
|
|
20
|
+
with_output_to(string(JsonString), json_write_dict(current_output, _{rows: JsonRows}, [])).
|
|
21
|
+
|
|
22
|
+
validate_non_empty_atom(Name, Value) :-
|
|
23
|
+
must_be(atom, Value),
|
|
24
|
+
( Value == ''
|
|
25
|
+
-> throw(error(domain_error(non_empty_atom, Name), _))
|
|
26
|
+
; true
|
|
27
|
+
).
|
|
28
|
+
|
|
29
|
+
validate_remote_endpoint(Endpoint) :-
|
|
30
|
+
( sub_atom(Endpoint, 0, _, _, 'http://')
|
|
31
|
+
; sub_atom(Endpoint, 0, _, _, 'https://')
|
|
32
|
+
),
|
|
33
|
+
endpoint_host(Endpoint, Host),
|
|
34
|
+
\+ local_or_private_host(Host),
|
|
35
|
+
!.
|
|
36
|
+
validate_remote_endpoint(Endpoint) :-
|
|
37
|
+
( sub_atom(Endpoint, 0, _, _, 'http://')
|
|
38
|
+
; sub_atom(Endpoint, 0, _, _, 'https://')
|
|
39
|
+
),
|
|
40
|
+
!,
|
|
41
|
+
throw(error(domain_error(public_remote_endpoint, Endpoint), _)).
|
|
42
|
+
validate_remote_endpoint(Endpoint) :-
|
|
43
|
+
throw(error(domain_error(remote_http_endpoint, Endpoint), _)).
|
|
44
|
+
|
|
45
|
+
validate_select_query(Query) :-
|
|
46
|
+
normalize_space(atom(Normalized), Query),
|
|
47
|
+
downcase_atom(Normalized, Lower),
|
|
48
|
+
sub_atom(Lower, 0, 6, After, 'select'),
|
|
49
|
+
( After =:= 0
|
|
50
|
+
; sub_atom(Lower, 6, 1, _, ' ')
|
|
51
|
+
; sub_atom(Lower, 6, 1, _, '*')
|
|
52
|
+
),
|
|
53
|
+
!.
|
|
54
|
+
validate_select_query(Query) :-
|
|
55
|
+
throw(error(domain_error(sparql_select_query, Query), _)).
|
|
56
|
+
|
|
57
|
+
endpoint_host(Endpoint, Host) :-
|
|
58
|
+
strip_endpoint_scheme(Endpoint, WithoutScheme),
|
|
59
|
+
segment_before(WithoutScheme, '/', WithoutPath),
|
|
60
|
+
segment_before(WithoutPath, '?', WithoutQuery),
|
|
61
|
+
segment_before(WithoutQuery, '#', Authority),
|
|
62
|
+
strip_userinfo(Authority, HostWithPort),
|
|
63
|
+
strip_port(HostWithPort, Host0),
|
|
64
|
+
downcase_atom(Host0, Host).
|
|
65
|
+
|
|
66
|
+
strip_endpoint_scheme(Endpoint, WithoutScheme) :-
|
|
67
|
+
sub_atom(Endpoint, 0, 7, _, 'http://'),
|
|
68
|
+
!,
|
|
69
|
+
sub_atom(Endpoint, 7, _, 0, WithoutScheme).
|
|
70
|
+
strip_endpoint_scheme(Endpoint, WithoutScheme) :-
|
|
71
|
+
sub_atom(Endpoint, 0, 8, _, 'https://'),
|
|
72
|
+
sub_atom(Endpoint, 8, _, 0, WithoutScheme).
|
|
73
|
+
|
|
74
|
+
segment_before(Atom, Delimiter, Segment) :-
|
|
75
|
+
sub_atom(Atom, Before, _, _, Delimiter),
|
|
76
|
+
!,
|
|
77
|
+
sub_atom(Atom, 0, Before, _, Segment).
|
|
78
|
+
segment_before(Atom, _Delimiter, Atom).
|
|
79
|
+
|
|
80
|
+
strip_userinfo(Authority, HostWithPort) :-
|
|
81
|
+
sub_atom(Authority, _, _, After, '@'),
|
|
82
|
+
!,
|
|
83
|
+
sub_atom(Authority, _, After, 0, HostWithPort).
|
|
84
|
+
strip_userinfo(Authority, Authority).
|
|
85
|
+
|
|
86
|
+
strip_port(HostWithPort, Host) :-
|
|
87
|
+
sub_atom(HostWithPort, 0, 1, _, '['),
|
|
88
|
+
sub_atom(HostWithPort, 1, Length, _, ']'),
|
|
89
|
+
!,
|
|
90
|
+
sub_atom(HostWithPort, 1, Length, _, Host).
|
|
91
|
+
strip_port(HostWithPort, Host) :-
|
|
92
|
+
segment_before(HostWithPort, ':', Host).
|
|
93
|
+
|
|
94
|
+
local_or_private_host(localhost).
|
|
95
|
+
local_or_private_host('0.0.0.0').
|
|
96
|
+
local_or_private_host('::1').
|
|
97
|
+
local_or_private_host(Host) :-
|
|
98
|
+
sub_atom(Host, _, _, 0, '.localhost').
|
|
99
|
+
local_or_private_host(Host) :-
|
|
100
|
+
sub_atom(Host, 0, _, _, '127.').
|
|
101
|
+
local_or_private_host(Host) :-
|
|
102
|
+
sub_atom(Host, 0, _, _, '10.').
|
|
103
|
+
local_or_private_host(Host) :-
|
|
104
|
+
sub_atom(Host, 0, _, _, '192.168.').
|
|
105
|
+
local_or_private_host(Host) :-
|
|
106
|
+
sub_atom(Host, 0, _, _, '169.254.').
|
|
107
|
+
local_or_private_host(Host) :-
|
|
108
|
+
sub_atom(Host, 0, _, _, 'fe80:').
|
|
109
|
+
local_or_private_host(Host) :-
|
|
110
|
+
sub_atom(Host, 0, 2, _, Prefix),
|
|
111
|
+
memberchk(Prefix, ['fc', 'fd']).
|
|
112
|
+
local_or_private_host(Host) :-
|
|
113
|
+
sub_atom(Host, 0, _, _, '172.'),
|
|
114
|
+
atomic_list_concat([_, SecondAtom|_], '.', Host),
|
|
115
|
+
atom_number(SecondAtom, Second),
|
|
116
|
+
Second >= 16,
|
|
117
|
+
Second =< 31.
|
|
118
|
+
|
|
119
|
+
validate_sparql_options([], []).
|
|
120
|
+
validate_sparql_options([result_format(json)|Rest], SparqlOptions) :-
|
|
121
|
+
!,
|
|
122
|
+
validate_sparql_options(Rest, SparqlOptions).
|
|
123
|
+
validate_sparql_options([timeout(Timeout)|Rest], [timeout(Timeout)|SparqlOptions]) :-
|
|
124
|
+
!,
|
|
125
|
+
validate_sparql_options(Rest, SparqlOptions).
|
|
126
|
+
validate_sparql_options([Option|_], _) :-
|
|
127
|
+
throw(error(domain_error(sparql_client_option, Option), _)).
|
|
128
|
+
|
|
129
|
+
row_json(Variables, Row, Dict) :-
|
|
130
|
+
Row =.. [row|Values],
|
|
131
|
+
pairs_json(Variables, Values, Pairs),
|
|
132
|
+
dict_create(Dict, row, Pairs).
|
|
133
|
+
|
|
134
|
+
pairs_json([], [], []).
|
|
135
|
+
pairs_json([Variable|Variables], [Value|Values], [Variable-JsonValue|Pairs]) :-
|
|
136
|
+
sparql_value_json(Value, JsonValue),
|
|
137
|
+
pairs_json(Variables, Values, Pairs).
|
|
138
|
+
|
|
139
|
+
sparql_value_json(Value, JsonValue) :-
|
|
140
|
+
atomic(Value),
|
|
141
|
+
!,
|
|
142
|
+
JsonValue = Value.
|
|
143
|
+
sparql_value_json(literal(Value), JsonValue) :-
|
|
144
|
+
!,
|
|
145
|
+
sparql_value_json(Value, JsonValue).
|
|
146
|
+
sparql_value_json(type(_Type, Value), JsonValue) :-
|
|
147
|
+
!,
|
|
148
|
+
sparql_value_json(Value, JsonValue).
|
|
149
|
+
sparql_value_json(Value, JsonValue) :-
|
|
150
|
+
term_string(Value, JsonValue).
|