-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtraits.rs
143 lines (113 loc) · 5.09 KB
/
traits.rs
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
137
138
139
140
141
142
143
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub enum RepresentationType {
Text,
}
pub type Id = u64;
/// Id for a learnable, a learnable represents a set of learnable edges.
/// Think of a normal flashcard as a single learnable with two edges (back to front, front to back)
#[derive(
Debug, Eq, Hash, PartialEq, Deserialize, Serialize, Copy, Clone, Default, Ord, PartialOrd,
)]
#[serde(transparent)]
pub struct LearnableId(pub Id);
/// Id for a representation, this is a unique id for the front or back of a traditional card.
#[derive(
Debug, Eq, Hash, PartialEq, Deserialize, Serialize, Copy, Clone, Default, Ord, PartialOrd,
)]
#[serde(transparent)]
pub struct RepresentationId(pub Id);
/// Id for a particular transformation, like translating language A to B.
#[derive(
Debug, Eq, Hash, PartialEq, Deserialize, Serialize, Copy, Clone, Default, Ord, PartialOrd,
)]
#[serde(transparent)]
pub struct TransformId(pub Id);
/// Type for the score, in interval [0.0 to 1.0] (inclusive).
pub type Score = f64;
/// Error in case anything goes wrong.
pub type MemorizerError = Box<dyn std::error::Error + Sync + Send>;
/// A particular representation of data, think about the side of a card.
pub trait Representation: std::fmt::Debug + Send + Sync {
/// Get the type of this presentation.
fn get_type(&self) -> RepresentationType;
/// Get the textual representation.
fn text(&self) -> &str;
/// Unique id for this representation.
fn id(&self) -> RepresentationId;
/// Check if this representation is identical to another representation.
/// This should not compare ID, instead it should compare the contents of the representation.
fn is_equal(&self, other: &dyn Representation) -> bool;
/// Get the approximate equality of this representation and the other representation. Must be
/// between 0.0 (completely wrong) and 1.0 (exactly equal).
/// This should not compare ID, instead it should compare the contents of the representation.
fn get_similarity(&self, other: &dyn Representation) -> Score {
if self.is_equal(other) {
1.0
} else {
0.0
}
}
}
/// A transformation, like Hex->Binary or 'Translate from A into B', think about the direction
/// the card is being learnt in.
pub trait Transform: std::fmt::Debug + Send + Sync {
/// A string describing the particular transformation to be performed.
fn description(&self) -> &str;
/// Unique id for this Transformation.
fn id(&self) -> TransformId;
}
/// A struct representing a particular question.
#[derive(Debug, PartialEq, Copy, Clone, Deserialize, Serialize, Default)]
pub struct Question {
/// From which learnable this question originates.
pub learnable: LearnableId,
/// The 'from' value, this is shown to the user.
pub from: RepresentationId,
/// The transformation the user is to perform.
pub transform: TransformId,
/// The true answer for this from and transformation.
pub to: RepresentationId,
}
/// Something that relates transformations and representations to each other. This owns the
/// representations and transforms. Think of this as a single card with front and back (or any
/// number of sides).
pub trait Learnable: std::fmt::Debug + Send + Sync {
/// Get the possible edges for this learnable.
fn edges(&self) -> Vec<Question>;
/// Retrieval function for a particular representation. Panics if the id is not known to this
/// learnable.
fn representation(&self, id: RepresentationId) -> Arc<dyn Representation>;
/// Retrieval function for a particular transformation. Panics if the id is not known to this
/// learnable.
fn transform(&self, transform: TransformId) -> Arc<dyn Transform>;
/// Unique id for this learnable.
fn id(&self) -> LearnableId;
}
/// Record of a question, the score obtained answering it and a timestamp.
#[derive(Debug, PartialEq, Copy, Clone, Deserialize, Serialize)]
pub struct Record {
/// The question as posed.
pub question: Question,
/// The final score stored for this question.
pub score: Score,
/// Timestamp associated to this question.
pub time: std::time::SystemTime,
}
/// Something to track past performance.
pub trait Recorder: std::fmt::Debug + Send + Sync {
/// Store an answer.
fn store_record(&mut self, record: &Record) -> Result<(), MemorizerError>;
/// Retrieve records for a particular question.
fn get_records_by_question(&self, question: &Question) -> Result<Vec<Record>, MemorizerError>;
}
/// The entity that decided what questions to ask. Only works on Ids.
pub trait Selector: std::fmt::Debug + Send + Sync {
/// Constructor, takes recorder of past event and a set of learnables.
fn set_questions(&mut self, questions: &[Question], recorder: &dyn Recorder);
/// Retrieve a question to ask, if empty session is done, no questions to ask right now.
fn get_question(&mut self) -> Option<Question>;
/// Store answer to a question, not guaranteed to be in sync with get_question.
fn store_record(&mut self, record: &Record);
}