import { isNonTerminal , WordWithTypes , Terminal } from "../grammar/category" ; import { Semiring } from "semiring" ; import { Chart } from "./chart/chart" ; import { getActiveCategory , State , advanceDot } from "./chart/state" ; param tokenPosition param word param types param scanProbability param sr param stateSets export function scan < S , T > ( tokenPosition , { word , types } , sr , stateSets , scanProbability ? ) { const changes = [ ] ; const scanProb = ! ! scanProbability ? scanProbability ( word , types ) : undefined ; types . forEach ( terminal => { const statesActiveOnTerminals = stateSets . getStatesActiveOnTerminals ( tokenPosition , terminal ) ; if ( statesActiveOnTerminals ) statesActiveOnTerminals . forEach ( ( preScanState ) => { const activeCategory = getActiveCategory ( preScanState ) ; if ( isNonTerminal ( activeCategory ) ) throw new Error ( "this is a bug" ) ; else { if ( ! activeCategory ( word ) ) throw new Error ( "Index failed" ) ; const preScanForward = stateSets . getForwardScore ( preScanState ) ; const preScanInner = stateSets . getInnerScore ( preScanState ) ; const postScanState = stateSets . getOrCreate ( tokenPosition + 1 , preScanState . ruleStartPosition , advanceDot ( preScanState ) , preScanState . rule , word ) ; const postScanForward = calculateForwardScore ( sr , preScanForward , scanProb ) ; stateSets . setForwardScore ( postScanState , postScanForward ) ; const postScanInner = calculateInnerScore ( sr , preScanInner , scanProb ) ; stateSets . setInnerScore ( postScanState , postScanInner ) ; const viterbiScore = { origin : preScanState , resultingState : postScanState , innerScore : postScanInner } ; stateSets . setViterbiScore ( viterbiScore ) ; changes . push ( { state : postScanState , viterbi : viterbiScore , inner : postScanInner , forward : postScanForward } ) ; } } ) ; } ) ; return changes ; } param scanProbability param sr param previousInner return function calculateInnerScore < S > ( sr , previousInner , scanProbability ? ) { if ( ! scanProbability ) return previousInner ; else return sr . times ( previousInner , scanProbability ) ; } param scanProbability param sr param previousStateForwardScore return function calculateForwardScore < S > ( sr , previousStateForwardScore , scanProbability ? ) { if ( ! scanProbability ) { return previousStateForwardScore ; } else { return sr . times ( previousStateForwardScore , scanProbability ) ; } }