% Generated by rdf-prolog-roundtrip.

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

rdf(iri('https://example.org/ev-depot/site/depot-a'), iri('https://example.org/vocab/availablePowerKw'), literal('60', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/ev-depot/graph/site')).
rdf(iri('https://example.org/ev-depot/site/depot-a'), iri('https://example.org/vocab/requiredChargeKw'), literal('22', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/ev-depot/graph/site')).
rdf(iri('https://example.org/ev-depot/site/depot-a'), iri('https://example.org/vocab/requiredConnector'), iri('https://example.org/ev-depot/connector/ccs2'), iri('https://example.org/ev-depot/graph/site')).
rdf(iri('https://example.org/ev-depot/site/depot-a'), iri('https://example.org/vocab/supply'), iri('https://example.org/ev-depot/supply/three-phase'), iri('https://example.org/ev-depot/graph/site')).
rdf(iri('https://example.org/ev-depot/charger/fleet22'), iri('https://example.org/vocab/chargeKw'), literal('22', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/fleet22'), iri('https://example.org/vocab/sitePowerRequirementKw'), literal('45', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/fleet22'), iri('https://example.org/vocab/connector'), iri('https://example.org/ev-depot/connector/ccs2'), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/fleet22'), iri('https://example.org/vocab/supply'), iri('https://example.org/ev-depot/supply/three-phase'), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/rapid50'), iri('https://example.org/vocab/chargeKw'), literal('50', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/rapid50'), iri('https://example.org/vocab/sitePowerRequirementKw'), literal('80', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/rapid50'), iri('https://example.org/vocab/connector'), iri('https://example.org/ev-depot/connector/ccs2'), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/rapid50'), iri('https://example.org/vocab/supply'), iri('https://example.org/ev-depot/supply/three-phase'), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/budget11'), iri('https://example.org/vocab/chargeKw'), literal('11', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/budget11'), iri('https://example.org/vocab/sitePowerRequirementKw'), literal('25', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/budget11'), iri('https://example.org/vocab/connector'), iri('https://example.org/ev-depot/connector/ccs2'), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/budget11'), iri('https://example.org/vocab/supply'), iri('https://example.org/ev-depot/supply/three-phase'), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/legacy22'), iri('https://example.org/vocab/chargeKw'), literal('22', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/legacy22'), iri('https://example.org/vocab/sitePowerRequirementKw'), literal('45', datatype('http://www.w3.org/2001/XMLSchema#integer')), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/legacy22'), iri('https://example.org/vocab/connector'), iri('https://example.org/ev-depot/connector/type2'), iri('https://example.org/ev-depot/graph/catalog')).
rdf(iri('https://example.org/ev-depot/charger/legacy22'), iri('https://example.org/vocab/supply'), iri('https://example.org/ev-depot/supply/three-phase'), iri('https://example.org/ev-depot/graph/catalog')).

% Rules
% Flagship example: explainable configuration rather than opaque filtering.
% The same relational model answers: what fits, why does an option fail, and
% what would have to change to make a rejected option viable?

%% goal: compatible(X0, X1)
%% goal: recommendation(X0, X1)
%% goal: blocker(X0, X1, X2)
%% goal: required_change(X0, X1, X2)

v(available_power,iri('https://example.org/vocab/availablePowerKw')).
v(required_charge,iri('https://example.org/vocab/requiredChargeKw')).
v(required_connector,iri('https://example.org/vocab/requiredConnector')).
v(supply,iri('https://example.org/vocab/supply')).
v(charge_kw,iri('https://example.org/vocab/chargeKw')).
v(site_power_requirement,iri('https://example.org/vocab/sitePowerRequirementKw')).
v(connector,iri('https://example.org/vocab/connector')).

g(site,iri('https://example.org/ev-depot/graph/site')). g(catalog,iri('https://example.org/ev-depot/graph/catalog')).
resource(depot_a,iri('https://example.org/ev-depot/site/depot-a')).
resource(fleet22,iri('https://example.org/ev-depot/charger/fleet22')).
resource(rapid50,iri('https://example.org/ev-depot/charger/rapid50')).
resource(budget11,iri('https://example.org/ev-depot/charger/budget11')).
resource(legacy22,iri('https://example.org/ev-depot/charger/legacy22')).
product(fleet22). product(rapid50). product(budget11). product(legacy22).
integer_literal(literal(Text,datatype('http://www.w3.org/2001/XMLSchema#integer')),N):-atom_chars(Text,Cs),number_chars(N,Cs).

site_number(Key,N):-resource(depot_a,S),v(Key,P),g(site,G),rdf(S,P,L,G),integer_literal(L,N).
site_term(Key,V):-resource(depot_a,S),v(Key,P),g(site,G),rdf(S,P,V,G).
product_number(Product,Key,N):-resource(Product,R),v(Key,P),g(catalog,G),rdf(R,P,L,G),integer_literal(L,N).
product_term(Product,Key,V):-resource(Product,R),v(Key,P),g(catalog,G),rdf(R,P,V,G).

blocker(depot_a,Product,insufficient_site_power(Available,Needed)):-product(Product),site_number(available_power,Available),product_number(Product,site_power_requirement,Needed),Available < Needed.
blocker(depot_a,Product,insufficient_charge_rate(Offered,Required)):-product(Product),product_number(Product,charge_kw,Offered),site_number(required_charge,Required),Offered < Required.
blocker(depot_a,Product,connector_mismatch(Offered,Required)):-product(Product),product_term(Product,connector,OfferedIri),site_term(required_connector,RequiredIri),OfferedIri \= RequiredIri,connector_name(OfferedIri,Offered),connector_name(RequiredIri,Required).
blocker(depot_a,Product,supply_mismatch):-product(Product),product_term(Product,supply,S),site_term(supply,SiteS),S \= SiteS.

connector_name(iri('https://example.org/ev-depot/connector/ccs2'),ccs2).
connector_name(iri('https://example.org/ev-depot/connector/type2'),type2).

compatible(depot_a,Product):-product(Product),\+ blocker(depot_a,Product,_).
recommendation(depot_a,fleet22):-compatible(depot_a,fleet22).

required_change(depot_a,Product,increase_site_power_to(Needed)):-blocker(depot_a,Product,insufficient_site_power(_,Needed)).
required_change(depot_a,Product,choose_charger_at_least_kw(Required)):-blocker(depot_a,Product,insufficient_charge_rate(_,Required)).
required_change(depot_a,Product,use_connector(Required)):-blocker(depot_a,Product,connector_mismatch(_,Required)).

result_rdf(S,iri('https://example.org/vocab/recommendedCharger'),C,iri('https://example.org/ev-depot/graph/derived')):-recommendation(depot_a,Product),resource(depot_a,S),resource(Product,C).
result_rdf(C,iri('https://example.org/vocab/configurationStatus'),iri('https://example.org/ev-depot/state/compatible'),iri('https://example.org/ev-depot/graph/derived')):-compatible(depot_a,Product),resource(Product,C).

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).
