use tensorlogic_ir::{TLExpr, Term};
use tensorlogic_oxirs_bridge::{ValidationExecutor, ValidationExecutorConfig};
fn default_executor() -> ValidationExecutor {
ValidationExecutor::new(ValidationExecutorConfig::default())
}
#[test]
fn test_simple_predicate_executes() {
let expr = TLExpr::pred("knows", vec![Term::var("x"), Term::var("y")]);
let executor = default_executor();
let result = executor
.execute_rule(&expr)
.expect("execute simple predicate");
assert!(
!result.output_tensors.is_empty(),
"expected at least one output tensor"
);
}
#[test]
fn test_finite_result_conforms() {
let expr = TLExpr::pred("p", vec![Term::var("x")]);
let executor = default_executor();
let result = executor.execute_rule(&expr).unwrap();
let report = executor.generate_validation_report(&result);
assert!(
report.conforms,
"finite placeholder outputs should produce a conforming report"
);
}
#[test]
fn test_export_as_rdf_prefix() {
let expr = TLExpr::pred("q", vec![Term::var("a")]);
let executor = default_executor();
let result = executor.execute_rule(&expr).unwrap();
let rdf = executor.export_as_rdf(&result);
assert!(
rdf.contains("@prefix"),
"RDF output must contain @prefix declarations"
);
assert!(rdf.contains("tl:"), "RDF output must use the tl: prefix");
}
#[test]
fn test_execution_stats_recorded() {
let expr = TLExpr::pred("r", vec![Term::var("x"), Term::constant("1.0")]);
let executor = default_executor();
let result = executor.execute_rule(&expr).unwrap();
assert!(
result.stats.output_tensor_count > 0,
"output_tensor_count must be ≥ 1"
);
}
#[test]
fn test_max_tensor_size_respected() {
let config = ValidationExecutorConfig {
max_tensor_size: 0,
..Default::default()
};
let expr = TLExpr::pred("s", vec![Term::var("x")]);
let executor = ValidationExecutor::new(config);
let _ = executor.execute_rule(&expr);
}
#[test]
fn test_report_has_no_violations_for_finite_output() {
let expr = TLExpr::pred("finite_check", vec![Term::var("x")]);
let executor = default_executor();
let result = executor.execute_rule(&expr).unwrap();
let report = executor.generate_validation_report(&result);
assert!(
report.results.is_empty() || report.conforms,
"no violations expected for finite output"
);
}
#[test]
fn test_export_rdf_contains_conforms_field() {
let expr = TLExpr::pred("v", vec![Term::var("x"), Term::var("y")]);
let executor = default_executor();
let result = executor.execute_rule(&expr).unwrap();
let rdf = executor.export_as_rdf(&result);
let has_conforms = rdf.contains("tl:conforms true") || rdf.contains("tl:conforms false");
assert!(
has_conforms,
"RDF must contain a tl:conforms field, got:\n{rdf}"
);
}
#[test]
fn test_export_rdf_contains_execution_result_type() {
let expr = TLExpr::pred("u", vec![Term::var("a")]);
let executor = default_executor();
let result = executor.execute_rule(&expr).unwrap();
let rdf = executor.export_as_rdf(&result);
assert!(
rdf.contains("tl:ExecutionResult"),
"RDF must declare a tl:ExecutionResult node"
);
}
#[test]
fn test_custom_base_iri_reflected_in_rdf() {
let config = ValidationExecutorConfig {
base_iri: "https://example.org/test/".to_string(),
..Default::default()
};
let expr = TLExpr::pred("w", vec![Term::var("x")]);
let executor = ValidationExecutor::new(config);
let result = executor.execute_rule(&expr).unwrap();
let rdf = executor.export_as_rdf(&result);
assert!(
rdf.contains("https://example.org/test/"),
"custom base IRI must appear in RDF output"
);
}
#[test]
fn test_unary_predicate_executes() {
let expr = TLExpr::pred("person", vec![Term::var("x")]);
let executor = default_executor();
let result = executor.execute_rule(&expr).expect("unary predicate");
assert!(!result.output_tensors.is_empty());
}
#[test]
fn test_conjunctive_expression_executes() {
let p = TLExpr::pred("p", vec![Term::var("x")]);
let q = TLExpr::pred("q", vec![Term::var("x")]);
let expr = TLExpr::and(p, q);
let executor = default_executor();
let result = executor
.execute_rule(&expr)
.expect("conjunctive expression");
assert!(
result.graph_node_count > 0,
"AND expression must produce at least one graph node"
);
assert!(!result.output_tensors.is_empty());
}
#[test]
fn test_disjunctive_expression_executes() {
let p = TLExpr::pred("alpha", vec![Term::var("x")]);
let q = TLExpr::pred("beta", vec![Term::var("x")]);
let expr = TLExpr::or(p, q);
let executor = default_executor();
let result = executor
.execute_rule(&expr)
.expect("disjunctive expression");
assert!(!result.output_tensors.is_empty());
}