Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Help/markdown/vscode/prompts/00-prime-claude.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Prime Claude for NLP++
<!-- desc: Paste this into a fresh Claude session before asking for any NLP++ help — it is everything Claude needs to know to work on your analyzers: the installed engine, example, and template paths, the conventions that keep it on the rails (use the Knowledge Base template as intended, build results into a KB and emit JSON with JsonKB, build on the library dictionaries and knowledge bases instead of hand-typed word lists, and run with -WORK pointing at the engine), and the engine facts that trip up newcomers. No task to fill in — once Claude has read this, ask it for whatever you need. -->
<!-- desc: Paste this into a fresh Claude session before asking for any NLP++ help — it is everything Claude needs to know to work on your analyzers: the installed engine, example, and template paths, the conventions that keep it on the rails (use the Knowledge Base template as intended, build results into a KB and emit JSON with JsonKB, build on the library dictionaries and knowledge bases instead of hand-typed word lists, reach for the knowledge base rather than a dictionary when only one rule needs the fact, and run with -WORK pointing at the engine), and the engine facts that trip up newcomers. No task to fill in — once Claude has read this, ask it for whatever you need. -->
This is everything you need to know to help me work on NLP++ analyzers. NLP++ is a rule-based programming language for natural language processing, run by the NLP engine. Read this in full before we start — afterward I will ask you to build a new analyzer, extend an existing one, write dictionaries and knowledge bases, generate test inputs, or debug why a rule fires. Everything you need is already installed on this machine at the paths below:

- NLP engine executable (run analyzers with this): {{engineExe}}
Expand Down Expand Up @@ -30,6 +30,7 @@ Rules of thumb — build on the libraries, never on hand-typed word lists:

- **Look in the libraries before you write a vocabulary.** {{languagesDir}} already ships, per language, dictionaries and matching knowledge bases for countries, nationalities/demonyms, languages, months and days, first names and surnames, professions, US states and street suffixes, numbers, prepositions, determiners, pronouns, conjunctions and stop words — plus a full lexicon (en-full.dict / en-full.kbb) carrying part of speech, root, and verb/noun features. {{miscDir}} adds currencies, ISO country codes, telephone country codes, timezones, emojis, roman numerals and URL domains. A pass built on the twenty words you typed by hand is brittle: it handles the test file and nothing else. The library file handles the whole vocabulary.
- **Wire one in by copying the .dict and its matching .kbb into the analyzer's kb/user/.** The tokenizer auto-loads every .dict there and tags matching tokens. Keep the pair together — a .kbb with the same stem supplies the concept hierarchy and the ambiguity readings for its .dict. Files named `…full.dict` / `…full.kbb` lazy-load word by word, so even a large lexicon costs little at startup. For a heavy domain KB that only some inputs need, load it on demand with loaddict / loadkbb (a file name in kb/user, not a path), guarded by a global so it loads once.
- **A dictionary changes what every rule sees; a knowledge base answers when asked.** A .dict in kb/user tags matching tokens for the whole run, in every pass — that is a blast radius, and it is the right one when the analyzer is built on that vocabulary. When one rule needs one fact, the KB is the instrument instead. Match on *shape* and validate in code: the rule is permissive, the loop is strict. A pass that picks US state codes out of a list matches a run of two-letter uppercase tokens separated by commas, then loops calling a KB lookup (`StateName()`) on each candidate — two characters, uppercase, and known to the knowledge base. Words like "multiple", "locations" and "in" fail at least one of those three tests and drop out on their own, without the rule having to name them. Loading a .dict to buy that one lookup would tag those codes in every other pass too, and a dictionary attribute like `s=` even changes tokenization — dicttok builds a typed node for those words, so plain _xALPHA rules stop matching them.
- **Match on the attributes, not on the words.** Dictionary attributes ride on the node, so `@PRE <1,1> var("nationality");` selects every entry in the file, and `N("country",1)`, `N("iso3",1)` read the data straight off the node — no dictfindword call needed. Rules written this way keep working as the library file grows.
- **Match _phrase as well as _xALPHA.** Multi-word and hyphenated entries ("American Samoan", "Bissau-Guinean") arrive from the tokenizer as a single _phrase node carrying the same dictionary attributes. A rule that only matches _xALPHA silently misses every one of them.
- **Join on a stable attribute, never on $text.** Key KB lookups on country=, iso3=, root= and the like — the surface form varies with plural, synonym and hyphenation, and $text on a hyphenated phrase comes back mangled ("bissau - guine").
Expand Down
Loading