% Generated by rdf-prolog-roundtrip.

% RDF terms use rdf(Subject, Predicate, Object, Graph).

rdf(iri('https://example.org/supply-chain/service/checkout-prod'), iri('https://example.org/vocab/rootComponent'), iri('https://example.org/supply-chain/component/shop-app'), iri('https://example.org/supply-chain/graph/sbom')).
rdf(iri('https://example.org/supply-chain/component/shop-app'), iri('https://example.org/vocab/dependsOn'), iri('https://example.org/supply-chain/component/payments-sdk'), iri('https://example.org/supply-chain/graph/sbom')).
rdf(iri('https://example.org/supply-chain/component/payments-sdk'), iri('https://example.org/vocab/dependsOn'), iri('https://example.org/supply-chain/component/crypto-wrapper'), iri('https://example.org/supply-chain/graph/sbom')).
rdf(iri('https://example.org/supply-chain/component/crypto-wrapper'), iri('https://example.org/vocab/dependsOn'), iri('https://example.org/supply-chain/component/openssl-3.0.12'), iri('https://example.org/supply-chain/graph/sbom')).
rdf(iri('https://example.org/supply-chain/component/shop-app'), iri('https://example.org/vocab/dependsOn'), iri('https://example.org/supply-chain/component/log-agent'), iri('https://example.org/supply-chain/graph/sbom')).
rdf(iri('https://example.org/supply-chain/component/log-agent'), iri('https://example.org/vocab/dependsOn'), iri('https://example.org/supply-chain/component/log-core-2.1'), iri('https://example.org/supply-chain/graph/sbom')).
rdf(iri('https://example.org/supply-chain/component/openssl-3.0.12'), iri('https://example.org/vocab/affectedBy'), iri('https://example.org/supply-chain/cve/CVE-2026-7777'), iri('https://example.org/supply-chain/graph/vulnerabilities')).
rdf(iri('https://example.org/supply-chain/cve/CVE-2026-7777'), iri('https://example.org/vocab/severityScore'), literal('98', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/supply-chain/graph/vulnerabilities')).
rdf(iri('https://example.org/supply-chain/cve/CVE-2026-7777'), iri('https://example.org/vocab/fixedComponent'), iri('https://example.org/supply-chain/component/openssl-3.0.14'), iri('https://example.org/supply-chain/graph/vulnerabilities')).
rdf(iri('https://example.org/supply-chain/component/log-core-2.1'), iri('https://example.org/vocab/affectedBy'), iri('https://example.org/supply-chain/cve/CVE-2026-2222'), iri('https://example.org/supply-chain/graph/vulnerabilities')).
rdf(iri('https://example.org/supply-chain/cve/CVE-2026-2222'), iri('https://example.org/vocab/severityScore'), literal('54', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/supply-chain/graph/vulnerabilities')).
rdf(iri('https://example.org/supply-chain/cve/CVE-2026-2222'), iri('https://example.org/vocab/fixedComponent'), iri('https://example.org/supply-chain/component/log-core-2.2'), iri('https://example.org/supply-chain/graph/vulnerabilities')).
rdf(iri('https://example.org/supply-chain/service/checkout-prod'), iri('https://example.org/vocab/criticalService'), iri('https://example.org/supply-chain/value/yes'), iri('https://example.org/supply-chain/graph/policy')).
rdf(iri('https://example.org/supply-chain/service/checkout-prod'), iri('https://example.org/vocab/currentDate'), literal('20260828', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/supply-chain/graph/policy')).
rdf(iri('https://example.org/supply-chain/waiver/logging'), iri('https://example.org/vocab/waivesForService'), iri('https://example.org/supply-chain/service/checkout-prod'), iri('https://example.org/supply-chain/graph/policy')).
rdf(iri('https://example.org/supply-chain/waiver/logging'), iri('https://example.org/vocab/waivesVulnerability'), iri('https://example.org/supply-chain/cve/CVE-2026-2222'), iri('https://example.org/supply-chain/graph/policy')).
rdf(iri('https://example.org/supply-chain/waiver/logging'), iri('https://example.org/vocab/expiresOn'), literal('20261231', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/supply-chain/graph/policy')).

% Rules
% Flagship example: software supply-chain deployment risk.
% RDF carries the SBOM, vulnerability feed, and policy. ISO Prolog performs
% transitive dependency analysis, waiver handling, and the deployment decision.

:- use_module(library(lists)).

%% goal: deployment_decision(X0, X1)
%% goal: exposure_path(X0, X1, X2)
%% goal: required_action(X0, X1)
%% goal: waiver_effect(X0, X1, X2)

v(root_component, iri('https://example.org/vocab/rootComponent')).
v(depends_on, iri('https://example.org/vocab/dependsOn')).
v(affected_by, iri('https://example.org/vocab/affectedBy')).
v(severity_score, iri('https://example.org/vocab/severityScore')).
v(fixed_component, iri('https://example.org/vocab/fixedComponent')).
v(critical_service, iri('https://example.org/vocab/criticalService')).
v(current_date, iri('https://example.org/vocab/currentDate')).
v(waives_for_service, iri('https://example.org/vocab/waivesForService')).
v(waives_vulnerability, iri('https://example.org/vocab/waivesVulnerability')).
v(expires_on, iri('https://example.org/vocab/expiresOn')).

g(sbom, iri('https://example.org/supply-chain/graph/sbom')).
g(vulnerabilities, iri('https://example.org/supply-chain/graph/vulnerabilities')).
g(policy, iri('https://example.org/supply-chain/graph/policy')).

resource(checkout_prod, iri('https://example.org/supply-chain/service/checkout-prod')).
resource(shop_app, iri('https://example.org/supply-chain/component/shop-app')).
resource(payments_sdk, iri('https://example.org/supply-chain/component/payments-sdk')).
resource(crypto_wrapper, iri('https://example.org/supply-chain/component/crypto-wrapper')).
resource(openssl_3_0_12, iri('https://example.org/supply-chain/component/openssl-3.0.12')).
resource(log_agent, iri('https://example.org/supply-chain/component/log-agent')).
resource(log_core_2_1, iri('https://example.org/supply-chain/component/log-core-2.1')).
resource(openssl_3_0_14, iri('https://example.org/supply-chain/component/openssl-3.0.14')).
resource(log_core_2_2, iri('https://example.org/supply-chain/component/log-core-2.2')).
resource(cve_2026_7777, iri('https://example.org/supply-chain/cve/CVE-2026-7777')).
resource(cve_2026_2222, iri('https://example.org/supply-chain/cve/CVE-2026-2222')).

yes(iri('https://example.org/supply-chain/value/yes')).

integer_literal(literal(Text, datatype('http://www.w3.org/2001/XMLSchema#integer')), N) :- atom_chars(Text, Cs), number_chars(N, Cs).

root_component(Service, Root) :- resource(Service,S), v(root_component,P), g(sbom,G), rdf(S,P,R,G), resource(Root,R).
depends(A,B) :- resource(A,RA), resource(B,RB), v(depends_on,P), g(sbom,G), rdf(RA,P,RB,G).
vulnerability(Component,Vuln) :- resource(Component,C), resource(Vuln,V), v(affected_by,P), g(vulnerabilities,G), rdf(C,P,V,G).
severity(Vuln,Score) :- resource(Vuln,V), v(severity_score,P), g(vulnerabilities,G), rdf(V,P,L,G), integer_literal(L,Score).
fix(Vuln,Fixed) :- resource(Vuln,V), resource(Fixed,F), v(fixed_component,P), g(vulnerabilities,G), rdf(V,P,F,G).

component_path(A,B,Path) :- component_path(A,B,[A],Path).
component_path(A,B,Visited,[A,B]) :- depends(A,B), \+ member(B,Visited).
component_path(A,B,Visited,[A|Rest]) :- depends(A,C), \+ member(C,Visited), component_path(C,B,[C|Visited],Rest).

dependency_path(Service,Component,Path) :- root_component(Service,Root), component_path(Root,Component,Path).

current_date(Service,Date) :- resource(Service,S), v(current_date,P), g(policy,G), rdf(S,P,L,G), integer_literal(L,Date).
critical(Service) :- resource(Service,S), v(critical_service,P), g(policy,G), yes(Y), rdf(S,P,Y,G).
active_waiver(Service,Vuln) :-
  resource(Service,S), resource(Vuln,V), g(policy,G),
  v(waives_for_service,PS), v(waives_vulnerability,PV), v(expires_on,PE),
  rdf(W,PS,S,G), rdf(W,PV,V,G), rdf(W,PE,L,G), integer_literal(L,Expiry), current_date(Service,Today), Expiry >= Today.

exposed(Service,Vuln,Path,Score) :-
  dependency_path(Service,Component,Path), vulnerability(Component,Vuln), severity(Vuln,Score), \+ active_waiver(Service,Vuln).

blocking_exposure(Service,Vuln,Path,Score) :- exposed(Service,Vuln,Path,Score), Score >= 70.

deployment_decision(Service, block) :- critical(Service), blocking_exposure(Service,_V,_P,_S).
exposure_path(Service,Vuln,Path) :- blocking_exposure(Service,Vuln,Path,_Score).
required_action(Service, upgrade(Component,Fixed)) :-
  blocking_exposure(Service,Vuln,Path,_), last(Path,Component), fix(Vuln,Fixed).
waiver_effect(Service,Vuln,accepted_until(Expiry)) :-
  active_waiver(Service,Vuln), resource(Service,S), resource(Vuln,V), g(policy,G),
  v(waives_for_service,PS), v(waives_vulnerability,PV), v(expires_on,PE),
  rdf(W,PS,S,G), rdf(W,PV,V,G), rdf(W,PE,L,G), integer_literal(L,Expiry).

result_rdf(S, iri('https://example.org/vocab/deploymentDecision'), iri('https://example.org/supply-chain/decision/block'), iri('https://example.org/supply-chain/graph/derived')) :-
  deployment_decision(checkout_prod,block), resource(checkout_prod,S).
result_rdf(S, iri('https://example.org/vocab/exposedTo'), V, iri('https://example.org/supply-chain/graph/derived')) :-
  exposure_path(checkout_prod,Vuln,_), resource(checkout_prod,S), resource(Vuln,V).
result_rdf(C, iri('https://example.org/vocab/upgradeTo'), F, iri('https://example.org/supply-chain/graph/derived')) :-
  required_action(checkout_prod,upgrade(Component,Fixed)), resource(Component,C), resource(Fixed,F).

write_results :- result_rdf(S,P,O,G), write_term(rdf(S,P,O,G), [quoted(true)]), write('.'), nl, fail.
write_results.
:- set_prolog_flag(unknown, fail).
