use egglog::EGraph;
fn assert_errs(program: &str) {
let mut egraph = EGraph::default();
let result = egraph.parse_and_run_program(None, program);
assert!(
result.is_err(),
"expected a recoverable error, got Ok for:\n{program}"
);
}
fn assert_no_panic(egraph: &mut EGraph, program: &str) {
let _ = egraph.parse_and_run_program(None, program);
}
#[test]
fn malformed_sort_declarations_error() {
assert_errs("(sort S (Vec))");
assert_errs("(sort S (Vec i64 i64))");
assert_errs("(sort S (Set))");
assert_errs("(sort S (Set i64 i64))");
assert_errs("(sort S (Pair i64))");
assert_errs("(sort S (Map i64))");
assert_errs("(sort S (MultiSet))");
assert_errs("(sort S (UnstableFn))");
assert_errs("(sort S (UnstableFn x String))");
assert_errs("(sort S (UnstableFn (i64) (String)))");
}
#[test]
fn partial_primitives_error_instead_of_panicking() {
assert_errs("(sort IV (Vec i64))(let v (vec-of 1 2 3))(extract (vec-set v 10 99))");
assert_errs("(sort IV (Vec i64))(let v (vec-of 1 2 3))(extract (vec-set v -1 99))");
assert_errs("(sort IV (Vec i64))(let v (vec-of 1 2 3))(extract (vec-remove v 10))");
assert_errs("(extract (<< (bigint 5) -3))");
assert_errs("(extract (>> (bigint 5) -3))");
assert_errs("(extract (bigrat (bigint 1) (bigint 0)))");
assert_errs("(extract (log2 0))");
assert_errs("(extract (log2 -5))");
assert_errs("(sort MS (MultiSet i64))(extract (multiset-pick (multiset-of)))");
}
#[test]
fn command_execution_errors() {
assert_errs("(sort Math)(constructor Num (i64) Math)(let x (Num 5))(extract x -1)");
assert_errs(
r#"(datatype Math (Num i64))
(rule ((= x (Num 1))) ((Num 2)) :name "r")
(rule ((= x (Num 1))) ((Num 3)) :name "r")"#,
);
assert_errs(r#"(input nonexistent_function "/tmp/nofile_xyz.txt")"#);
assert_errs(
r#"(sort Math)(constructor Num (i64) Math)
(function edge (Math) i64 :merge old)
(input edge "/tmp/nofile_xyz.txt")"#,
);
assert_errs(
r#"(function edge (i64) i64 :merge old)(input edge "/tmp/does_not_exist_xyz.txt")"#,
);
assert_errs(
r#"(sort Math)(constructor Num (i64) Math)
(let y (Num 7))(delete (Num 7))
(output "/tmp/egglog_out_xyz.txt" y)"#,
);
}
#[test]
fn unstable_fn_resolution_errors() {
assert_errs(
r#"(sort BinFn (UnstableFn (i64 i64) i64))
(function holder () BinFn :merge old)
(rule ((= s "+")) ((set (holder) (unstable-fn "this_function_does_not_exist"))))
(run 1)"#,
);
assert_errs(
r#"(sort BinFn (UnstableFn (i64 i64) i64))
(function holder () BinFn :merge old)
(rule ((= s "+")) ((set (holder) (unstable-fn s))))
(run 1)"#,
);
}
#[test]
fn desugar_and_parse_errors() {
assert_errs("(fail (datatype*))");
assert_errs(r#"(fail (include "nonexistent_xyz.egg"))"#);
assert_errs("(rewrite 1 2 :subsume)");
}
#[test]
fn multiset_index_with_primitive_function_does_not_panic() {
let mut egraph = EGraph::default();
assert_no_panic(
&mut egraph,
r#"(sort MS (MultiSet i64))
(let m (multiset-of 1 2))
(unstable-multiset-clear-index m (unstable-fn "multiset-count"))"#,
);
}
#[test]
fn prove_exists_without_proofs_errors() {
let mut egraph = EGraph::default();
let result = egraph.parse_and_run_program(None, "(datatype M (Foo))(Foo)(prove-exists (Foo))");
assert!(result.is_err());
}
#[test]
fn term_encoding_with_escaped_string_does_not_panic() {
let mut egraph = EGraph::new_with_term_encoding();
assert_no_panic(
&mut egraph,
r#"(sort Math)(constructor MkStr (String) Math)
(MkStr "x")
(check (= (MkStr "\"") (MkStr "\"")))"#,
);
}