use std::env;
use reasoninglayer::{
constrained, guard, psi, var, AddRuleRequest, AuthConfig, BackwardChainRequest, ClientConfig,
CreateSortRequest, CreateTermRequest, GuardOp, ReasoningLayerClient, Value,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let base_url =
env::var("REASONINGLAYER_URL").unwrap_or_else(|_| "https://platform.ovh.reasoninglayer.ai".into());
let tenant_id = env::var("REASONINGLAYER_TENANT_ID")
.expect("REASONINGLAYER_TENANT_ID environment variable is required");
let token = env::var("REASONINGLAYER_API_TOKEN")
.expect("REASONINGLAYER_API_TOKEN environment variable is required");
let client = ReasoningLayerClient::new(ClientConfig::new(
base_url,
&tenant_id,
AuthConfig::Bearer(token),
))?;
let person = client
.sorts()
.create_sort(CreateSortRequest::with_name("person"), None)
.await?;
println!("created sort person: {}", person.id);
let mut employee_req = CreateSortRequest::with_name("employee");
employee_req.parents = vec![person.id];
let employee = client.sorts().create_sort(employee_req, None).await?;
println!("created sort employee: {}", employee.id);
let mut features = std::collections::BTreeMap::new();
features.insert("name".into(), Value::string("Alice"));
features.insert("salary".into(), Value::real(95_000.0));
let term = client
.terms()
.create_term(
CreateTermRequest {
sort_id: employee.id.to_string(),
owner_id: tenant_id.clone(),
features,
},
None,
)
.await?;
println!("created term {}", term.term.id);
client
.inference()
.add_rule(
AddRuleRequest {
term: psi("well_paid", [("person", var("?X"))]),
antecedents: vec![psi(
"employee",
[
("name", var("?X")),
("salary", constrained("?S", guard(GuardOp::Gt, 80_000_i64))),
],
)],
certainty: None,
},
None,
)
.await?;
println!("added rule");
let req = BackwardChainRequest {
goal: Some(psi("well_paid", [("person", var("?Who"))])),
max_solutions: Some(10),
..Default::default()
};
let result = client.inference().backward_chain(req, None).await?;
println!(
"{} solutions in {}ms",
result.solutions.len(),
result.query_time_ms
);
for (i, solution) in result.solutions.iter().enumerate() {
for binding in &solution.substitution.bindings {
let name = binding.variable_name.as_deref().unwrap_or("?");
println!(" [{i}] {name} = {}", binding.bound_to_display);
}
}
Ok(())
}