import { Grammar } from "../grammar/grammar" ; import { Chart } from "./chart/chart" ; import { State , getActiveCategory } from "./chart/state" ; import { Category , isNonTerminal , NonTerminal } from "../grammar/category" ; import { Rule } from "../grammar/rule" ; param index param grammar param stateSets export function predict < S , T > ( index , grammar , stateSets ) { const changes = [ ] ; const statesToPredictOn = stateSets . getStatesActiveOnNonTerminals ( index ) ; if ( statesToPredictOn ) { const newStates = new Set < State < S , T > > ( ) ; const probMap = grammar . probabilityMapping ; const sr = probMap . semiring ; const fromProb = probMap . fromProbability ; statesToPredictOn . forEach ( ( statePredecessor ) => { const Z = getActiveCategory ( statePredecessor ) ; const prevForward = stateSets . getForwardScore ( statePredecessor ) ; grammar . leftStarCorners . getNonZeroScores ( Z ) . forEach ( ( Y ) => { if ( isNonTerminal ( Y ) && grammar . ruleMap . has ( Y ) ) grammar . ruleMap . get ( Y ) . forEach ( ( Y_to_v ) => { const Y = Y_to_v . left ; const Y_to_vScore = fromProb ( Y_to_v . probability ) ; const fw = sr . times ( prevForward , sr . times ( fromProb ( grammar . getLeftStarScore ( Z , Y ) ) , Y_to_vScore ) ) ; let predicted ; const isNew = ! stateSets . has ( Y_to_v , index , index , 0 ) ; predicted = isNew ? { position : index , ruleStartPosition : index , ruleDotPosition : 0 , rule : Y_to_v } : stateSets . getOrCreate ( index , index , 0 , Y_to_v ) ; if ( isNew ) newStates . add ( predicted ) ; const innerScore = stateSets . getInnerScore ( predicted ) ; if ( ! ( Y_to_vScore === innerScore || probMap . ZERO === innerScore ) ) throw new Error ( Y_to_vScore + " != " + innerScore ) ; const viterbi = { origin : statePredecessor , resultingState : predicted , innerScore : Y_to_vScore , } ; stateSets . addForwardScore ( predicted , fw , sr ) ; stateSets . setInnerScore ( predicted , Y_to_vScore ) ; stateSets . setViterbiScore ( viterbi ) ; const change = { state : predicted , innerScore : Y_to_vScore , forwardScore : fw , viterbiScore : viterbi , origin : statePredecessor } ; changes . push ( change ) ; } ) ; } ) ; } ) ; newStates . forEach ( ss => stateSets . getOrCreate ( ss . position , ss . ruleStartPosition , ss . ruleDotPosition , ss . rule ) ) ; } return changes ; }