gollum-ir 0.4.0

Intermediate Representation for the Gollum language
Documentation
//! IR query type.

use crate::metadata::IrMetadata;
use crate::term::IrTerm;

/// An IR-level query.
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct IrQuery {
    /// The query goal (conjunction encoded as `","` structure for multi-goal queries).
    pub goal: IrTerm,
    /// Optional reasoning metadata.
    pub metadata: Option<IrMetadata>,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_single_goal_query() {
        let q = IrQuery {
            goal: IrTerm::Structure {
                name: "parent".into(),
                args: vec![IrTerm::Atom("alice".into()), IrTerm::Var("X".into())],
            },
            metadata: None,
        };
        assert!(q.metadata.is_none());
    }

    #[test]
    fn test_multi_goal_query() {
        // ?- parent(alice, X), parent(X, Y).
        // encoded as ","(parent(alice,X), ","(parent(X,Y), ...))
        let q = IrQuery {
            goal: IrTerm::Structure {
                name: ",".into(),
                args: vec![
                    IrTerm::Structure {
                        name: "parent".into(),
                        args: vec![IrTerm::Atom("alice".into()), IrTerm::Var("X".into())],
                    },
                    IrTerm::Structure {
                        name: "parent".into(),
                        args: vec![IrTerm::Var("X".into()), IrTerm::Var("Y".into())],
                    },
                ],
            },
            metadata: None,
        };
        if let IrTerm::Structure { name, args } = &q.goal {
            assert_eq!(name, ",");
            assert_eq!(args.len(), 2);
        } else {
            panic!("expected Structure");
        }
    }
}