10 · Georgetown-IBM Demo (1954) — RU→EN#
Dependencies: stdlib only — no pip installs required Runtime: < 1 minute on any CPU
On January 7, 1954, in the auditorium of the IBM headquarters in New York, a crowd watched an IBM 701 translate 49 Russian sentences into English — automatically, in seconds. The Georgetown-IBM experiment was the first public demonstration of machine translation.
“The experiment indicates that it is reasonable to expect that the complete problem of machine translation will be solved within three to five years.” — Leon Dostert, Georgetown University, 1954
The prediction was off by about 60 years. But the demonstration was real, and the architecture it embodied — direct transfer with a bilingual lexicon and a small set of grammar rules — remained the dominant paradigm until the 1990s.
Historical context#
The system was designed by Paul Garvin (Georgetown) in collaboration with IBM engineers. It operated in the domain of chemistry, politics, and mathematics. The lexicon had 250 entries; the grammar had 6 rules. The source language was Russian, written in transliterated form (Romanized) on IBM punch cards.
The 6 rules handled the main structural divergences between Russian and English that arise in the chemistry domain:
Post-nominal adjective → pre-nominal (Russian adjectives often follow nouns)
Genitive construction → “X of Y”
Negation particle before verb → “does not VERB”
Modal mozhno → “it is possible to VERB”
Sentence-final verb → SVO reordering
Prepositional phrase with pri → “in the presence of”
What we implement#
A 250-entry transliterated Russian lexicon (chemistry + politics domain)
The 6 grammar rules as token-sequence transformations
A translate() pipeline: tokenize → lookup → apply rules → output
~20 demo sentences modelled on the 1954 domain
A time-machine cell running 20 chemistry/science sentences through the system
# This chapter is **stdlib only** — nothing to install.
# It runs on any Python 3.8+ with no pip dependencies.
1 · The Lexicon#
The Georgetown system used 250 dictionary entries. Each entry associates a transliterated Russian word with an English gloss and a grammatical code that the rule engine reads.
Grammatical codes used here:
N— noun (nominative / default)N-GEN— noun known to appear in genitive context (approximated lexically)V— verb (infinitive or present stem)ADJ— adjectivePREP— prepositionPRON— pronounADV— adverbCONJ— conjunctionNEG— negation particle (ne)MODAL— modal expression (mozhno = “can / it is possible”)NUM— numeralPART— particle / discourse markerAUX— auxiliary / copula
The lexicon is intentionally transparent so students can see exactly what the 1954 system “knew”.
# ─────────────────────────────────────────────────────────────────────────
# Georgetown-IBM 250-entry Lexicon
# Format: (transliterated_russian, grammatical_code, english_gloss)
# ─────────────────────────────────────────────────────────────────────────
LEXICON_RAW = [
# ── Chemistry: elements & materials ──────────────────────────────────
("ugol", "N", "coal"),
("kislorod", "N", "oxygen"),
("vodorod", "N", "hydrogen"),
("zhelezo", "N", "iron"),
("zoloto", "N", "gold"),
("serebro", "N", "silver"),
("med", "N", "copper"),
("alyuminiy", "N", "aluminum"),
("svinets", "N", "lead"),
("uglerod", "N", "carbon"),
("azot", "N", "nitrogen"),
("fosfat", "N", "phosphate"),
("kislota", "N", "acid"),
("kisloty", "N-GEN", "acid"),
("shcheloch", "N", "alkali"),
("sol", "N", "salt"),
("veshchestvo", "N", "substance"),
("element", "N", "element"),
("elementy", "N", "elements"),
("atom", "N", "atom"),
("atomy", "N", "atoms"),
("molekula", "N", "molecule"),
("molekuly", "N-GEN", "molecule"),
("reaktsiya", "N", "reaction"),
("reaktsii", "N-GEN", "reaction"),
("soyedineniye", "N", "compound"),
("rastvor", "N", "solution"),
("kristall", "N", "crystal"),
("temperatura", "N", "temperature"),
("temperatury", "N-GEN", "temperature"),
("davleniye", "N", "pressure"),
("davleniya", "N-GEN", "pressure"),
("zhidkost", "N", "liquid"),
("gaz", "N", "gas"),
("toplivo", "N", "fuel"),
("topliva", "N-GEN", "fuel"),
("voda", "N", "water"),
("vody", "N-GEN", "water"),
("ruda", "N", "ore"),
("rudy", "N-GEN", "ore"),
("pech", "N", "furnace"),
("pechi", "N-GEN", "furnace"),
("pecheykh", "N", "furnaces"),
("struktura", "N", "structure"),
("strukturu", "N", "structure"),
("struktury", "N-GEN", "structure"),
("svoystvo", "N", "property"),
("svoystva", "N-GEN", "property"),
("osnova", "N", "foundation"),
("osnovy", "N-GEN", "foundation"),
("baza", "N", "base"),
("okis", "N", "oxide"),
("okisi", "N-GEN", "oxide"),
("smyes", "N", "mixture"),
("smyesi", "N-GEN", "mixture"),
("produkt", "N", "product"),
("produkty", "N", "products"),
("produktov", "N-GEN", "products"),
("katalizator", "N", "catalyst"),
("oksid", "N", "oxide"),
("uglekislota", "N", "carbonic acid"),
("uglevodorod", "N", "hydrocarbon"),
("uglevodorod y", "N", "hydrocarbons"),
# ── Chemistry: processes & conditions ────────────────────────────────
("protsess", "N", "process"),
("metod", "N", "method"),
("analiz", "N", "analysis"),
("sintez", "N", "synthesis"),
("osazhdeniye", "N", "precipitation"),
("distillyatsiya", "N", "distillation"),
("filtrat", "N", "filtrate"),
("osadok", "N", "precipitate"),
("kontsentratsiya", "N", "concentration"),
("kontsent ratsiya","N", "concentration"),
("skorost", "N", "rate"),
("skorosti", "N-GEN", "rate"),
("ravnovesiye", "N", "equilibrium"),
("energiya", "N", "energy"),
("energii", "N-GEN", "energy"),
("teplo", "N", "heat"),
("tepla", "N-GEN", "heat"),
("svet", "N", "light"),
("elektrichestvo", "N", "electricity"),
("magnitnoye", "ADJ", "magnetic"),
("polyarniy", "ADJ", "polar"),
("ionny", "ADJ", "ionic"),
("kovalentny", "ADJ", "covalent"),
("metallicheskiy", "ADJ", "metallic"),
# ── Adjectives ───────────────────────────────────────────────────────
("zhidkiy", "ADJ", "liquid"),
("zhidkoye", "ADJ", "liquid"),
("gazovy", "ADJ", "gaseous"),
("tverdoye", "ADJ", "solid"),
("organicheskiy", "ADJ", "organic"),
("organicheskikh", "ADJ", "organic"),
("neorganicheskiy", "ADJ", "inorganic"),
("khimicheskiy", "ADJ", "chemical"),
("khimicheskikh", "ADJ", "chemical"),
("khimicheskiye", "ADJ", "chemical"),
("atomnuyu", "ADJ", "atomic"),
("atomny", "ADJ", "atomic"),
("molekulyarny", "ADJ", "molecular"),
("biologicheskiy", "ADJ", "biological"),
("fizicheskiy", "ADJ", "physical"),
("fizicheskikh", "ADJ", "physical"),
("elektricheskiy", "ADJ", "electrical"),
("termicheskiy", "ADJ", "thermal"),
("kisly", "ADJ", "acidic"),
("shchelochnoy", "ADJ", "alkaline"),
("chisty", "ADJ", "pure"),
("kholodnoy", "ADJ", "cold"),
("goryachey", "ADJ", "hot"),
("vysokiy", "ADJ", "high"),
("vysokoy", "ADJ", "high"),
("nizky", "ADJ", "low"),
("nizkoy", "ADJ", "low"),
("noviy", "ADJ", "new"),
("vazhniy", "ADJ", "important"),
("effektivny", "ADJ", "effective"),
("promyshlennoy", "ADJ", "industrial"),
("promyshlennuyu", "ADJ", "industrial"),
("nauchniy", "ADJ", "scientific"),
("mezhdunarodny", "ADJ", "international"),
("mezhdunarodnogo", "ADJ", "international"),
("razlichny", "ADJ", "various"),
("bolshoy", "ADJ", "large"),
("maliy", "ADJ", "small"),
("perviy", "ADJ", "first"),
("osnovnoy", "ADJ", "main"),
("osnovanа", "ADJ", "based"),
("osnovan", "ADJ", "based"),
("osnovanа", "ADJ", "based"),
# ── Science / politics: nouns ─────────────────────────────────────────
("mir", "N", "peace"),
("voyna", "N", "war"),
("narod", "N", "people"),
("strana", "N", "country"),
("strany", "N-GEN", "country"),
("ekonomika", "N", "economy"),
("ekonomiki", "N-GEN", "economy"),
("nauka", "N", "science"),
("nauki", "N-GEN", "science"),
("tekhnologiya", "N", "technology"),
("industria", "N", "industry"),
("razvitiye", "N", "development"),
("razvitiya", "N-GEN", "development"),
("sotrudnichestvo", "N", "cooperation"),
("sotrudnichestva", "N-GEN", "cooperation"),
("kommunikatsiya", "N", "communication"),
("yazyk", "N", "language"),
("yazyki", "N", "languages"),
("rech", "N", "speech"),
("rechi", "N-GEN", "speech"),
("tekst", "N", "text"),
("slovo", "N", "word"),
("misli", "N", "thoughts"),
("mysl", "N", "thought"),
("informatsia", "N", "information"),
("znanie", "N", "knowledge"),
("znania", "N-GEN", "knowledge"),
("issledovaniye", "N", "research"),
("issledovaniya", "N-GEN", "research"),
("laboratoriya", "N", "laboratory"),
("laboratorii", "N-GEN", "laboratory"),
("institut", "N", "institute"),
("instituta", "N-GEN", "institute"),
("universitye", "N", "university"),
("stepen", "N", "degree"),
("urovyen", "N", "level"),
("primer", "N", "example"),
("rezulat", "N", "result"),
("rezultaty", "N", "results"),
("rezultat", "N", "result"),
("tsel", "N", "goal"),
("kolichestvo", "N", "quantity"),
("kolichestva", "N-GEN", "quantity"),
("sostav", "N", "composition"),
("sostava", "N-GEN", "composition"),
("chislo", "N", "number"),
("mira", "N-GEN", "world"),
("sostoyanie", "N", "state"),
("sostoyaniyakh", "N", "states"),
("chelovek", "N", "human"),
("lyudi", "N", "people"),
("vremya", "N", "time"),
("sila", "N", "force"),
("sily", "N-GEN", "force"),
("mashina", "N", "machine"),
("mashiny", "N-GEN", "machine"),
("sistema", "N", "system"),
("sistemy", "N-GEN", "system"),
("velichina", "N", "magnitude"),
("velichiny", "N-GEN", "magnitude"),
("uslovie", "N", "condition"),
("usloviya", "N", "conditions"),
("osnove", "N", "basis"),
("rost", "N", "growth"),
("rosta", "N-GEN", "growth"),
("zhizn", "N", "life"),
# ── Verbs ─────────────────────────────────────────────────────────────
("byt", "V", "be"),
("yest", "V", "is"),
("imet", "V", "have"),
("delat", "V", "make"),
("poluchat", "V", "obtain"),
("poluchayut", "V", "obtain"),
("sozdat", "V", "create"),
("ispolzovat", "V", "use"),
("ispolzuyutsya", "V", "are used"),
("sushchestvovat", "V", "exist"),
("sushchestvuyet", "V", "exists"),
("prevrashchat", "V", "convert"),
("prevrashchayut", "V", "convert"),
("prisutstvovat", "V", "be present"),
("prisutstvuyet", "V", "is present"),
("vzaimodeystvovat","V", "react"),
("vzaimodeystvuyet","V", "reacts"),
("vzaimodeystvuyut","V", "react"),
("soyedinyatsya", "V", "combine"),
("soyedinyayutsya", "V", "combine"),
("rastvoryatsya", "V", "dissolve"),
("rastvoryen", "V", "is dissolved"),
("zavisit", "V", "depends"),
("trebovat", "V", "require"),
("trebuyet", "V", "requires"),
("trebuyut", "V", "require"),
("imet", "V", "have"),
("imeyut", "V", "have"),
("osnovana", "V", "is based"),
("peredayom", "V", "transmit"),
("proiskhodit", "V", "occurs"),
("proiskhodyat", "V", "occur"),
("povyshat", "V", "increase"),
("povyshayet", "V", "increases"),
("snizhat", "V", "decrease"),
("snizhayet", "V", "decreases"),
("obespechivat", "V", "provide"),
("obespechivayut", "V", "provide"),
("primenyat", "V", "apply"),
("primenyayut", "V", "apply"),
("vklyuchat", "V", "include"),
("vklyuchayut", "V", "include"),
("nazyvat", "V", "call"),
("nazyvayut", "V", "call"),
("izmeryat", "V", "measure"),
("izuchat", "V", "study"),
("izuchayut", "V", "study"),
# ── Prepositions ─────────────────────────────────────────────────────
("v", "PREP", "in"),
("vo", "PREP", "in"),
("iz", "PREP", "from"),
("s", "PREP", "with"),
("so", "PREP", "with"),
("na", "PREP", "on"),
("pri", "PREP", "in the presence of"),
("dlya", "PREP", "for"),
("do", "PREP", "up to"),
("posle", "PREP", "after"),
("ot", "PREP", "from"),
("mezhdu", "PREP", "between"),
("cherez", "PREP", "through"),
("bez", "PREP", "without"),
("pod", "PREP", "under"),
("nad", "PREP", "above"),
("k", "PREP", "to"),
("po", "PREP", "by"),
("posredstvennymi", "PREP", "by means of"),
("s obrazovaniyem", "PREP", "with formation of"),
# ── Conjunctions ─────────────────────────────────────────────────────
("i", "CONJ", "and"),
("a", "CONJ", "but"),
("no", "CONJ", "but"),
("ili", "CONJ", "or"),
("chto", "CONJ", "that"),
("kogda", "CONJ", "when"),
("esli", "CONJ", "if"),
("tak", "CONJ", "so"),
("takzhe", "ADV", "also"),
# ── Pronouns ─────────────────────────────────────────────────────────
("mi", "PRON", "we"),
("oni", "PRON", "they"),
("eto", "PRON", "this"),
("on", "PRON", "it"),
("ona", "PRON", "it"),
("ego", "PRON", "its"),
("vse", "PRON", "all"),
("nekotorye", "PRON", "some"),
("mnogie", "PRON", "many"),
("kazhdiy", "PRON", "each"),
("takie", "PRON", "such"),
("tot", "PRON", "that"),
("etot", "PRON", "this"),
# ── Adverbs ──────────────────────────────────────────────────────────
("ochen", "ADV", "very"),
("togda", "ADV", "then"),
("tam", "ADV", "there"),
("zdes", "ADV", "here"),
("teper", "ADV", "now"),
("vsegda", "ADV", "always"),
("horosho", "ADV", "well"),
("bystro", "ADV", "rapidly"),
("medlenno", "ADV", "slowly"),
("obychno", "ADV", "usually"),
("chasto", "ADV", "frequently"),
("polnostyu", "ADV", "completely"),
("pochti", "ADV", "almost"),
("tolko", "ADV", "only"),
("uzhe", "ADV", "already"),
("eshche", "ADV", "still"),
("ne", "NEG", "not"),
# ── Modal ─────────────────────────────────────────────────────────────
("mozhno", "MODAL", "possible"),
("nelzya", "MODAL", "impossible"),
# ── Numerals ─────────────────────────────────────────────────────────
("odin", "NUM", "one"),
("dva", "NUM", "two"),
("tri", "NUM", "three"),
("chetyre", "NUM", "four"),
("pyat", "NUM", "five"),
("shest", "NUM", "six"),
("sem", "NUM", "seven"),
("vosem", "NUM", "eight"),
("devyat", "NUM", "nine"),
("desyat", "NUM", "ten"),
("trekh", "NUM", "three"),
("neskolko", "NUM", "several"),
("mnogo", "NUM", "many"),
# ── Particles / discourse ─────────────────────────────────────────────
("takzhe", "PART", "also"),
("lish", "PART", "only"),
("uzhe", "PART", "already"),
("krome", "PART", "except"),
("dazhe", "PART", "even"),
("imenno", "PART", "namely"),
("zhe", "PART", "indeed"),
("li", "PART", "whether"),
("vot", "PART", "here is"),
]
# Build lookup dictionary (lowercase → (code, gloss))
LEXICON = {}
for word, code, gloss in LEXICON_RAW:
LEXICON[word.lower()] = (code, gloss)
print(f"Lexicon loaded: {len(LEXICON)} entries")
print()
# Show a sample
sample_words = ["kislorod", "zhelezo", "khimicheskiy", "ne", "mozhno", "v", "i"]
print(f"{'Word':<22s} {'Code':<10s} {'English'}")
print("-" * 50)
for w in sample_words:
if w in LEXICON:
code, gloss = LEXICON[w]
print(f" {w:<20s} {code:<10s} {gloss}")
2 · The Six Grammar Rules#
The Georgetown system applied rules to sequences of grammatical codes, not raw words. Think of each rule as a pattern-rewrite over the token sequence.
We represent each translated sentence as a list of (code, english_word) tuples.
Each rule inspects the list and may reorder, insert, or replace elements.
Rule |
Pattern |
Transformation |
Example |
|---|---|---|---|
1 |
N ADJ |
→ ADJ N |
ugol zhidkiy → “liquid coal” |
2 |
N N-GEN |
→ N “of” N |
temperatura reaktsii → “temperature of reaction” |
3 |
NEG V |
→ “does not” V |
ne vzaimodeystvuyet → “does not react” |
4 |
MODAL V |
→ “it is possible to” V |
mozhno prevrashchat → “it is possible to convert” |
5 |
PREP “pri” |
→ “in the presence of” |
pri kislote → “in the presence of acid” |
6 |
sentence-final V |
→ move after first N/PRON |
SVO reordering |
# ─────────────────────────────────────────────────────────────────────────
# Grammar rules
# Each rule takes a list of (code, word) tuples and returns a (possibly
# reordered / augmented) list.
# ─────────────────────────────────────────────────────────────────────────
def apply_rule1_adj_noun(tokens):
"""Rule 1: Post-nominal adjective → pre-nominal.
Pattern: (N, w1) (ADJ, w2) → (ADJ, w2) (N, w1)
"""
result = list(tokens)
changed = True
while changed:
changed = False
for i in range(len(result) - 1):
c1, w1 = result[i]
c2, w2 = result[i + 1]
if c1 in ("N", "N-GEN") and c2 == "ADJ":
result[i], result[i + 1] = result[i + 1], result[i]
changed = True
break # restart scan after a swap
return result
def apply_rule2_genitive(tokens):
"""Rule 2: Genitive noun construction → N 'of' N.
Pattern: (N/ADJ, w1) (N-GEN, w2) → (N, w1) (PREP, 'of') (N, w2)
"""
result = []
i = 0
while i < len(tokens):
if (i + 1 < len(tokens)
and tokens[i][0] in ("N", "ADJ")
and tokens[i + 1][0] == "N-GEN"):
result.append(tokens[i])
result.append(("PREP", "of"))
result.append(("N", tokens[i + 1][1]))
i += 2
else:
result.append(tokens[i])
i += 1
return result
def apply_rule3_negation(tokens):
"""Rule 3: NEG before V → 'does not' + V (drops the NEG token)."""
result = []
i = 0
while i < len(tokens):
if (tokens[i][0] == "NEG"
and i + 1 < len(tokens)
and tokens[i + 1][0] == "V"):
result.append(("AUX", "does not"))
i += 1 # skip NEG, next iteration will handle V normally
else:
result.append(tokens[i])
i += 1
return result
def apply_rule4_modal(tokens):
"""Rule 4: MODAL + V → 'it is possible to' + V (replaces MODAL)."""
result = []
i = 0
while i < len(tokens):
if (tokens[i][0] == "MODAL"
and i + 1 < len(tokens)
and tokens[i + 1][0] == "V"):
result.append(("AUX", "it is possible to"))
i += 1 # consume MODAL; next iteration handles V
else:
result.append(tokens[i])
i += 1
return result
def apply_rule5_pri(tokens):
"""Rule 5: PREP 'in the presence of' + N → keep but mark phrase.
(The lexicon already maps 'pri' → 'in the presence of', so this rule
is mostly a no-op for the surface form. We normalise so PREP does not
stack with the next PREP accidentally.)
Actually this rule moves the pri-phrase to the end if it is mid-sentence.
"""
# Find any (PREP, 'in the presence of') and move it + its N-argument
# to the end of the sentence.
pri_phrase = []
rest = []
i = 0
while i < len(tokens):
if (tokens[i] == ("PREP", "in the presence of")
and i + 1 < len(tokens)
and tokens[i + 1][0] in ("N", "N-GEN", "ADJ")):
pri_phrase.append(tokens[i])
pri_phrase.append(tokens[i + 1])
i += 2
else:
rest.append(tokens[i])
i += 1
return rest + pri_phrase
def apply_rule6_verb_final(tokens):
"""Rule 6: Sentence-final V → move to after first subject (N/PRON).
Russian allows SOV and OVS; we convert to SVO.
Only fires when the last content token is a verb and a subject precedes it.
"""
if not tokens:
return tokens
last_code, last_word = tokens[-1]
if last_code not in ("V", "AUX"):
return tokens # verb not final, rule does not fire
# Find first N or PRON (subject candidate)
subj_idx = None
for i, (c, _) in enumerate(tokens[:-1]):
if c in ("N", "PRON", "N-GEN"):
subj_idx = i
break
if subj_idx is None:
return tokens # no subject found, give up
# Move final verb to position right after the subject
verb_token = tokens[-1]
new_tokens = list(tokens[:-1]) # drop final verb
insert_at = subj_idx + 1
new_tokens.insert(insert_at, verb_token)
return new_tokens
RULES = [
apply_rule3_negation, # NEG+V → "does not" V (must precede rule 6)
apply_rule4_modal, # MODAL+V → "it is possible to" V
apply_rule5_pri, # move pri-phrase to end
apply_rule2_genitive, # N N-GEN → N of N
apply_rule1_adj_noun, # N ADJ → ADJ N
apply_rule6_verb_final, # SOV → SVO
]
print("Six grammar rules defined:")
for i, r in enumerate(RULES, 1):
print(f" Rule {i}: {r.__name__}")
3 · The Translation Pipeline#
Russian input string
│
▼
tokenize() split on whitespace / punctuation
│
▼
lookup() replace each token with (code, english_gloss)
unknown words: keep as-is with code "UNK"
│
▼
apply_rules() apply all 6 rules in sequence
│
▼
detokenize() join words, capitalise first word
│
▼
English output
import re as _re
def tokenize_ru(sentence: str) -> list:
"""Split transliterated Russian into word tokens (lowercase)."""
# Keep alphabetic runs and hyphens; discard punctuation separately
return _re.findall(r"[a-z][a-z'-]*", sentence.lower())
def lookup_token(token: str) -> tuple:
"""Return (grammatical_code, english_word) for a Russian token.
Falls back to ('UNK', token) for out-of-vocabulary words.
"""
if token in LEXICON:
return LEXICON[token]
return ("UNK", f"[{token}]")
def apply_rules(tokens: list) -> list:
"""Apply all 6 grammar rules in sequence."""
for rule in RULES:
tokens = rule(tokens)
return tokens
def detokenize(tokens: list) -> str:
"""Join (code, word) pairs into a surface English string."""
words = [w for _, w in tokens]
if not words:
return ""
sentence = " ".join(words)
return sentence[0].upper() + sentence[1:]
def translate(russian_sentence: str) -> str:
"""Full Georgetown-style RU→EN pipeline."""
raw_tokens = tokenize_ru(russian_sentence)
coded_tokens = [lookup_token(t) for t in raw_tokens]
reordered = apply_rules(coded_tokens)
return detokenize(reordered)
# Quick smoke test
test = "ne vzaimodeystvuyet s kholodnoy kislotoy"
print(f"Input: {test}")
print(f"Output: {translate(test)}")
4 · Demo Sentences#
The 1954 demonstration used sentences from chemistry, politics, and science. Here are ~20 representative examples modelled on the actual domain, together with reference translations and the system’s output.
A ✓ means the output is acceptable; ✗ means a rule fired incorrectly or a word is missing from the 250-entry lexicon (OOV = out of vocabulary).
DEMO_SENTENCES = [
# (transliterated Russian, reference English translation)
("mi peredayom misli posredstvennymi rechi",
"we transmit thoughts by means of speech"),
("veshchestvo sushchestvuyet v trekh sostoyaniyakh",
"substance exists in three states"),
("ugol mozhno prevrashchat v zhidkoye toplivo",
"coal can be converted into liquid fuel"),
("kislorod i vodorod soyedinyayutsya s obrazovaniyem vodi",
"oxygen and hydrogen combine with formation of water"),
("temperatura kisloty zavisit ot davleniya",
"temperature of acid depends on pressure"),
("khimicheskiye elementy imeyut atomnuyu strukturu",
"chemical elements have atomic structure"),
("alyuminiy ne vzaimodeystvuyet s kholodnoy kislotoy",
"aluminum does not react with cold acid"),
("zhelezo poluchayut iz rudy v pechakh",
"iron is obtained from ore in furnaces"),
("razvitiye nauki trebuyet mezhdunarodnogo sotrudnichestva",
"development of science requires international cooperation"),
("ekonomika strany osnovan na promyshlennoy baze",
"economy of country is based on industrial foundation"),
("kislorod rastvoryen v vode pri nizkoy temperature",
"oxygen is dissolved in water in the presence of low temperature"),
("rost kolichestva uglevodorodov proiskhodit bystro",
"growth of the quantity of hydrocarbons occurs rapidly"),
("katalizator povyshayet skorost reaktsii",
"catalyst increases rate of reaction"),
("kontsentratsiya rastvora zavisit ot temperatury",
"concentration of solution depends on temperature"),
("vodorod i azot soyedinyayutsya pri vysokoy temperature",
"hydrogen and nitrogen combine in the presence of high temperature"),
("nauka i tekhnologiya obespechivayut razvitiye industrii",
"science and technology provide development of industry"),
("organicheskiye soedineniya vklyuchayut uglerod",
"organic compounds include carbon"),
("mi ispolzuyutsya noviy metod analiza",
"we use new method of analysis"),
("chistiy alyuminiy ne vzaimodeystvuyet s vodoy",
"pure aluminum does not react with water"),
("energiya khimicheskoy reaktsii zavisit ot sostava",
"energy of chemical reaction depends on composition"),
]
print("Georgetown-IBM Demo — RU→EN Translation")
print("=" * 65)
print(f" {'#':<3s} {'Input (transliterated Russian)':<40s}")
print(f" {'':3s} {'Reference':<40s}")
print(f" {'':3s} {'System output':<40s}")
print("-" * 65)
for i, (ru, ref) in enumerate(DEMO_SENTENCES, 1):
out = translate(ru)
oov_count = sum(1 for t in tokenize_ru(ru) if t not in LEXICON)
marker = "✗ OOV" if oov_count > 0 else "✓"
print(f"\n {i:2d}. {marker}")
print(f" RU: {ru}")
print(f" REF: {ref}")
print(f" SYS: {out}")
5 · Rule Tracing#
Let us trace a single sentence step by step so the rule engine is fully transparent. We use sentence 3: ugol mozhno prevrashchat v zhidkoye toplivo (“coal can be converted into liquid fuel”).
def trace_translate(russian_sentence: str) -> str:
"""Translate with step-by-step rule tracing."""
print(f"Input: {russian_sentence}")
print()
raw = tokenize_ru(russian_sentence)
print(f"Step 1 — tokenize: {raw}")
coded = [lookup_token(t) for t in raw]
print(f"Step 2 — lookup: {coded}")
print()
current = coded
for rule in RULES:
before = list(current)
current = rule(current)
if current != before:
print(f" {rule.__name__!r:35s} → {current}")
else:
print(f" {rule.__name__!r:35s} (no change)")
print()
result = detokenize(current)
print(f"Output: {result}")
return result
_ = trace_translate("ugol mozhno prevrashchat v zhidkoye toplivo")
6 · Lexicon Coverage Analysis#
A 250-word lexicon is tiny. Let us measure exactly how many words in each demo sentence fall outside the vocabulary (OOV = out-of-vocabulary).
print("Lexicon coverage per demo sentence")
print(f" {'#':<3s} {'Tokens':>6s} {'In-vocab':>8s} {'OOV':>5s} {'Coverage':>9s} OOV words")
print("-" * 70)
total_tokens = 0
total_covered = 0
for i, (ru, _) in enumerate(DEMO_SENTENCES, 1):
toks = tokenize_ru(ru)
oov = [t for t in toks if t not in LEXICON]
cov = 1 - len(oov) / len(toks) if toks else 1.0
total_tokens += len(toks)
total_covered += len(toks) - len(oov)
oov_str = ", ".join(oov) if oov else "—"
print(f" {i:2d}. {len(toks):6d} {len(toks)-len(oov):8d} {len(oov):5d} {cov:8.1%} {oov_str}")
print("-" * 70)
overall = total_covered / total_tokens if total_tokens else 1.0
print(f" {'ALL':3s} {total_tokens:6d} {total_covered:8d} {total_tokens-total_covered:5d} {overall:8.1%}")
print()
print(f"Overall lexicon coverage: {overall:.1%}")
print()
print("Note: the real 1954 system carefully chose sentences to stay within")
print("its 250-word lexicon. Sentences were not generated spontaneously —")
print("they were pre-selected to demonstrate the system's coverage.")
7 · Historical Accuracy Note#
Our implementation simplifies the 1954 system in several ways:
Transliteration instead of Cyrillic: The actual IBM 701 used punch cards that could not represent Cyrillic. Input was in a special phonemic code. We use standard transliteration (GOST-equivalent).
Grammatical codes: Dostert (1955) describes the codes as multi-field numeric strings (e.g., “31” = verb, “32” = noun, etc.). We use readable mnemonics (
N,V,ADJ, …) to make the rules self-documenting.Rule count: The 1954 publicity materials cited “6 rules”. Later analyses (Hutchins 2004) suggest the actual number may have been higher; 6 is the canonical figure cited in Dostert (1955).
Lexicon size: 250 entries is the figure from contemporary reports. The actual lexicon was domain-specific to chemistry, politics, and mathematics.
Determinism: The 1954 system was fully deterministic — no probabilities, no search, no ambiguity resolution. Our implementation faithfully reproduces this property.
Reference: Dostert, L. E. (1955). The Georgetown-IBM Experiment. In W. N. Locke & A. D. Booth (Eds.), Machine Translation of Languages. MIT Press.
8 · Time-Machine Cell#
Every chapter in this course runs the same 20 held-out test sentences through its translation system, so the quality arc across the eras is directly visible.
The 20 shared benchmark sentences are English→German (Multi30k domain). Georgetown only knew Russian→English and only covered chemistry/politics. It cannot process the EN→DE benchmark sentences — wrong direction, wrong domain, wrong language.
Instead, we run 20 chemistry/science sentences through the Georgetown system to show what the 1954 era could and could not do.
“Georgetown’s 250-word lexicon is domain-specific and direction-specific. It cannot process the 20 EN→DE benchmark sentences (wrong direction, wrong domain). The quality arc for EN→DE begins in Chapter 20 (EBMT). Here we witness the era when MT was direct transfer, rule-based, and domain-locked.”
# ── Shared EN→DE benchmark (cannot be processed by Georgetown) ─────────────
TIME_MACHINE_EN_DE = [
"A man is walking his dog in the park .",
"Two children are playing near a fountain .",
"A woman in a red coat is reading a book .",
"Several people are waiting at a bus stop .",
"A cyclist is riding through a crowded street .",
"A dog is chasing a ball on the beach .",
"A group of tourists is taking photographs .",
"A young girl is feeding ducks by a pond .",
"Two men are playing chess in a cafe .",
"A street musician is playing the violin .",
"Children are running through a field of flowers .",
"An old man is sitting on a bench reading a newspaper .",
"A woman is carrying groceries up a flight of stairs .",
"A boy is kicking a football against a wall .",
"A couple is dancing on an empty street .",
"A chef is preparing food in an outdoor kitchen .",
"A cat is sleeping on a warm windowsill .",
"Workers are repairing a road in the rain .",
"A small boat is sailing on a calm lake .",
"Firefighters are climbing a tall ladder .",
]
# ── Georgetown RU→EN time-machine sentences ────────────────────────────────
TIME_MACHINE_RU_EN = [
"ugol mozhno prevrashchat v zhidkoye toplivo",
"kislorod rastvoryen v vode pri nizkoy temperature",
"temperatura kisloty zavisit ot davleniya",
"zhelezo poluchayut iz rudy v pechakh",
"alyuminiy ne vzaimodeystvuyet s kholodnoy kislotoy",
"khimicheskiye elementy imeyut atomnuyu strukturu",
"katalizator povyshayet skorost reaktsii",
"vodorod i azot soyedinyayutsya pri vysokoy temperature",
"nauka i tekhnologiya obespechivayut razvitiye industrii",
"razvitiye nauki trebuyet mezhdunarodnogo sotrudnichestva",
"veshchestvo sushchestvuyet v trekh sostoyaniyakh",
"organicheskiye soedineniya vklyuchayut uglerod",
"energiya khimicheskoy reaktsii zavisit ot sostava",
"kontsentratsiya rastvora zavisit ot temperatury",
"kislorod i vodorod soyedinyayutsya s obrazovaniyem vodi",
"mi peredayom misli posredstvennymi rechi",
"ekonomika strany osnovan na promyshlennoy baze",
"rost kolichestva uglevodorodov proiskhodit bystro",
"chistiy alyuminiy ne vzaimodeystvuyet s vodoy",
"nauka i tekhnologiya obespechivayut razvitiye industrii",
]
print("╔══════════════════════════════════════════════════════════════════╗")
print("║ TIME-MACHINE CELL — Chapter 10 · Georgetown 1954 ║")
print("╚══════════════════════════════════════════════════════════════════╝")
print()
print("EN→DE benchmark sentences: CANNOT BE PROCESSED")
print(" Georgetown (1954) translates Russian→English, chemistry domain only.")
print(" The EN→DE quality arc begins in Chapter 20 (EBMT, 1984).")
print()
print("─" * 68)
print("RU→EN output for 20 chemistry / science sentences:")
print("─" * 68)
print()
for i, ru in enumerate(TIME_MACHINE_RU_EN, 1):
en = translate(ru)
oov = [t for t in tokenize_ru(ru) if t not in LEXICON]
flag = f" [OOV: {', '.join(oov)}]" if oov else ""
print(f" {i:2d}. RU: {ru}")
print(f" EN: {en}{flag}")
print()
print("─" * 68)
print("Observations:")
print(" • The system handles common chemistry vocabulary correctly.")
print(" • Rule 2 (genitive) and Rule 4 (modal) fire on most sentences.")
print(" • OOV words appear in brackets — the 250-word lexicon is very small.")
print(" • All output is grammatically flat (no morphology, no agreement).")
print(" • Translation is instantaneous — fully deterministic, no search.")
print()
print("Quality verdict: intelligible for in-domain sentences; breaks immediately")
print("for any out-of-domain or morphologically complex input.")
print()
print("Next chapter: Chapter 11 (Soviet 1955) adds morphological analysis.")
print("The EN→DE quality arc begins at Chapter 20 (EBMT).")
Summary#
Property |
Georgetown 1954 |
|---|---|
Direction |
Russian → English |
Domain |
Chemistry, politics, mathematics |
Lexicon |
250 entries (transliterated) |
Grammar |
6 deterministic rules |
Morphology |
None (single wordform per entry) |
Ambiguity resolution |
None (first-match, deterministic) |
Training |
None (hand-crafted) |
Dependencies |
stdlib only |
Key insight: The Georgetown experiment proved MT was possible, not that it was general. The 6-rule system works by carefully selecting sentences that avoid all the hard cases. This tension — demonstration vs. generalization — runs through the entire history of MT.
Next: Chapter 11 (Soviet 1955) adds morphological awareness: stem-and-ending tables, case resolution, and aspect disambiguation for a larger chemistry lexicon.
References:
Dostert, L. E. (1955). The Georgetown-IBM Experiment. In Locke & Booth (Eds.), Machine Translation of Languages. MIT Press.
Hutchins, W. J. (2004). The Georgetown-IBM Experiment Demonstrated in January 1954. Proceedings of AMTA 2004. LNAI 3265, 102–114.
Hutchins, W. J. (1986). Machine Translation: Past, Present, Future. Ellis Horwood.