1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use std::{
collections::HashMap,
fmt::{Debug, Formatter},
};
use itertools::Itertools;
use once_cell::sync::Lazy;
use super::atoms::Function;
use crate::{
algebra::{
atoms::Variable,
dynamic_function::{
make_dynamic, DescribableFunction, DynamicFunction, DynamicFunctionShape, TypeShape,
},
Matcher,
},
trace::{Query, Source},
};
pub type FunctionDefinition = (DynamicFunctionShape, Box<dyn DynamicFunction>);
pub struct Signature {
pub functions_by_name: HashMap<&'static str, FunctionDefinition>,
pub functions_by_typ: HashMap<TypeShape, Vec<FunctionDefinition>>,
pub functions: Vec<FunctionDefinition>,
pub types_by_name: HashMap<&'static str, TypeShape>,
}
impl Debug for Signature {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
writeln!(f, "functions; {:?}", self.functions)
}
}
impl Signature {
pub fn new(definitions: Vec<FunctionDefinition>) -> Signature {
let functions_by_name: HashMap<&'static str, FunctionDefinition> = definitions
.clone()
.into_iter()
.map(|(shape, dynamic_fn)| (shape.name, (shape, dynamic_fn)))
.collect();
let functions_by_typ: HashMap<TypeShape, Vec<FunctionDefinition>> = definitions
.clone()
.into_iter()
.into_group_map_by(|(shape, _dynamic_fn)| shape.return_type);
let types_by_name: HashMap<&'static str, TypeShape> = definitions
.clone()
.into_iter()
.map(|(shape, _dynamic_fn)| {
let used_types: Vec<TypeShape> = shape .argument_types
.iter()
.copied()
.chain(vec![shape.return_type])
.collect::<Vec<TypeShape>>();
used_types
})
.unique()
.flatten()
.map(|typ| (typ.name, typ))
.collect();
Signature {
functions_by_name,
functions_by_typ,
functions: definitions,
types_by_name,
}
}
pub fn new_function<F: 'static, Types>(f: &'static F) -> Function
where
F: DescribableFunction<Types>,
{
let (shape, dynamic_fn) = make_dynamic(f);
Function::new(shape, dynamic_fn.clone())
}
pub fn new_var_with_type<T: 'static, M: Matcher>(
source: Option<Source>,
matcher: Option<M>,
counter: u16,
) -> Variable<M> {
let type_shape = TypeShape::of::<T>();
Self::new_var(type_shape, source, matcher, counter)
}
pub fn new_var<M: Matcher>(
type_shape: TypeShape,
source: Option<Source>,
matcher: Option<M>,
counter: u16,
) -> Variable<M> {
let query = Query {
source,
matcher,
counter,
};
Variable::new(type_shape, query)
}
}
pub type StaticSignature = Lazy<Signature>;
pub const fn create_static_signature(init: fn() -> Signature) -> StaticSignature {
Lazy::new(init)
}
#[macro_export]
macro_rules! define_signature {
($name_signature:ident, $($f:path)+) => {
use $crate::algebra::signature::create_static_signature;
use $crate::algebra::signature::StaticSignature;
use $crate::algebra::signature::Signature;
pub static $name_signature: StaticSignature = create_static_signature(|| {
let definitions = vec![
$($crate::algebra::dynamic_function::make_dynamic(&$f)),*
];
Signature::new(definitions)
});
};
}