Skip to content

Commit a44c605

Browse files
authored
Merge pull request #3 from pragmaticslaboratory/feature/expanding-documentation-and-create-fasow-ui
feature: expanding documentation and create fasow UI
2 parents c6e1312 + bf2d62d commit a44c605

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+5113
-79
lines changed

README.md

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,288 @@ yarn start
7171

7272
# FASOW Architecture
7373

74+
The FASOW architecture is based on the idea of the reflection tower, and is composed by
75+
3 principal modules, the `Experiment`, the `TowerHandler` and the `DataHandler`. Thus, FASOW provides us
76+
a way to implement and create a simulation of an Agent Based model of a Word of Mouth campaign on a Social
77+
Network Site (SNS), managing a flexible architecture easy to learn (easy to reach more users?) and an output generator.
78+
79+
![img_6.png](img_6.png)
80+
# DataHandler
81+
# TowerHandler
82+
83+
## Reflective Tower
84+
85+
The idea of the reflection tower is present in programming languages and allow us to segment a
86+
software architecture by abstraction levels of different granularity. On this case, the FASOW architecture
87+
is segmented by 4 levels (Experiment, Environment, Agent and Actions), where each one handles a specific concern of
88+
the Agent Based Models.
89+
90+
### FASOW Levels
91+
92+
A level in FASOW is an abstraction that handles a specific concern of the ABMs and is composed principally
93+
by three modules or more.
94+
95+
![img_1.png](img_1.png)
96+
97+
* MetaLevel Interface: A Metaprogramming interface that exposes the implementation of the base interface. The MetaLevel interface
98+
provides methods to managed, define or interact with the instantiation of the particularities of the level on execution time, and provides
99+
the capability to register a new particularity component for the level.
100+
101+
* MetaLevel Config: Is a Meta-Configuration object which communicate and connect the MetaLevel Interface with the BaseLevel Interface.
102+
This objects had certain information that is required to pass through the particularity constructor when we will instantiate them
103+
on execution time.
104+
105+
* BaseLevel Interface: A Base Interface, that can be abstract or not, but that defines the base functionality for the level,
106+
this interface is the entity that the MetaLevel Interface will instantiate on execution time.
107+
108+
* ParticularityLevel Modules: These modules are entities that extends the functionality that provides the base level interface,
109+
and allows to users to implements other requirements that cant be provided by the base level interface.
110+
111+
by this way, and by adding levels with less particularity knowledge we can start to see the Reflection Tower!
112+
which connect and centralize all MetaInterfaces on the TowerHandler.
113+
114+
![img_2.png](img_2.png)
115+
116+
### 1.Experiment Level
117+
118+
The experiment level manage the `experiments` on FASOW, and represents the model to study, implement and simulate,
119+
this level is composed by the `ExperimentAPI`, the `MetaExperimentConfig` and the Abstract `Experiment` class
120+
with his extended particularities modules.
121+
122+
The `Experiments` allow us to introduce the input the model and define strategy to follow during the simulation
123+
on FASOW, however, to do that as previous step we need to register all modules that will being used on the simulation by using the use of the TowerHandle.
124+
```typescript
125+
126+
abstract class Experiment {
127+
name: string;
128+
description: string;
129+
repetition: number;
130+
maxRepetitions: number;
131+
132+
strategy(): void;
133+
run();
134+
setConfig(config: MetaExperimentConfig): void;
135+
loadConfig(): void;
136+
//..getters and setters
137+
}
138+
```
139+
The `ExperimentAPI` manages the `Experiments` by handling his registration and creation, also allow us to set and change
140+
the configuration on the MetaExperimentConfig, which represents part of the information required to instantiate and
141+
initialize the model to run the simulation.
142+
```typescript
143+
144+
interface IExperimentAPI {
145+
selectExperimentByName(experiment: string): void;
146+
registerNewExperiment(exp: typeof Experiment): void;
147+
setExperimentName(name: string): void;
148+
setExperimentDescription(description: string): void;
149+
setExperimentMaxRepetitions(maxRepetitions: number): void;
150+
getExperimentConfig(): MetaExperimentConfig;
151+
createSelectedExperiment(): Experiment;
152+
selectExperiment(selected: typeof Experiment): void;
153+
getSelectedExperiment(): typeof Experiment;
154+
getState(): any;
155+
selectExperimentByName(experiment: string): void;
156+
}
157+
```
158+
159+
The `MetaExperimentConfig` help us to define a name, a description and what to instantiate for the experiment
160+
to simulate, and also, we can define a number of times which the simulation will be repeated to handles the
161+
stochastic effect.
162+
163+
```typescript
164+
export default interface MetaExperimentConfig {
165+
// Experiment Metadata
166+
readonly id: number;
167+
name: string;
168+
description: string;
169+
type: typeof Experiment;
170+
maxRepetitions: number;
171+
// Scenario Metadata
172+
environmentConfig: MetaEnvironmentConfig;
173+
}
174+
```
175+
176+
### 2. Environment Level
177+
178+
The environment level manages the `Environments` which are the abstraction of a Social Network Site (SNS) and the simulation,
179+
allow us to define and configure the Simulation. This level is composed by the `EnvironmentAPI`, the `MetaEnvironmentConfig`
180+
and the Abstract `Environment`.
181+
182+
The `Environments` being the abstraction of the simulation and a Social Network Site, enable us to set the size of the
183+
simulation, the types of Agents to create and his relationships, and the duration of a simulation. Also, provides
184+
the place to define the behavior that a social network site and his users will follow.
185+
186+
```typescript
187+
export default abstract class Environment implements EnvironmentConfig, IEnvironmentCreator, Ticks {
188+
id: number;
189+
initialized: boolean;
190+
seedSize: number;
191+
networkSize: number;
192+
seeds: Agent[];
193+
agents: Agent[];
194+
maxTick: number;
195+
tick: number;
196+
197+
setConfig(config: MetaEnvironmentConfig): Environment;
198+
public abstract step(): void;
199+
public run(): void;
200+
initialize(): void;
201+
createAgents(): void;
202+
addFollowers(): void;
203+
addFollowings(): void;
204+
isDone(): boolean;
205+
resetAgentStates(): void;
206+
resetSeedStates(): void;
207+
abstract createEnvironment(environmentConfig: MetaEnvironmentConfig): Environment;
208+
//...getters and setters
209+
}
210+
```
211+
The `MetaEnvironmentConfig` establish the configuration of the simulation like the size of agents to create, the duration
212+
of the simulation, the SNS to use and the configuration of the agents to instantiate.
213+
214+
```typescript
215+
export default interface MetaEnvironmentConfig {
216+
networkSize: number;
217+
maxTick: number;
218+
environmentType: typeof Environment;
219+
metaAgentsConfigs: MetaAgentConfig[];
220+
}
221+
```
222+
223+
The `MetaEnvironmentAPI` manages the registration of the new Environments particularities and the configuration of the
224+
Environment that will be created on the execution time.
225+
226+
```typescript
227+
export default interface EnvironmentAPI {
228+
//...
229+
registerNewEnvironment(newEnvironmentType: typeof Environment)
230+
private getEnvironment(environmentType: typeof Environment): typeof Environment //Why is private ?
231+
generateEnvironment(config: MetaEnvironmentConfig): Environment
232+
setNetworkToScenario(environment: typeof Environment)
233+
addAgentToScenario(agentConfig: MetaAgentConfig)
234+
setNetworkSizeToScenario(size: number)
235+
setPeriodsToScenario(max: number)
236+
setScenarioConfig(scenarioConfig: MetaEnvironmentConfig)
237+
getScenarioConfig(): MetaEnvironmentConfig
238+
resetScenarioConfig(): MetaEnvironmentConfig
239+
getState(): any
240+
}
241+
```
242+
243+
### 3. Agent Level
244+
245+
The experiment layer manage the `experiments`
246+
247+
```typescript
248+
console.log('Hola mundo')
249+
```
250+
### 4. Action Level
251+
252+
The experiment layer manage the `experiments`
253+
254+
```typescript
255+
console.log('Hola mundo')
256+
```
257+
258+
## The FASOW Tower
259+
260+
![img_4.png](img_4.png)
261+
262+
## FASOW Modules
263+
### DataHandler Decorators
264+
265+
## Social Network Sites.
266+
## Extending Behaviors
267+
268+
With the use of the Reflection Tower and with the Four Levels of abstraction that provides FASOW
269+
we can extend the functionality of FASOW by the creation of:
270+
271+
1. **New Experiments**: To Implement a new Model to simulate on FASOW!.
272+
2. **New Environments**: To Adding new Social Network Sites (like the Reddit Social Network) or a specific Agent management rule.
273+
3. **New Agents**: To Adding new behaviors, logic or states that could have an Agent.
274+
4. **New Actions**: To Adding new ways to send or receive a message or change the state of the agent in some circumstance.
275+
276+
Whichever will be the approach to follow, always we will have to Register this new Behavior on FASOW with the use of the TowerHandler.
277+
```typescript
278+
//..experiments/ExampleExperiment.ts
279+
class ExampleExperiment extends Experiment {
280+
// ... other logic
281+
Strategy(): void {
282+
FASOW.TowerHandler.registerNewAgent(TwitterAgent); //Registering a new Agent on FASOW
283+
FASOW.TowerHandler.registerNewAction(ActionRead); //Registering a new Action on FASOW
284+
FASOW.TowerHandler.registerNewAction(ActionShare); //Registering a new Action on FASOW
285+
FASOW.TowerHandler.registerNewEnvironment(EnvironmentTwitter); // Registering a new Action on FASOW
286+
}
287+
}
288+
```
289+
290+
However, the `Experiments` must be Registered on FASOW, by importing them manually and adding to the `fasowLoader.ts` file
291+
as the following way:
292+
293+
```typescript
294+
//..fasowLoader.ts
295+
import ExperimentAgentCombination from 'src/experiments/ExperimentAgentCombinatio/ExperimentAgentCombination';
296+
import ExperimentAgentCombinationBestSeed from 'src/experiments/ExperimentAgentCombinatio/ExperimentAgentCombinationBestSeed';
297+
import ExampleExperiment from './experiments/ExampleExperiment';
298+
import TestExperiment from './experiments/TestExperiment/TestExperiment';
299+
300+
const fasowConfig = [
301+
ExperimentAgentCombination,
302+
ExperimentAgentCombinationBestSeed,
303+
ExampleExperiment,
304+
/** Add your Experiments below to register them on FASOW**/
305+
TestExperiment, //Here you are registering your Experiments
306+
];
307+
308+
export default fasowConfig;
309+
```
310+
311+
### Extending Experiment Layer.
312+
### Extending Agent Layer.
313+
### Extending Environment Layer.
314+
315+
### Extending Action Layer.
316+
By extending the funtionality of the action layers we can add new behaviors to handle how to send, receive
317+
the message or change some state in the Agents by the execution of some rules.
318+
319+
To do this we need to create a new `Action` that extends the `Abstract Action` like this:
320+
```typescript
321+
class TestAction extends Action {
322+
createAction(actionData: MetaActionConfig): Action {
323+
return new TestAction().setConfig(actionData);
324+
}
325+
326+
execute(agent: Agent): void {
327+
agent.receiveMessage();
328+
console.log('TestAction specialized Behavior');
329+
}
330+
}
331+
```
332+
Then we need to register this new action with the TowerHandler to allow to FASOW can use them.
333+
334+
```typescript
335+
// TODO: Imports must be fixed because FASOW not exists in that path xd
336+
import FASOW from "./FASOW";
337+
```
338+
Also, to maintain the FASOW logic this must be done in definition of the Strategies on the Experiments.
339+
340+
```typescript
341+
import FASOW from "./FASOW";
342+
import Experiment from "./Experiment";
343+
344+
345+
class ExampleExperiment extends Experiment {
346+
// ... other logic
347+
Strategy(): void {
348+
FASOW.TowerHandler.registerNewAction(TestAction); // Register the new Action on the Experiment Strategy
349+
}
350+
}
351+
```
352+
353+
354+
355+
74356
## License
75357

76358
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.
Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@ import { ApiParam, ApiTags } from '@nestjs/swagger';
77
export class AppController {
88
constructor(private readonly appService: AppService) {}
99

10-
@Post('run')
11-
run() {
12-
this.appService.runExperiment();
13-
return this.appService.clearDataHandlerOutput();
14-
}
15-
1610
@ApiParam({
1711
name: 'ExperimentId',
1812
type: String,
@@ -40,4 +34,14 @@ export class AppController {
4034
this.appService.runSelectedExperiment();
4135
return this.appService.clearDataHandlerOutput();
4236
}
37+
38+
@Get('getSelectedExperimentConfig')
39+
getSelectedExperimentConfig() {
40+
//Todo: Maybe replace the undefined for nulls, because if the response had undefined, then that response key will be removed instead of been returned with null value
41+
42+
const selectedExperimentConfig = this.appService.getExperimentConfig();
43+
44+
console.log('getSelectedExperimentConfig: ', selectedExperimentConfig);
45+
return selectedExperimentConfig;
46+
}
4347
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Injectable } from '@nestjs/common';
2-
import FASOW from './fasow';
2+
import FASOW from '../fasow';
33

44
@Injectable()
55
export class AppService {

fasow-api/src/experiments/ExampleExperiment.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ export default class ExampleExperiment extends Experiment {
7272
FASOW.TowerHandler.setExperimentDescription('Nothing');
7373
}
7474

75-
// eslint-disable-next-line class-methods-use-this
7675
createExperiment(): Experiment {
7776
return new ExampleExperiment();
7877
}

fasow-api/src/experiments/ExperimentAgentCombinatio/ExperimentAgentCombination.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export default class ExperimentAgentCombination extends Experiment {
9292

9393
run() {
9494
for (let i: number = 10; i < 100; i += 10) {
95-
FASOW.TimeKeeper.setMaxRepetition(1);
95+
this.setMaxRepetition(1);
9696
const percentageHubOfSeed: number = i;
9797
const percentageLeaderOfSeed: number = 100 - i;
9898
console.log('Calculating Percentages of seeds Combinations');
@@ -111,7 +111,7 @@ export default class ExperimentAgentCombination extends Experiment {
111111
console.log('Finals Agents Percentages: ');
112112
console.log(this.percentageTypes);
113113
super.run();
114-
FASOW.TimeKeeper.resetRepetitions();
114+
this.resetRepetitions();
115115
}
116116
}
117117

fasow-api/src/experiments/ExperimentAgentCombinatio/ExperimentAgentCombinationBestSeed.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,13 @@ export default class ExperimentAgentCombinationBestSeed extends Experiment {
6060
}
6161

6262
Strategy(): void {
63+
// Registration of the used components.
6364
FASOW.TowerHandler.registerNewAgent(TwitterAgent);
6465
FASOW.TowerHandler.registerNewAction(ActionRead);
6566
FASOW.TowerHandler.registerNewAction(ActionShare);
6667
FASOW.TowerHandler.registerNewEnvironment(EnvironmentTwitter);
68+
69+
// Defining The MetaExperimentConfiguration.
6770
const nonSeedConfig: MetaAgentConfig = {
6871
id: 0,
6972
name: 'average',
@@ -94,7 +97,7 @@ export default class ExperimentAgentCombinationBestSeed extends Experiment {
9497
environmentType: EnvironmentTwitter,
9598
metaAgentsConfigs: [nonSeedConfig, seedConfig],
9699
});
97-
FASOW.TimeKeeper.setMaxRepetition(2);
100+
this.setMaxRepetition(2);
98101
}
99102

100103
createExperiment(): Experiment {

0 commit comments

Comments
 (0)