mycroft/ast/
mod.rs

1//! The `ast` module defines the parsed form of the Mycroft language.
2mod printers;
3
4/// A `Program` contains all parts of a Mycroft program, and is the basic
5/// unit to be handed to the code generator.
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
7pub struct Program {
8    /// The list of predicate definitions, defining the different kinds of
9    /// facts that may be stored in the database.
10    pub predicates: Vec<Predicate>,
11    /// The list of available queries: questions that the database will be able to answer
12    /// efficiently.
13    pub queries: Vec<Query>,
14    /// The list of rules to be active on the database when running
15    pub rules: Vec<Rule>,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
19/// A named field is a predicate field for those using the named style.
20pub struct NamedField<T> {
21    /// Field name
22    pub name: String,
23    /// Associated value
24    pub val: T,
25}
26
27/// `Fields` contains either an ordered list of type names or a list of
28/// `NamedField`s. These are encoded separately at this stage to ensure that ordered predicates are
29/// only matched against ordered match clauses, and named predicates with named match clauses
30/// during translation to IR.
31#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
32pub enum Fields<T> {
33    /// List of field associated values, matched by position
34    Ordered(Vec<T>),
35    /// List of named fields, matched by name
36    Named(Vec<NamedField<T>>),
37}
38
39/// `FieldType` describes how a particular field in a predicate will be stored and viewed
40#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
41pub struct FieldType {
42    /// Type of values stored
43    pub type_: String,
44    /// If `None`, values will be viewed as-is. If `Some(func_name)`, matches against this
45    /// predicate may return any subset of matching values, aggregated together via the provided
46    /// aggegation function.
47    /// Any provided function must be commutative and associative for proper functioning, and have
48    /// type (T, T) -> T
49    pub aggregator: Option<String>,
50}
51
52/// A `Predicate` can essentially be seen as a fact-type declaration. It describes the types of
53/// each field of a particular relation, and prescribes how it is to be matched (by index or by
54/// name).
55#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
56pub struct Predicate {
57    /// Predicate name
58    pub name: String,
59    /// Predicate fields. The associated value is the field type.
60    pub fields: Fields<FieldType>,
61}
62
63/// A `Query` is a predefined question that can be asked of the database. Appropriate indexes and
64/// code to use them will be generated. It is formed as a unification query over several clauses.
65#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
66pub struct Query {
67    /// Query name
68    pub name: String,
69    /// Clauses
70    pub clauses: Vec<Clause>,
71}
72
73/// A `Clause` is one component of a unification query, specifying a predicate combined with
74/// restrictions over each variable
75#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
76pub struct Clause {
77    /// The predicate to match against
78    pub pred_name: String,
79    /// The restrictions over fields
80    pub matches: Fields<Match>,
81    /// Whether or not this is a circumscribed clause
82    pub circumscribed: bool,
83}
84
85/// A `Match` is the specifier for how to unify a particular field
86#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
87pub enum Match {
88    /// Unify the field to the named variable
89    Var(String),
90    /// Unify the field to the named constant (must be a legal rust expression)
91    Const(String),
92    /// No restriction
93    Unbound,
94}
95
96/// A `Rule` is a triggered transition that will instantiate the head and insert it when the body
97/// is matched.
98#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
99pub struct Rule {
100    /// Rule name, to be used in debugging and provenance
101    pub name: String,
102    /// Clause which must contain as its matches only variables appearing in the body and constants
103    /// On successful match of the body, the results will be substituted into the head and realized.
104    pub head: Clause,
105    /// Set of clauses which must unify to provide input to the head
106    pub body: Vec<Clause>,
107    /// Function to be called on bound body clause variables to produce head solutions
108    pub func: Option<String>,
109    /// Stage to call this rule in
110    pub stage: Option<usize>,
111}