fetish_lib/
application_table.rs

1use crate::type_id::*;
2use crate::term_application::*;
3use crate::term_application_result::*;
4use crate::term_pointer::*;
5use crate::context::*;
6use crate::term_reference::*;
7use std::collections::HashMap;
8use multimap::MultiMap;
9
10///For a given function type `A -> B`, stores
11///current information about [`TermApplicationResult`]s
12///for that function type with several easily-queryable views.
13pub struct ApplicationTable<'a> {
14    func_type_id : TypeId,
15    table : MultiMap::<TermApplication, TermReference>,
16    result_to_application_map :  MultiMap::<TermReference, TermApplicationResult>,
17    arg_to_application_map : MultiMap::<TermReference, TermApplicationResult>,
18    func_to_application_map : MultiMap::<TermPointer, TermApplicationResult>,
19    ctxt : &'a Context
20}
21
22impl <'a> ApplicationTable<'a> {
23    ///Constructs an initially-empty [`ApplicationTable`] for the given
24    ///function [`TypeId`] in the given [`Context`].
25    pub fn new(func_type_id : TypeId, ctxt : &'a Context) -> ApplicationTable<'a> {
26        if (!ctxt.is_vector_type(func_type_id)) {
27            ApplicationTable {
28                func_type_id,
29                table : MultiMap::new(),
30                result_to_application_map : MultiMap::new(),
31                arg_to_application_map : MultiMap::new(),
32                func_to_application_map : MultiMap::new(),
33                ctxt
34            }
35        } else {
36            panic!();
37        }
38    }
39
40    ///Yields all [`TermReference`] results recorded for the given [`TermApplication`].
41    pub fn get_results_from_application(&self, term_app : &TermApplication) -> Vec<TermReference> {
42        match (self.table.get_vec(term_app)) {
43            Option::Some(vec) => vec.clone(),
44            Option::None => Vec::new()
45        }
46    }
47
48    ///Yields all recorded [`TermApplicationResult`]s which involve the passed `arg`.
49    pub fn get_app_results_with_arg(&self, arg : &TermReference) -> Vec<TermApplicationResult> {
50        match (self.arg_to_application_map.get_vec(arg)) {
51            Option::Some(vec) => vec.clone(),
52            Option::None => Vec::new()
53        }
54    }
55
56    ///Yields all recorded [`TermApplicationResult`]s which involve the passed `func`.
57    pub fn get_app_results_with_func(&self, func : TermPointer) -> Vec<TermApplicationResult> {
58        match (self.func_to_application_map.get_vec(&func)) {
59            Option::Some(vec) => vec.clone(),
60            Option::None => Vec::new()
61        }
62    }
63
64    ///Yields all recorded [`TermApplicationResult`]s which have had the passed `result`.
65    pub fn get_app_results_with_result(&self, result : &TermReference) -> Vec<TermApplicationResult> {
66        match (self.result_to_application_map.get_vec(result)) {
67            Option::Some(vec) => vec.clone(),
68            Option::None => Vec::new()
69        }
70    }
71
72    ///Records that the evaluation of `term_app` resulted in `result_ref`.
73    pub fn link(&mut self, term_app : TermApplication, result_ref : TermReference) {
74        let result = TermApplicationResult {
75            term_app : term_app.clone(),
76            result_ref : result_ref.clone()
77        };
78
79        self.result_to_application_map.insert(result_ref.clone(), result.clone());
80        self.arg_to_application_map.insert(term_app.arg_ref.clone(), result.clone());
81        self.func_to_application_map.insert(term_app.func_ptr.clone(), result.clone());
82        self.table.insert(term_app, result_ref);
83    }
84}