spb/metrika Public
Stata-class statistics, GPU-accelerated by Apple Silicon. Native Swift — no Electron, no Python runtime, no compromises.
Swift 92.4%
HTML 3.3%
R 3%
Shell 1.3%
1//2// KnownVerbs.swift3// Metrika4//5// Author: Simon-Pierre Boucher6// Contact: contact@spboucher.ai7// Copyright © 2026 Simon-Pierre Boucher. All rights reserved.8//910/// Registry of built-in ZQL verbs with their minimum abbreviations,11/// Stata-style: `reg` resolves to `regress`, `su` to `summarize`.12public struct ZQVerbTable: Sendable {13 /// canonical verb → minimum abbreviation length14 public let verbs: [String: Int]15 /// Verbs whose first argument is a raw file path rather than a varlist.16 public let fileVerbs: Set<String>17 /// Verbs taking a `newvar = expression` assignment.18 public let assignmentVerbs: Set<String>19 /// Prefix verbs that wrap another command after a colon.20 public let prefixVerbs: Set<String>21 /// Compound verbs followed by a sub-verb (`graph scatter …`).22 public let compoundVerbs: Set<String>2324 public static let builtin = ZQVerbTable(25 verbs: [26 "use": 3,27 "sysuse": 6,28 "save": 4,29 "import": 3,30 "export": 3,31 "summarize": 2,32 "tabulate": 3,33 "correlate": 3,34 "describe": 1,35 "list": 1,36 "margins": 4,37 "generate": 3,38 "replace": 7,39 "drop": 4,40 "keep": 4,41 "regress": 3,42 "logit": 5,43 "probit": 6,44 "poisson": 7,45 "ivregress": 9,46 "xtreg": 5,47 "xtset": 5,48 "areg": 4,49 "boost": 5,50 "elasticnet": 7,51 "lasso": 5,52 "bayes": 5,53 "bootstrap": 9,54 "permute": 7,55 "jackknife": 9,56 "graph": 2,57 "kdensity": 4,58 "histogram": 4,59 "scatter": 7,60 "display": 2,61 "log": 3,62 "set": 3,63 "clear": 5,64 "count": 3,65 "sort": 4,66 "merge": 5,67 "append": 6,68 "reshape": 7,69 "collapse": 8,70 "egen": 4,71 "predict": 7,72 "test": 4,73 "help": 4,74 ],75 fileVerbs: ["use", "sysuse", "save", "import", "export", "log"],76 assignmentVerbs: ["generate", "replace", "egen"],77 prefixVerbs: ["bayes", "bootstrap", "permute", "jackknife"],78 compoundVerbs: ["graph", "ivregress"]79 )8081 public init(82 verbs: [String: Int],83 fileVerbs: Set<String>,84 assignmentVerbs: Set<String>,85 prefixVerbs: Set<String>,86 compoundVerbs: Set<String>87 ) {88 self.verbs = verbs89 self.fileVerbs = fileVerbs90 self.assignmentVerbs = assignmentVerbs91 self.prefixVerbs = prefixVerbs92 self.compoundVerbs = compoundVerbs93 }9495 /// Resolves a typed verb (possibly abbreviated) to its canonical form.96 /// Returns nil when no verb matches unambiguously.97 public func resolve(_ typed: String) -> String? {98 if let minLength = verbs[typed], typed.count >= minLength { return typed }99 if verbs.keys.contains(typed) { return typed }100101 let candidates = verbs.filter { verb, minLength in102 typed.count >= minLength && verb.hasPrefix(typed)103 }104 return candidates.count == 1 ? candidates.first!.key : nil105 }106107 /// Closest known verb by edit distance, for error suggestions.108 /// Only returns matches within distance 2 to avoid absurd hints.109 public func closest(to typed: String) -> String? {110 let scored = verbs.keys111 .map { (verb: $0, distance: levenshteinDistance(typed, $0)) }112 .sorted { $0.distance < $1.distance }113 guard let best = scored.first, best.distance <= 2 else { return nil }114 return best.verb115 }116}117