Files

75 lines
1.7 KiB
JavaScript

import { FPR_State } from './state.mjs';
export class Abstract_Reduction_Contract {
on_create_scanner(scanner) {}
on_start_transform(scanner, sequence) {}
on_end_transform(scanner, sequence) {}
on_reduction_attempted(scanner, sequence) {}
on_reduction_made(scanner, sequence) {}
check_if_done(scanner, sequence) {
return false;
}
assert_readiness(scanner, sequence) {}
}
export class Reduction_Contract extends Abstract_Reduction_Contract {
check_if_done(scanner, sequence) {
return scanner.last_reduction_status === false;
}
}
export class FPR_Contract extends Reduction_Contract {
constructor(end_condition=null) {
super();
Object.assign(this, { end_condition });
}
check_if_done(scanner, sequence) {
if (this.end_condition) {
return this.end_condition(scanner, sequence);
} else {
return super.check_if_done(scanner, sequence);
}
}
on_create_scanner(scanner) {
Object.assign(scanner, {
cycle_detected: false,
state_manager: new FPR_State(),
});
}
on_start_transform(scanner, sequence) {
super.on_start_transform(scanner, sequence);
const state_manager = scanner.state_manager;
state_manager.clear_journal();
const state = state_manager.gather_state(sequence); //Log initial state
state_manager.log_state(state);
scanner.cycle_detected = false;
}
on_reduction_made(scanner, sequence) {
const state_manager = scanner.state_manager;
const state = state_manager.gather_state(sequence);
const pre_count = state_manager.length;
state_manager.log_state(state);
const post_count = state_manager.length;
if (pre_count === post_count) {
scanner.cycle_detected = true;
}
}
assert_readiness(scanner, sequence) {
if (scanner.cycle_detected) {
throw new Error('Cycle detected');
}
}
}