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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
    Appellation: exec <module>
    Contrib: FL03 <jo3mccain@icloud.com>
    Description: ... summary ...
*/
use crate::instructions::Instruction;
use crate::{Alphabet, Program, Scope, State, Symbolic};
use async_trait::async_trait;
use contained_core::{states::Stateful, Error};
use futures::{Future, StreamExt};
use predicates::Predicate;
use std::sync::{Arc, Mutex};

/// [AsyncExecute] describes a self-contained executor that can be executed asynchronously.
#[async_trait]
pub trait AsyncExecute<S: Symbolic + Send + Sync>:
    Alphabet<S> + StreamExt<Item = Instruction<S>> + Stateful<State> + Unpin
{
    type Driver: Future + Scope<S> + Send + Sync;
    type Error: Send + Sync;

    async fn execute(&mut self) -> Result<&Arc<Mutex<Self::Driver>>, Self::Error> {
        // Get the default symbol
        let default_symbol = self.clone().default_symbol();
        // Get the next instruction
        while let Some(instruction) = self.next().await {
            // Get the tail of the instruction
            let tail = instruction.clone().tail();
            // Update the current state
            self.update_state(tail.state());
            // Update the tape
            self.scope_mut().lock().unwrap().set_symbol(tail.symbol());
            // Update the index; adjusts the index according to the direction
            self.scope_mut()
                .lock()
                .unwrap()
                .shift(tail.action(), default_symbol.clone());
        }
        // Return the actor
        Ok(self.scope())
    }
    /// Returns a reference to the scope
    fn scope(&self) -> &Arc<Mutex<Self::Driver>>;
    /// Returns a mutable reference to the scope
    fn scope_mut(&mut self) -> &mut Arc<Mutex<Self::Driver>>;
}

/// [Execute] describes a self-contained executor that can be executed synchronously.
pub trait Execute<S: Symbolic>:
    Alphabet<S> + Iterator<Item = Instruction<S>> + Stateful<State>
{
    type Driver: Scope<S>;

    /// [Execute::execute]
    fn execute(&mut self) -> Result<&Self::Driver, Error> {
        // Get the default symbol
        let default_symbol = self.program().default_symbol();
        // Get the next instruction
        while let Some(instruction) = self.next() {
            let tail = instruction.clone().tail();
            // Update the current state
            self.update_state(tail.state());
            // Update the tape
            self.scope_mut().set_symbol(tail.symbol());
            // Update the index; adjusts the index according to the direction
            self.scope_mut()
                .shift(tail.action(), default_symbol.clone());
        }
        // Return the actor
        Ok(self.scope())
    }
    /// [Execute::execute_once]
    fn execute_once(&mut self) -> Result<&Self::Driver, Error> {
        // Get the default symbol
        let default_symbol = self.clone().default_symbol();
        // Get the next instruction
        if let Some(instruction) = self.next() {
            let tail = instruction.tail();
            // Update the current state
            self.update_state(tail.state());
            // Update the tape
            self.scope_mut().set_symbol(tail.symbol());
            // Update the index; adjusts the index according to the direction
            self.scope_mut().shift(tail.action(), default_symbol);
            // Return the actor
            return Ok(self.scope());
        }
        Err(Error::ExecutionError(
            "No more instructions to execute".into(),
        ))
    }
    /// [Execute::execute_until]
    fn execute_until(
        &mut self,
        until: impl Predicate<Self::Driver>,
    ) -> Result<&Self::Driver, Error> {
        while !until.eval(self.scope()) {
            self.execute_once()?;
        }
        Ok(self.scope())
    }

    fn program(&self) -> &Program<S>;

    fn scope(&self) -> &Self::Driver;

    fn scope_mut(&mut self) -> &mut Self::Driver;
}

/// [Executable] describes a program that can be executed with an external driver.
pub trait Executable<S: Symbolic>: Clone + Alphabet<S> + Iterator<Item = Instruction<S>> {
    type Driver: Scope<S>;
    type Error;

    fn execute(&mut self, driver: &mut Self::Driver) -> Result<Self::Driver, Self::Error> {
        // Get the default symbol
        let default_symbol = self.clone().default_symbol();
        // Get the next instruction
        for instruction in self.by_ref() {
            let tail = instruction.clone().tail();
            // Update the current state
            driver.update_state(tail.state());
            // Update the tape
            driver.set_symbol(tail.symbol());
            // Update the index; adjusts the index according to the direction
            driver.shift(tail.action(), default_symbol.clone());
        }
        // Return the actor
        Ok(driver.clone())
    }
    fn execute_once(&mut self, driver: &mut Self::Driver) -> Result<Self::Driver, Self::Error> {
        // Get the default symbol
        let default_symbol = self.clone().default_symbol();
        // Get the next instruction
        if let Some(instruction) = self.next() {
            let tail = instruction.tail();
            // Update the current state
            driver.update_state(tail.state());
            // Update the tape
            driver.set_symbol(tail.symbol());
            // Update the index; adjusts the index according to the direction
            driver.shift(tail.action(), default_symbol);
        }
        // Return the actor
        Ok(driver.clone())
    }
    fn execute_until(
        &mut self,
        driver: &mut Self::Driver,
        until: impl Predicate<Self::Driver>,
    ) -> Result<Self::Driver, Self::Error> {
        // Get the default symbol
        let default_symbol = self.clone().default_symbol();
        // Get the next instruction
        for instruction in self.by_ref() {
            let tail = instruction.clone().tail();
            // Update the current state
            driver.update_state(tail.state());
            // Update the tape
            driver.set_symbol(tail.symbol());
            // Update the index; adjusts the index according to the direction
            driver.shift(tail.action(), default_symbol.clone());
            if until.eval(driver) {
                break;
            }
        }
        // Return the actor
        Ok(driver.clone())
    }
}