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}