Feat/fst order pred part3 & part4 (#457)

* support wildcard predicates in frontend

* suport wildcard predicate in podlang

* add validation test

* test full flow and apply some fixes

* fix clippy

* fix merge issues

* use desugared predicate

* Fix parsing of intro statement templates inside custom predicates

* Tidy up comments

* lang: handle wildcard predicate

* add unreachable message

---------

Co-authored-by: Rob Knight <mail@robknight.org.uk>
This commit is contained in:
Eduard S. 2026-02-02 10:59:33 +01:00 committed by GitHub
parent b66f5051b5
commit 498e946612
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 324 additions and 180 deletions

View file

@ -611,17 +611,21 @@ pub fn fill_wildcard_values(
wildcard_map: &mut [Option<Value>],
) -> Result<()> {
for (st_tmpl, st) in pred.statements.iter().zip(args) {
let st_args = st.args();
if let PredicateOrWildcard::Wildcard(wc) = &st_tmpl.pred_or_wc {
wc_check_or_set(Value::from(st.predicate().hash(params)), wc, wildcard_map)?;
}
st_tmpl
.args
.iter()
.zip(&st_args)
.try_for_each(|(st_tmpl_arg, st_arg)| {
check_st_tmpl(st_tmpl_arg, st_arg, wildcard_map)
})?;
let st_args = st.args();
for (st_tmpl_arg, st_arg) in st_tmpl.args.iter().zip(&st_args) {
if let Err(st_tmpl_check_error) = check_st_tmpl(st_tmpl_arg, st_arg, wildcard_map) {
return Err(Error::statements_dont_match(
st.clone(),
st_tmpl.clone(),
wildcard_map.to_vec(),
st_tmpl_check_error,
));
}
}
}
Ok(())
}
@ -741,16 +745,7 @@ pub(crate) fn check_custom_pred(
for (st_tmpl, st) in pred.statements.iter().zip(args) {
// For `or` predicates, only one statement needs to match the template.
// The rest of the statements can be `None`.
let expected_pred_is_none = match &st_tmpl.pred_or_wc {
PredicateOrWildcard::Predicate(st_tmpl_pred) => {
*st_tmpl_pred == Predicate::Native(NativePredicate::None)
}
PredicateOrWildcard::Wildcard(wc) => {
wc_values[wc.index]
== Value::from(Predicate::Native(NativePredicate::None).hash(params))
}
};
if !pred.conjunction && matches!(st, Statement::None) && !expected_pred_is_none {
if !pred.conjunction && matches!(st, Statement::None) {
continue;
}
check_custom_pred_argument(params, custom_pred_ref, st_tmpl, st, &wc_values)?;