eyeprolog 1.1.4 → 1.1.6
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/examples/dpv-odrl-purpose-mapping.pl +124 -0
- package/examples/odrl-dpv-fpv-trust-flow.pl +154 -0
- package/examples/odrl-dpv-healthcare-risk-ranked.pl +177 -0
- package/examples/odrl-dpv-risk-ranked.pl +201 -0
- package/examples/odrl-policy-advanced.pl +140 -0
- package/examples/odrl-policy.pl +80 -0
- package/examples/output/dpv-odrl-purpose-mapping.pl +18 -0
- package/examples/output/odrl-dpv-fpv-trust-flow.pl +9 -0
- package/examples/output/odrl-dpv-healthcare-risk-ranked.pl +15 -0
- package/examples/output/odrl-dpv-risk-ranked.pl +20 -0
- package/examples/output/odrl-policy-advanced.pl +6 -0
- package/examples/output/odrl-policy.pl +4 -0
- package/examples/output/rdf12-annotated-claims.pl +9 -0
- package/examples/output/rdf12-annotation.pl +4 -0
- package/examples/output/rdf12-directional-language.pl +2 -0
- package/examples/output/rdf12-nested-triple-term.pl +1 -0
- package/examples/output/rdf12-trig-graph-join.pl +1 -0
- package/examples/output/rdf12-trig-named-graph.pl +3 -0
- package/examples/output/rdf12-trig-triple-term.pl +1 -0
- package/examples/output/rdf12-triple-term.pl +1 -0
- package/examples/output/snaf.pl +1 -0
- package/examples/proof/snaf.pl +20 -0
- package/examples/rdf12-annotated-claims.pl +151 -0
- package/examples/rdf12-annotation.pl +54 -0
- package/examples/rdf12-directional-language.pl +24 -0
- package/examples/rdf12-nested-triple-term.pl +31 -0
- package/examples/rdf12-trig-graph-join.pl +34 -0
- package/examples/rdf12-trig-named-graph.pl +27 -0
- package/examples/rdf12-trig-triple-term.pl +27 -0
- package/examples/rdf12-triple-term.pl +27 -0
- package/examples/snaf.pl +12 -0
- package/package.json +1 -1
- package/playground.html +15 -0
- package/test/run-examples.mjs +1 -0
- package/the-art-of-eyeprolog.md +26 -2
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
% Adapted from rdf-prolog-roundtrip.
|
|
2
|
+
% This standalone program combines generated RDF input with its ISO Prolog rules.
|
|
3
|
+
|
|
4
|
+
% Generated by rdf-prolog-roundtrip.
|
|
5
|
+
|
|
6
|
+
% RDF terms use rdf(Subject, Predicate, Object, Graph).
|
|
7
|
+
|
|
8
|
+
rdf(iri('https://example.org/alpha_care_process'), iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), iri('https://w3id.org/dpv#Process'), default_graph).
|
|
9
|
+
rdf(iri('https://example.org/alpha_care_process'), iri('https://w3id.org/dpv#hasDataController'), iri('https://example.org/hospital_a'), default_graph).
|
|
10
|
+
rdf(iri('https://example.org/alpha_care_process'), iri('https://w3id.org/dpv#hasRecipient'), iri('https://example.org/research_partner'), default_graph).
|
|
11
|
+
rdf(iri('https://example.org/alpha_care_process'), iri('https://w3id.org/dpv#hasPersonalData'), iri('https://example.org/lab_result'), default_graph).
|
|
12
|
+
rdf(iri('https://example.org/alpha_care_process'), iri('https://w3id.org/dpv#hasProcessing'), iri('https://w3id.org/dpv#Use'), default_graph).
|
|
13
|
+
rdf(iri('https://example.org/alpha_care_process'), iri('https://w3id.org/dpv#hasPurpose'), iri('https://w3id.org/dpv#Healthcare'), default_graph).
|
|
14
|
+
rdf(iri('https://example.org/alpha_care_process'), iri('https://w3id.org/dpv#hasLegalBasis'), iri('https://w3id.org/dpv#Consent'), default_graph).
|
|
15
|
+
rdf(iri('https://example.org/alpha_policy'), iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), iri('http://www.w3.org/ns/odrl/2/Policy'), default_graph).
|
|
16
|
+
rdf(iri('https://example.org/alpha_policy'), iri('https://example.org/representsProcess'), iri('https://example.org/alpha_care_process'), default_graph).
|
|
17
|
+
rdf(iri('https://example.org/alpha_policy'), iri('http://www.w3.org/ns/odrl/2/permission'), iri('https://example.org/alpha_permission'), default_graph).
|
|
18
|
+
rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), iri('http://www.w3.org/ns/odrl/2/Permission'), default_graph).
|
|
19
|
+
rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/ns/odrl/2/assigner'), iri('https://example.org/hospital_a'), default_graph).
|
|
20
|
+
rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/ns/odrl/2/assignee'), iri('https://example.org/research_partner'), default_graph).
|
|
21
|
+
rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/ns/odrl/2/target'), iri('https://example.org/lab_result'), default_graph).
|
|
22
|
+
rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/ns/odrl/2/action'), iri('http://www.w3.org/ns/odrl/2/use'), default_graph).
|
|
23
|
+
rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/ns/odrl/2/constraint'), iri('https://example.org/alpha_purpose_constraint'), default_graph).
|
|
24
|
+
rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/ns/odrl/2/constraint'), iri('https://example.org/alpha_basis_constraint'), default_graph).
|
|
25
|
+
rdf(iri('https://example.org/alpha_purpose_constraint'), iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), iri('http://www.w3.org/ns/odrl/2/Constraint'), default_graph).
|
|
26
|
+
rdf(iri('https://example.org/alpha_purpose_constraint'), iri('http://www.w3.org/ns/odrl/2/leftOperand'), iri('http://www.w3.org/ns/odrl/2/purpose'), default_graph).
|
|
27
|
+
rdf(iri('https://example.org/alpha_purpose_constraint'), iri('http://www.w3.org/ns/odrl/2/operator'), iri('http://www.w3.org/ns/odrl/2/isA'), default_graph).
|
|
28
|
+
rdf(iri('https://example.org/alpha_purpose_constraint'), iri('http://www.w3.org/ns/odrl/2/rightOperand'), iri('https://w3id.org/dpv#Healthcare'), default_graph).
|
|
29
|
+
rdf(iri('https://example.org/alpha_basis_constraint'), iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), iri('http://www.w3.org/ns/odrl/2/Constraint'), default_graph).
|
|
30
|
+
rdf(iri('https://example.org/alpha_basis_constraint'), iri('http://www.w3.org/ns/odrl/2/leftOperand'), iri('https://example.org/legalBasis'), default_graph).
|
|
31
|
+
rdf(iri('https://example.org/alpha_basis_constraint'), iri('http://www.w3.org/ns/odrl/2/operator'), iri('http://www.w3.org/ns/odrl/2/isA'), default_graph).
|
|
32
|
+
rdf(iri('https://example.org/alpha_basis_constraint'), iri('http://www.w3.org/ns/odrl/2/rightOperand'), iri('https://w3id.org/dpv#Consent'), default_graph).
|
|
33
|
+
|
|
34
|
+
% The DPV process and ODRL policy are RDF data. The rules verify the six
|
|
35
|
+
% correspondences and return one deterministic mapping report.
|
|
36
|
+
%% goal: result_rdf(_, _, _, _)
|
|
37
|
+
|
|
38
|
+
dpv_odrl_purpose_mapping(Mappings) :-
|
|
39
|
+
findall(
|
|
40
|
+
mapping(SourceRole, Value, TargetRole),
|
|
41
|
+
mapped_role(SourceRole, Value, TargetRole),
|
|
42
|
+
Mappings
|
|
43
|
+
).
|
|
44
|
+
|
|
45
|
+
mapped_role(data_controller, Controller, assigner) :-
|
|
46
|
+
rdf_link(ex(alpha_care_process), dpv(hasDataController), ex(Controller)),
|
|
47
|
+
rdf_link(ex(alpha_permission), odrl(assigner), ex(Controller)).
|
|
48
|
+
|
|
49
|
+
mapped_role(recipient, Recipient, assignee) :-
|
|
50
|
+
rdf_link(ex(alpha_care_process), dpv(hasRecipient), ex(Recipient)),
|
|
51
|
+
rdf_link(ex(alpha_permission), odrl(assignee), ex(Recipient)).
|
|
52
|
+
|
|
53
|
+
mapped_role(personal_data, Data, target) :-
|
|
54
|
+
rdf_link(ex(alpha_care_process), dpv(hasPersonalData), ex(Data)),
|
|
55
|
+
rdf_link(ex(alpha_permission), odrl(target), ex(Data)).
|
|
56
|
+
|
|
57
|
+
mapped_role(processing, dpv_use, action) :-
|
|
58
|
+
rdf_link(ex(alpha_care_process), dpv(hasProcessing), dpv('Use')),
|
|
59
|
+
rdf_link(ex(alpha_permission), odrl(action), odrl(use)).
|
|
60
|
+
|
|
61
|
+
mapped_role(purpose, dpv_healthcare, constraint(alpha_purpose_constraint)) :-
|
|
62
|
+
rdf_link(ex(alpha_care_process), dpv(hasPurpose), dpv('Healthcare')),
|
|
63
|
+
odrl_constraint(alpha_purpose_constraint, odrl(purpose), dpv('Healthcare')).
|
|
64
|
+
|
|
65
|
+
mapped_role(legal_basis, dpv_consent, constraint(alpha_basis_constraint)) :-
|
|
66
|
+
rdf_link(ex(alpha_care_process), dpv(hasLegalBasis), dpv('Consent')),
|
|
67
|
+
odrl_constraint(alpha_basis_constraint, ex(legalBasis), dpv('Consent')).
|
|
68
|
+
|
|
69
|
+
odrl_constraint(Name, LeftOperand, RightOperand) :-
|
|
70
|
+
rdf_link(ex(alpha_permission), odrl(constraint), ex(Name)),
|
|
71
|
+
rdf_link(ex(Name), odrl('leftOperand'), LeftOperand),
|
|
72
|
+
rdf_link(ex(Name), odrl(operator), odrl('isA')),
|
|
73
|
+
rdf_link(ex(Name), odrl('rightOperand'), RightOperand).
|
|
74
|
+
|
|
75
|
+
rdf_link(Subject, Predicate, Object) :-
|
|
76
|
+
iri_term(Subject, SubjectIri),
|
|
77
|
+
iri_term(Predicate, PredicateIri),
|
|
78
|
+
rdf(iri(SubjectIri), iri(PredicateIri), iri(ObjectIri), default_graph),
|
|
79
|
+
iri_term(Object, ObjectIri).
|
|
80
|
+
|
|
81
|
+
iri_term(ex(Name), Iri) :- namespace_iri('https://example.org/', Name, Iri).
|
|
82
|
+
iri_term(dpv(Name), Iri) :- namespace_iri('https://w3id.org/dpv#', Name, Iri).
|
|
83
|
+
iri_term(odrl(Name), Iri) :- namespace_iri('http://www.w3.org/ns/odrl/2/', Name, Iri).
|
|
84
|
+
|
|
85
|
+
namespace_iri(Prefix, Name, Iri) :- atom_concat(Prefix, Name, Iri).
|
|
86
|
+
|
|
87
|
+
% RDF form of every verified DPV -> ODRL mapping.
|
|
88
|
+
result_rdf(iri(Node), iri('https://example.org/sourceRole'), iri(RoleIri), default_graph) :-
|
|
89
|
+
mapped_role(Role, _Value, _Target),
|
|
90
|
+
mapping_node(Role, Node),
|
|
91
|
+
mapping_role_iri(Role, RoleIri).
|
|
92
|
+
result_rdf(iri(Node), iri('https://example.org/value'), iri(ValueIri), default_graph) :-
|
|
93
|
+
mapped_role(Role, Value, _Target),
|
|
94
|
+
mapping_node(Role, Node),
|
|
95
|
+
mapping_value_iri(Role, Value, ValueIri).
|
|
96
|
+
result_rdf(iri(Node), iri('https://example.org/mappingTarget'), iri(TargetIri), default_graph) :-
|
|
97
|
+
mapped_role(Role, _Value, Target),
|
|
98
|
+
mapping_node(Role, Node),
|
|
99
|
+
mapping_target_iri(Target, TargetIri).
|
|
100
|
+
|
|
101
|
+
mapping_node(Role, Iri) :- atom_concat('https://example.org/result/mapping/', Role, Iri).
|
|
102
|
+
mapping_role_iri(Role, Iri) :- atom_concat('https://example.org/role/', Role, Iri).
|
|
103
|
+
|
|
104
|
+
mapping_value_iri(data_controller, Value, Iri) :- iri_term(ex(Value), Iri).
|
|
105
|
+
mapping_value_iri(recipient, Value, Iri) :- iri_term(ex(Value), Iri).
|
|
106
|
+
mapping_value_iri(personal_data, Value, Iri) :- iri_term(ex(Value), Iri).
|
|
107
|
+
mapping_value_iri(processing, dpv_use, Iri) :- iri_term(dpv('Use'), Iri).
|
|
108
|
+
mapping_value_iri(purpose, dpv_healthcare, Iri) :- iri_term(dpv('Healthcare'), Iri).
|
|
109
|
+
mapping_value_iri(legal_basis, dpv_consent, Iri) :- iri_term(dpv('Consent'), Iri).
|
|
110
|
+
|
|
111
|
+
mapping_target_iri(assigner, Iri) :- iri_term(odrl(assigner), Iri).
|
|
112
|
+
mapping_target_iri(assignee, Iri) :- iri_term(odrl(assignee), Iri).
|
|
113
|
+
mapping_target_iri(target, Iri) :- iri_term(odrl(target), Iri).
|
|
114
|
+
mapping_target_iri(action, Iri) :- iri_term(odrl(action), Iri).
|
|
115
|
+
mapping_target_iri(constraint(Name), Iri) :- iri_term(ex(Name), Iri).
|
|
116
|
+
|
|
117
|
+
% ISO Prolog helper: print the complete test result as rdf/4 facts.
|
|
118
|
+
write_results :-
|
|
119
|
+
result_rdf(S, P, O, G),
|
|
120
|
+
write_term(rdf(S, P, O, G), [quoted(true)]),
|
|
121
|
+
write('.'),
|
|
122
|
+
nl,
|
|
123
|
+
fail.
|
|
124
|
+
write_results.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
% Adapted from rdf-prolog-roundtrip.
|
|
2
|
+
% This standalone program combines generated RDF input with its ISO Prolog rules.
|
|
3
|
+
|
|
4
|
+
% Generated by rdf-prolog-roundtrip.
|
|
5
|
+
|
|
6
|
+
% RDF terms use rdf(Subject, Predicate, Object, Graph).
|
|
7
|
+
|
|
8
|
+
rdf(iri('https://example.org/trust-policy'), iri('http://www.w3.org/ns/odrl/2/permission'), iri('https://example.org/healthcare-permission'), default_graph).
|
|
9
|
+
rdf(iri('https://example.org/trust-policy'), iri('http://www.w3.org/ns/odrl/2/prohibition'), iri('https://example.org/marketing-prohibition'), default_graph).
|
|
10
|
+
rdf(iri('https://example.org/healthcare-permission'), iri('http://www.w3.org/ns/odrl/2/assignee'), iri('https://example.org/research-partner'), default_graph).
|
|
11
|
+
rdf(iri('https://example.org/healthcare-permission'), iri('http://www.w3.org/ns/odrl/2/target'), iri('https://example.org/lab-result'), default_graph).
|
|
12
|
+
rdf(iri('https://example.org/healthcare-permission'), iri('http://www.w3.org/ns/odrl/2/action'), iri('http://www.w3.org/ns/odrl/2/use'), default_graph).
|
|
13
|
+
rdf(iri('https://example.org/healthcare-permission'), iri('http://www.w3.org/ns/odrl/2/purpose'), iri('https://example.org/healthcare'), default_graph).
|
|
14
|
+
rdf(iri('https://example.org/healthcare-permission'), iri('https://example.org/minTrust'), literal('0.80', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
15
|
+
rdf(iri('https://example.org/marketing-prohibition'), iri('http://www.w3.org/ns/odrl/2/assignee'), iri('https://example.org/ad-network'), default_graph).
|
|
16
|
+
rdf(iri('https://example.org/marketing-prohibition'), iri('http://www.w3.org/ns/odrl/2/target'), iri('https://example.org/lab-result'), default_graph).
|
|
17
|
+
rdf(iri('https://example.org/marketing-prohibition'), iri('http://www.w3.org/ns/odrl/2/action'), iri('http://www.w3.org/ns/odrl/2/distribute'), default_graph).
|
|
18
|
+
rdf(iri('https://example.org/marketing-prohibition'), iri('http://www.w3.org/ns/odrl/2/purpose'), iri('https://example.org/marketing'), default_graph).
|
|
19
|
+
rdf(iri('https://example.org/hospital-a'), iri('https://example.org/trustScore'), literal('0.92', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
20
|
+
rdf(iri('https://example.org/small-clinic'), iri('https://example.org/trustScore'), literal('0.63', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
21
|
+
rdf(iri('https://example.org/ad-network'), iri('https://example.org/trustScore'), literal('0.28', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
22
|
+
rdf(iri('https://example.org/flow-care'), iri('https://example.org/source'), iri('https://example.org/hospital-a'), default_graph).
|
|
23
|
+
rdf(iri('https://example.org/flow-care'), iri('https://example.org/recipient'), iri('https://example.org/research-partner'), default_graph).
|
|
24
|
+
rdf(iri('https://example.org/flow-care'), iri('https://example.org/data'), iri('https://example.org/lab-result'), default_graph).
|
|
25
|
+
rdf(iri('https://example.org/flow-care'), iri('https://example.org/requestedAction'), iri('http://www.w3.org/ns/odrl/2/use'), default_graph).
|
|
26
|
+
rdf(iri('https://example.org/flow-care'), iri('https://example.org/requestedPurpose'), iri('https://example.org/healthcare'), default_graph).
|
|
27
|
+
rdf(iri('https://example.org/flow-clinic'), iri('https://example.org/source'), iri('https://example.org/small-clinic'), default_graph).
|
|
28
|
+
rdf(iri('https://example.org/flow-clinic'), iri('https://example.org/recipient'), iri('https://example.org/research-partner'), default_graph).
|
|
29
|
+
rdf(iri('https://example.org/flow-clinic'), iri('https://example.org/data'), iri('https://example.org/lab-result'), default_graph).
|
|
30
|
+
rdf(iri('https://example.org/flow-clinic'), iri('https://example.org/requestedAction'), iri('http://www.w3.org/ns/odrl/2/use'), default_graph).
|
|
31
|
+
rdf(iri('https://example.org/flow-clinic'), iri('https://example.org/requestedPurpose'), iri('https://example.org/healthcare'), default_graph).
|
|
32
|
+
rdf(iri('https://example.org/flow-ads'), iri('https://example.org/source'), iri('https://example.org/hospital-a'), default_graph).
|
|
33
|
+
rdf(iri('https://example.org/flow-ads'), iri('https://example.org/recipient'), iri('https://example.org/ad-network'), default_graph).
|
|
34
|
+
rdf(iri('https://example.org/flow-ads'), iri('https://example.org/data'), iri('https://example.org/lab-result'), default_graph).
|
|
35
|
+
rdf(iri('https://example.org/flow-ads'), iri('https://example.org/requestedAction'), iri('http://www.w3.org/ns/odrl/2/distribute'), default_graph).
|
|
36
|
+
rdf(iri('https://example.org/flow-ads'), iri('https://example.org/requestedPurpose'), iri('https://example.org/marketing'), default_graph).
|
|
37
|
+
|
|
38
|
+
% ODRL policy rules, trust scores, and requested flows are RDF data. The rules
|
|
39
|
+
% produce one deterministic FPV-style decision report.
|
|
40
|
+
%% goal: result_rdf(_, _, _, _)
|
|
41
|
+
|
|
42
|
+
trust_flow_report([Care, Clinic, Ads]) :-
|
|
43
|
+
flow_decision(flow_care, Care),
|
|
44
|
+
flow_decision(flow_clinic, Clinic),
|
|
45
|
+
flow_decision(flow_ads, Ads).
|
|
46
|
+
|
|
47
|
+
flow_decision(Flow, decision(Flow, permit, confidence(Score), status(executable_flow))) :-
|
|
48
|
+
permitted_flow(Flow, Score).
|
|
49
|
+
flow_decision(Flow, decision(Flow, review, confidence(Score), risk(trustworthiness_risk))) :-
|
|
50
|
+
review_flow(Flow, Score).
|
|
51
|
+
flow_decision(Flow, decision(Flow, deny, status(blocked_flow), risk(unwanted_disclosure))) :-
|
|
52
|
+
prohibited_flow(Flow).
|
|
53
|
+
|
|
54
|
+
permitted_flow(Flow, Score) :-
|
|
55
|
+
flow_request(Flow, Source, Recipient, Data, Action, Purpose),
|
|
56
|
+
policy_rule(odrl(permission), Rule, Recipient, Data, Action, Purpose),
|
|
57
|
+
rdf_number(Rule, ex(minTrust), Minimum),
|
|
58
|
+
rdf_number(Source, ex(trustScore), Score),
|
|
59
|
+
Score >= Minimum.
|
|
60
|
+
|
|
61
|
+
review_flow(Flow, Score) :-
|
|
62
|
+
flow_request(Flow, Source, Recipient, Data, Action, Purpose),
|
|
63
|
+
policy_rule(odrl(permission), Rule, Recipient, Data, Action, Purpose),
|
|
64
|
+
rdf_number(Rule, ex(minTrust), Minimum),
|
|
65
|
+
rdf_number(Source, ex(trustScore), Score),
|
|
66
|
+
Score < Minimum.
|
|
67
|
+
|
|
68
|
+
prohibited_flow(Flow) :-
|
|
69
|
+
flow_request(Flow, _Source, Recipient, Data, Action, Purpose),
|
|
70
|
+
policy_rule(odrl(prohibition), _Rule, Recipient, Data, Action, Purpose).
|
|
71
|
+
|
|
72
|
+
flow_request(Flow, Source, Recipient, Data, Action, Purpose) :-
|
|
73
|
+
flow_resource(Flow, Resource),
|
|
74
|
+
rdf_link(Resource, ex(source), Source),
|
|
75
|
+
rdf_link(Resource, ex(recipient), Recipient),
|
|
76
|
+
rdf_link(Resource, ex(data), Data),
|
|
77
|
+
rdf_link(Resource, ex(requestedAction), Action),
|
|
78
|
+
rdf_link(Resource, ex(requestedPurpose), Purpose).
|
|
79
|
+
|
|
80
|
+
policy_rule(Type, Rule, Recipient, Data, Action, Purpose) :-
|
|
81
|
+
rdf_link(ex('trust-policy'), Type, Rule),
|
|
82
|
+
rdf_link(Rule, odrl(assignee), Recipient),
|
|
83
|
+
rdf_link(Rule, odrl(target), Data),
|
|
84
|
+
rdf_link(Rule, odrl(action), Action),
|
|
85
|
+
rdf_link(Rule, odrl(purpose), Purpose).
|
|
86
|
+
|
|
87
|
+
flow_resource(flow_care, ex('flow-care')).
|
|
88
|
+
flow_resource(flow_clinic, ex('flow-clinic')).
|
|
89
|
+
flow_resource(flow_ads, ex('flow-ads')).
|
|
90
|
+
|
|
91
|
+
rdf_link(Subject, Predicate, Object) :-
|
|
92
|
+
iri_term(Subject, SubjectIri),
|
|
93
|
+
iri_term(Predicate, PredicateIri),
|
|
94
|
+
rdf(iri(SubjectIri), iri(PredicateIri), iri(ObjectIri), default_graph),
|
|
95
|
+
iri_term(Object, ObjectIri).
|
|
96
|
+
|
|
97
|
+
rdf_number(Subject, Predicate, Number) :-
|
|
98
|
+
iri_term(Subject, SubjectIri),
|
|
99
|
+
iri_term(Predicate, PredicateIri),
|
|
100
|
+
rdf(iri(SubjectIri), iri(PredicateIri), literal(Text, datatype(_Datatype)), default_graph),
|
|
101
|
+
atom_chars(Text, Chars),
|
|
102
|
+
number_chars(Number, Chars).
|
|
103
|
+
|
|
104
|
+
iri_term(ex(Name), Iri) :- namespace_iri('https://example.org/', Name, Iri).
|
|
105
|
+
iri_term(odrl(Name), Iri) :- namespace_iri('http://www.w3.org/ns/odrl/2/', Name, Iri).
|
|
106
|
+
|
|
107
|
+
namespace_iri(Prefix, Name, Iri) :- atom_concat(Prefix, Name, Iri).
|
|
108
|
+
|
|
109
|
+
% RDF form of each flow decision.
|
|
110
|
+
result_rdf(iri(FlowIri), iri('https://example.org/decision'), iri(DecisionIri), default_graph) :-
|
|
111
|
+
flow_decision(Flow, DecisionTerm),
|
|
112
|
+
decision_name(DecisionTerm, Decision),
|
|
113
|
+
flow_resource(Flow, FlowResource),
|
|
114
|
+
iri_term(FlowResource, FlowIri),
|
|
115
|
+
atom_concat('https://example.org/', Decision, DecisionIri).
|
|
116
|
+
result_rdf(iri(FlowIri), iri('https://example.org/confidence'), literal(Text, datatype('http://www.w3.org/2001/XMLSchema#decimal')), default_graph) :-
|
|
117
|
+
flow_decision(Flow, DecisionTerm),
|
|
118
|
+
decision_has_confidence(DecisionTerm),
|
|
119
|
+
flow_resource(Flow, FlowResource),
|
|
120
|
+
iri_term(FlowResource, FlowIri),
|
|
121
|
+
flow_request(Flow, Source, _Recipient, _Data, _Action, _Purpose),
|
|
122
|
+
iri_term(Source, SourceIri),
|
|
123
|
+
rdf(iri(SourceIri), iri('https://example.org/trustScore'), literal(Text, datatype(_)), default_graph).
|
|
124
|
+
result_rdf(iri(FlowIri), iri('https://example.org/status'), iri(StatusIri), default_graph) :-
|
|
125
|
+
flow_decision(Flow, DecisionTerm),
|
|
126
|
+
decision_status(DecisionTerm, Status),
|
|
127
|
+
flow_resource(Flow, FlowResource),
|
|
128
|
+
iri_term(FlowResource, FlowIri),
|
|
129
|
+
atom_concat('https://example.org/', Status, StatusIri).
|
|
130
|
+
result_rdf(iri(FlowIri), iri('https://example.org/risk'), iri(RiskIri), default_graph) :-
|
|
131
|
+
flow_decision(Flow, DecisionTerm),
|
|
132
|
+
decision_risk(DecisionTerm, Risk),
|
|
133
|
+
flow_resource(Flow, FlowResource),
|
|
134
|
+
iri_term(FlowResource, FlowIri),
|
|
135
|
+
atom_concat('https://example.org/', Risk, RiskIri).
|
|
136
|
+
|
|
137
|
+
decision_name(decision(_, permit, _, _), permit).
|
|
138
|
+
decision_name(decision(_, review, _, _), review).
|
|
139
|
+
decision_name(decision(_, deny, _, _), deny).
|
|
140
|
+
decision_has_confidence(decision(_, permit, confidence(_), _)).
|
|
141
|
+
decision_has_confidence(decision(_, review, confidence(_), _)).
|
|
142
|
+
decision_status(decision(_, permit, _, status(Status)), Status).
|
|
143
|
+
decision_status(decision(_, deny, status(Status), _), Status).
|
|
144
|
+
decision_risk(decision(_, review, _, risk(Risk)), Risk).
|
|
145
|
+
decision_risk(decision(_, deny, _, risk(Risk)), Risk).
|
|
146
|
+
|
|
147
|
+
% ISO Prolog helper: print the complete test result as rdf/4 facts.
|
|
148
|
+
write_results :-
|
|
149
|
+
result_rdf(S, P, O, G),
|
|
150
|
+
write_term(rdf(S, P, O, G), [quoted(true)]),
|
|
151
|
+
write('.'),
|
|
152
|
+
nl,
|
|
153
|
+
fail.
|
|
154
|
+
write_results.
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
% Adapted from rdf-prolog-roundtrip.
|
|
2
|
+
% This standalone program combines generated RDF input with its ISO Prolog rules.
|
|
3
|
+
|
|
4
|
+
% Generated by rdf-prolog-roundtrip.
|
|
5
|
+
|
|
6
|
+
% RDF terms use rdf(Subject, Predicate, Object, Graph).
|
|
7
|
+
|
|
8
|
+
rdf(iri('https://example.org/healthcare-policy'), iri('http://www.w3.org/ns/odrl/2/permission'), iri('https://example.org/research-use'), default_graph).
|
|
9
|
+
rdf(iri('https://example.org/healthcare-policy'), iri('http://www.w3.org/ns/odrl/2/permission'), iri('https://example.org/genomic-sharing'), default_graph).
|
|
10
|
+
rdf(iri('https://example.org/healthcare-policy'), iri('http://www.w3.org/ns/odrl/2/permission'), iri('https://example.org/record-retention'), default_graph).
|
|
11
|
+
rdf(iri('https://example.org/healthcare-policy'), iri('https://example.org/riskProfile'), iri('https://example.org/consent-profile'), default_graph).
|
|
12
|
+
rdf(iri('https://example.org/healthcare-policy'), iri('https://example.org/riskProfile'), iri('https://example.org/sharing-profile'), default_graph).
|
|
13
|
+
rdf(iri('https://example.org/healthcare-policy'), iri('https://example.org/riskProfile'), iri('https://example.org/retention-profile'), default_graph).
|
|
14
|
+
rdf(iri('https://example.org/research-use'), iri('https://example.org/clause'), literal('h1', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
15
|
+
rdf(iri('https://example.org/research-use'), iri('http://www.w3.org/ns/odrl/2/action'), iri('http://www.w3.org/ns/odrl/2/use'), default_graph).
|
|
16
|
+
rdf(iri('https://example.org/genomic-sharing'), iri('https://example.org/clause'), literal('h2', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
17
|
+
rdf(iri('https://example.org/genomic-sharing'), iri('http://www.w3.org/ns/odrl/2/action'), iri('https://example.org/disclose'), default_graph).
|
|
18
|
+
rdf(iri('https://example.org/genomic-sharing'), iri('http://www.w3.org/ns/odrl/2/target'), iri('https://example.org/genomic-data'), default_graph).
|
|
19
|
+
rdf(iri('https://example.org/record-retention'), iri('https://example.org/clause'), literal('h4', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
20
|
+
rdf(iri('https://example.org/record-retention'), iri('http://www.w3.org/ns/odrl/2/constraint'), iri('https://example.org/retention-constraint'), default_graph).
|
|
21
|
+
rdf(iri('https://example.org/retention-constraint'), iri('http://www.w3.org/ns/odrl/2/leftOperand'), iri('https://example.org/retentionDays'), default_graph).
|
|
22
|
+
rdf(iri('https://example.org/retention-constraint'), iri('http://www.w3.org/ns/odrl/2/operator'), iri('http://www.w3.org/ns/odrl/2/eq'), default_graph).
|
|
23
|
+
rdf(iri('https://example.org/retention-constraint'), iri('http://www.w3.org/ns/odrl/2/rightOperand'), literal('3650', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
24
|
+
rdf(iri('https://example.org/consent-profile'), iri('https://example.org/risk'), iri('https://example.org/consent-risk'), default_graph).
|
|
25
|
+
rdf(iri('https://example.org/consent-profile'), iri('https://example.org/policyRule'), iri('https://example.org/research-use'), default_graph).
|
|
26
|
+
rdf(iri('https://example.org/consent-profile'), iri('https://example.org/need'), iri('https://example.org/explicit-consent-for-research'), default_graph).
|
|
27
|
+
rdf(iri('https://example.org/consent-profile'), iri('https://example.org/baseScore'), literal('85', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
28
|
+
rdf(iri('https://example.org/consent-profile'), iri('https://example.org/mitigation'), iri('https://example.org/require-explicit-consent'), default_graph).
|
|
29
|
+
rdf(iri('https://example.org/sharing-profile'), iri('https://example.org/risk'), iri('https://example.org/sharing-risk'), default_graph).
|
|
30
|
+
rdf(iri('https://example.org/sharing-profile'), iri('https://example.org/policyRule'), iri('https://example.org/genomic-sharing'), default_graph).
|
|
31
|
+
rdf(iri('https://example.org/sharing-profile'), iri('https://example.org/need'), iri('https://example.org/deidentify-before-sharing'), default_graph).
|
|
32
|
+
rdf(iri('https://example.org/sharing-profile'), iri('https://example.org/baseScore'), literal('90', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
33
|
+
rdf(iri('https://example.org/sharing-profile'), iri('https://example.org/mitigation'), iri('https://example.org/require-deidentification'), default_graph).
|
|
34
|
+
rdf(iri('https://example.org/retention-profile'), iri('https://example.org/risk'), iri('https://example.org/retention-risk'), default_graph).
|
|
35
|
+
rdf(iri('https://example.org/retention-profile'), iri('https://example.org/policyRule'), iri('https://example.org/record-retention'), default_graph).
|
|
36
|
+
rdf(iri('https://example.org/retention-profile'), iri('https://example.org/need'), iri('https://example.org/retention-limit-3-years'), default_graph).
|
|
37
|
+
rdf(iri('https://example.org/retention-profile'), iri('https://example.org/baseScore'), literal('55', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
38
|
+
rdf(iri('https://example.org/retention-profile'), iri('https://example.org/mitigation'), iri('https://example.org/limit-retention-to-1095-days'), default_graph).
|
|
39
|
+
rdf(iri('https://example.org/explicit-consent-for-research'), iri('https://example.org/importance'), literal('35', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
40
|
+
rdf(iri('https://example.org/deidentify-before-sharing'), iri('https://example.org/importance'), literal('35', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
41
|
+
rdf(iri('https://example.org/retention-limit-3-years'), iri('https://example.org/importance'), literal('15', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
42
|
+
rdf(iri('https://example.org/retention-limit-3-years'), iri('https://example.org/maximumDays'), literal('1095', datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph).
|
|
43
|
+
|
|
44
|
+
% ODRL permissions and DPV-style risk profiles are RDF data. The rules detect
|
|
45
|
+
% missing safeguards, score the risks, and return one deterministic ranking.
|
|
46
|
+
%% goal: result_rdf(_, _, _, _)
|
|
47
|
+
|
|
48
|
+
healthcare_risk_report(Ranked) :-
|
|
49
|
+
findall(
|
|
50
|
+
key(InverseScore, Clause)-dpv_risk(Risk, Score, Level, Clause, Mitigation),
|
|
51
|
+
(
|
|
52
|
+
risk_report(Risk, Score, Level, Clause, Mitigation),
|
|
53
|
+
InverseScore is 1000 - Score
|
|
54
|
+
),
|
|
55
|
+
Unsorted
|
|
56
|
+
),
|
|
57
|
+
sort(Unsorted, Sorted),
|
|
58
|
+
ranked_values(Sorted, 1, Ranked).
|
|
59
|
+
|
|
60
|
+
risk_report(Risk, Score, Level, Clause, Mitigation) :-
|
|
61
|
+
risk_profile(_Profile, Risk, Rule, Need, Base, Mitigation),
|
|
62
|
+
risk_triggered(Risk, Rule, Need),
|
|
63
|
+
rdf_text(Rule, ex(clause), ClauseText),
|
|
64
|
+
Clause = ClauseText,
|
|
65
|
+
rdf_number(Need, ex(importance), Importance),
|
|
66
|
+
Raw is Base + Importance,
|
|
67
|
+
(Raw > 100 -> Score = 100 ; Score = Raw),
|
|
68
|
+
risk_level(Score, Level).
|
|
69
|
+
|
|
70
|
+
risk_profile(Profile, Risk, Rule, Need, Base, Mitigation) :-
|
|
71
|
+
rdf_link(ex('healthcare-policy'), ex(riskProfile), Profile),
|
|
72
|
+
rdf_link(Profile, ex(risk), RiskResource),
|
|
73
|
+
risk_resource(Risk, RiskResource),
|
|
74
|
+
rdf_link(Profile, ex(policyRule), Rule),
|
|
75
|
+
rdf_link(Profile, ex(need), Need),
|
|
76
|
+
rdf_number(Profile, ex(baseScore), Base),
|
|
77
|
+
rdf_link(Profile, ex(mitigation), MitigationResource),
|
|
78
|
+
mitigation_resource(Mitigation, MitigationResource).
|
|
79
|
+
|
|
80
|
+
risk_triggered(consent_risk, Rule, _Need) :-
|
|
81
|
+
rdf_link(ex('healthcare-policy'), odrl(permission), Rule),
|
|
82
|
+
rdf_link(Rule, odrl(action), odrl(use)),
|
|
83
|
+
\+ constraint_text(Rule, ex(explicitConsent), 'true').
|
|
84
|
+
|
|
85
|
+
risk_triggered(sharing_risk, Rule, _Need) :-
|
|
86
|
+
rdf_link(ex('healthcare-policy'), odrl(permission), Rule),
|
|
87
|
+
rdf_link(Rule, odrl(action), ex(disclose)),
|
|
88
|
+
rdf_link(Rule, odrl(target), ex('genomic-data')),
|
|
89
|
+
\+ constraint_text(Rule, ex(deidentified), 'true').
|
|
90
|
+
|
|
91
|
+
risk_triggered(retention_risk, Rule, Need) :-
|
|
92
|
+
rdf_link(ex('healthcare-policy'), odrl(permission), Rule),
|
|
93
|
+
constraint_number(Rule, ex(retentionDays), Days),
|
|
94
|
+
rdf_number(Need, ex(maximumDays), Maximum),
|
|
95
|
+
Days > Maximum.
|
|
96
|
+
|
|
97
|
+
constraint_text(Rule, LeftOperand, Value) :-
|
|
98
|
+
rdf_link(Rule, odrl(constraint), Constraint),
|
|
99
|
+
rdf_link(Constraint, odrl('leftOperand'), LeftOperand),
|
|
100
|
+
rdf_link(Constraint, odrl(operator), odrl(eq)),
|
|
101
|
+
rdf_text(Constraint, odrl('rightOperand'), Value).
|
|
102
|
+
|
|
103
|
+
constraint_number(Rule, LeftOperand, Number) :-
|
|
104
|
+
constraint_text(Rule, LeftOperand, Text),
|
|
105
|
+
atom_chars(Text, Chars),
|
|
106
|
+
number_chars(Number, Chars).
|
|
107
|
+
|
|
108
|
+
risk_level(Score, high) :- Score > 79.
|
|
109
|
+
risk_level(Score, moderate) :- Score > 49, Score < 80.
|
|
110
|
+
|
|
111
|
+
ranked_values([], _Rank, []).
|
|
112
|
+
ranked_values([_Key-Risk|Rest], Rank, [rank(Rank, Risk)|Ranked]) :-
|
|
113
|
+
NextRank is Rank + 1,
|
|
114
|
+
ranked_values(Rest, NextRank, Ranked).
|
|
115
|
+
|
|
116
|
+
risk_resource(consent_risk, ex('consent-risk')).
|
|
117
|
+
risk_resource(sharing_risk, ex('sharing-risk')).
|
|
118
|
+
risk_resource(retention_risk, ex('retention-risk')).
|
|
119
|
+
|
|
120
|
+
mitigation_resource(require_explicit_consent, ex('require-explicit-consent')).
|
|
121
|
+
mitigation_resource(require_deidentification, ex('require-deidentification')).
|
|
122
|
+
mitigation_resource(limit_retention_to_1095_days, ex('limit-retention-to-1095-days')).
|
|
123
|
+
|
|
124
|
+
rdf_link(Subject, Predicate, Object) :-
|
|
125
|
+
iri_term(Subject, SubjectIri),
|
|
126
|
+
iri_term(Predicate, PredicateIri),
|
|
127
|
+
rdf(iri(SubjectIri), iri(PredicateIri), iri(ObjectIri), default_graph),
|
|
128
|
+
iri_term(Object, ObjectIri).
|
|
129
|
+
|
|
130
|
+
rdf_text(Subject, Predicate, Text) :-
|
|
131
|
+
iri_term(Subject, SubjectIri),
|
|
132
|
+
iri_term(Predicate, PredicateIri),
|
|
133
|
+
rdf(iri(SubjectIri), iri(PredicateIri), literal(Text, datatype(_Datatype)), default_graph).
|
|
134
|
+
|
|
135
|
+
rdf_number(Subject, Predicate, Number) :-
|
|
136
|
+
rdf_text(Subject, Predicate, Text),
|
|
137
|
+
atom_chars(Text, Chars),
|
|
138
|
+
number_chars(Number, Chars).
|
|
139
|
+
|
|
140
|
+
iri_term(ex(Name), Iri) :- namespace_iri('https://example.org/', Name, Iri).
|
|
141
|
+
iri_term(odrl(Name), Iri) :- namespace_iri('http://www.w3.org/ns/odrl/2/', Name, Iri).
|
|
142
|
+
|
|
143
|
+
namespace_iri(Prefix, Name, Iri) :- atom_concat(Prefix, Name, Iri).
|
|
144
|
+
|
|
145
|
+
% RDF form of the ranked healthcare risks.
|
|
146
|
+
result_rdf(iri(RiskIri), iri('https://example.org/rank'), literal(RankText, datatype('http://www.w3.org/2001/XMLSchema#integer')), default_graph) :-
|
|
147
|
+
healthcare_ranked_item(Rank, Risk, _Score, _Level, _Clause, _Mitigation),
|
|
148
|
+
risk_resource(Risk, RiskTerm), iri_term(RiskTerm, RiskIri), number_atom(Rank, RankText).
|
|
149
|
+
result_rdf(iri(RiskIri), iri('https://example.org/score'), literal(ScoreText, datatype('http://www.w3.org/2001/XMLSchema#integer')), default_graph) :-
|
|
150
|
+
healthcare_ranked_item(_Rank, Risk, Score, _Level, _Clause, _Mitigation),
|
|
151
|
+
risk_resource(Risk, RiskTerm), iri_term(RiskTerm, RiskIri), number_atom(Score, ScoreText).
|
|
152
|
+
result_rdf(iri(RiskIri), iri('https://example.org/level'), iri(LevelIri), default_graph) :-
|
|
153
|
+
healthcare_ranked_item(_Rank, Risk, _Score, Level, _Clause, _Mitigation),
|
|
154
|
+
risk_resource(Risk, RiskTerm), iri_term(RiskTerm, RiskIri), atom_concat('https://example.org/', Level, LevelIri).
|
|
155
|
+
result_rdf(iri(RiskIri), iri('https://example.org/clause'), literal(Clause, datatype('http://www.w3.org/2001/XMLSchema#string')), default_graph) :-
|
|
156
|
+
healthcare_ranked_item(_Rank, Risk, _Score, _Level, Clause, _Mitigation),
|
|
157
|
+
risk_resource(Risk, RiskTerm), iri_term(RiskTerm, RiskIri).
|
|
158
|
+
result_rdf(iri(RiskIri), iri('https://example.org/mitigation'), iri(MitigationIri), default_graph) :-
|
|
159
|
+
healthcare_ranked_item(_Rank, Risk, _Score, _Level, _Clause, Mitigation),
|
|
160
|
+
risk_resource(Risk, RiskTerm), iri_term(RiskTerm, RiskIri),
|
|
161
|
+
mitigation_resource(Mitigation, MitigationTerm), iri_term(MitigationTerm, MitigationIri).
|
|
162
|
+
|
|
163
|
+
healthcare_ranked_item(Rank, Risk, Score, Level, Clause, Mitigation) :-
|
|
164
|
+
healthcare_risk_report(Ranked),
|
|
165
|
+
list_member(rank(Rank, dpv_risk(Risk, Score, Level, Clause, Mitigation)), Ranked).
|
|
166
|
+
list_member(X, [X|_]).
|
|
167
|
+
list_member(X, [_|Xs]) :- list_member(X, Xs).
|
|
168
|
+
number_atom(Number, Atom) :- number_chars(Number, Chars), atom_chars(Atom, Chars).
|
|
169
|
+
|
|
170
|
+
% ISO Prolog helper: print the complete test result as rdf/4 facts.
|
|
171
|
+
write_results :-
|
|
172
|
+
result_rdf(S, P, O, G),
|
|
173
|
+
write_term(rdf(S, P, O, G), [quoted(true)]),
|
|
174
|
+
write('.'),
|
|
175
|
+
nl,
|
|
176
|
+
fail.
|
|
177
|
+
write_results.
|