package router import ( "strings" "github.com/kami/maven/internal/lexicon" "github.com/kami/maven/internal/morph" ) // transientWords — the states a thing is in for an afternoon, as dictionary // forms. They used to be prefixes, which is how a prefix list always goes wrong: // "лаг" matched "лагерь" and "падает" matched nothing else it inflected into. // morph.SameWord compares the words themselves (Vikunja #528). // // Russian aspect pairs are two separate verbs, so a slot lists both where both // are said. English members have no dictionary here and fall back to exact // comparison, which is what they had. var transientWords = []string{ "медленный", "медленно", "тормозить", "тормоз", "лагать", "лаг", "зависать", "зависнуть", "виснуть", "глючить", "барахлить", "отваливаться", "отвалиться", "падать", "упасть", "сдохнуть", "греться", "перегреваться", "перегреться", "slow", "laggy", "stuck", "frozen", "flaky", "broken", "down", } // brokenWords — what "не ..." is denying when the sentence is a complaint. // Dictionary forms, same reason. var brokenWords = []string{ "работать", "пахать", "грузить", "грузиться", "открываться", "включаться", "коннектиться", "подключаться", "work", "load", "connect", "respond", } // selfMarkers — the words that make a sentence about him rather than about a // thing. Their presence turns the test off, because losing a fact he meant to // store is worse than keeping a complaint: "я сломал руку" is durable, and // "интернет не работает" is not. // // A closed class, so it comes from the lexicon: the first-person pronoun has a // fixed number of forms and this file was the third place they were typed out // (Vikunja #528). var selfMarkers = lexicon.FirstPerson() // IsTransientComplaint reports whether text observes a passing state of some // thing rather than recording a fact. // // It exists because "сеть какая-то медленная" and "интернет не работает" were // written to the fact store as `self` rows at confidence 1.00 (Vikunja #481), // where recall reads them back later as if they were still true. A complaint // describes a moment; the fact store describes him. // // Deterministic, offline, and shaped exactly like IsQuestionShaped: an // explicit capture verb wins over everything, because "запомни что интернет // не работает" is an instruction and not a passing remark. A first-person // marker also turns it off — the test is meant to catch a sentence about a // thing, and it errs toward storing. func IsTransientComplaint(text string) bool { t := strings.TrimSpace(text) if t == "" { return false } toks := planTokens(strings.ToLower(t)) for _, v := range captureVerbs { if hasTok(toks, v) { return false } } for _, m := range selfMarkers { if hasTok(toks, m) { return false } } for _, tok := range toks { for _, w := range transientWords { if morph.SameWord(tok, w) { return true } } } // "не" plus a verb of working, in either order of the two tokens that // follow it — "не работает" and "не очень работает" both deny the same // thing. for i, tok := range toks { if tok != "не" && tok != "not" && tok != "isn" { continue } for j := i + 1; j < len(toks) && j <= i+2; j++ { for _, v := range brokenWords { if morph.SameWord(toks[j], v) { return true } } } } return false }