-
Notifications
You must be signed in to change notification settings - Fork 1
/
Codelets.py
140 lines (110 loc) · 3.69 KB
/
Codelets.py
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
from dataclasses import dataclass
from typing import Union, List, Tuple, Dict, Set, FrozenSet, Iterable, \
Iterator, Any, NewType, Type, ClassVar, Sequence, Callable, Hashable, \
Collection, Sequence, Literal, Protocol, Optional, TypeVar, \
runtime_checkable
from abc import ABC, abstractmethod
@dataclass(frozen=True)
class Feature:
pass
Features = Union[None, Feature, Sequence[Feature]]
@dataclass(frozen=True)
class Ref:
'''A reference to a member of an Agent.'''
name: str
T = TypeVar('T')
R = Union[T, Ref]
SlipnodeType = Hashable # TODO
@dataclass(frozen=True)
class CodeletDataclassMixin:
name: ClassVar[str]
class Codelet(ABC, CodeletDataclassMixin):
@abstractmethod
def go(self, fm: 'FARGModel', **kwargs) -> 'Codelets':
'''Should do the codelet's action, and return any follow-up codelets
to execute next, in the same timestep.'''
pass
Codelets = Union[None, Codelet, Sequence[Codelet]]
@dataclass(frozen=True)
class Agent:
born: Codelets = None
wake: Codelets = None
snag: Codelets = None
delegate_succeeded: Codelets = None
delegate_failed: Codelets = None
succeeded: Codelets = None
failed: Codelets = None
@dataclass(frozen=True)
class AgentState:
name: str
Born = AgentState('born')
Wake = AgentState('wake')
Snag = AgentState('snag')
delegate_succeeded = AgentState('delegate_succeeded')
delegate_failed = AgentState('delegate_failed')
succeeded = AgentState('succeeded')
failed = AgentState('failed')
@dataclass(frozen=True)
class BuildCompanion(Codelet):
behalf_of: Agent
companion_info: Hashable
def go(self, fm):
for ci in self.companion_info:
fm.build(ci, behalf_of=self.behalf_of)
return NewState(self.behalf_of, Wake)
@dataclass(frozen=True)
class NewState(Codelet):
agent: Agent
state: AgentState
def go(self, fm, agent: Agent, state: AgentState): # type: ignore[override]
fm.set_state(agent, state)
@dataclass(frozen=True)
class QuerySlipnetAndBuildDelegate(Codelet):
features: Features
slipnode_type: SlipnodeType
sk = Sleep(Ref('behalf_of'))
def go( # type: ignore[override]
self,
fm,
behalf_of: Agent,
features: Features,
slipnode_type: SlipnodeType
):
# set up activations_in
# exclude delegates already built
# pulse_slipnet
# build a copy of the agent(s) found, linked to behalf_of
raise NotImplementedError
@dataclass(frozen=True)
class Sleep(Codelet):
agent: R[Agent]
def go(self, fm, agent: Agent, num_timesteps: int): # type: ignore[override]
fm.sleep(agent=agent, num_timesteps=num_timesteps)
@dataclass(frozen=True)
class TakeAvails(Codelet):
cellref: CellRef
'''Take avails from cellref and then call sk to build a LitPainter.'''
def go(self, fm, **kwargs):
pass # TODO
if __name__ == '__main__':
class Want(Agent):
'''An Agent that wants to build a sequence of LitPainters that
paint a target value onto a SeqCanvas, constructed from avails in
a given cell--as in Numbo.'''
target: Hashable
startcell: Union[CellRef, None]
sk: Union[Codelet, None]
born = BuildCompanion([
AvailDetector(Ref('target'), sk=NotifyMeSuccess),
GettingCloser.Tagger(Ref('target'))
])
wake = QuerySlipnetAndBuildDelegate([
BeforeFromAvails(Ref('startcell')),
AfterFrom(Ref('target')),
SlipnodeType(Consume)
])
fm = FARGModel()
ca = fm.build(SeqCanvas([SeqState((4, 5, 6), None)]))
wa = fm.build(
Want(target=15, startcell=cr0, sk=RaiseException(TestFoundIt))
)