type noun = R of string * string | V of string * string | M of string | Mv of string | Pn of string | Pnv of string
let sn n = R(n, n^"s")
let nouns = [|
	R("pussy", "pussies"); sn "cock"; R("penis", "penises"); sn "representative";
	R("minority","minorities"); sn "dick"; sn "breast"; sn "mouth"; sn "face";
	M "hair"; Pn "politics"; sn "soul"; sn "ear"; sn "nose"; sn "senator"; sn "kink";
	sn "girl"; sn "boy"; R("city","cities"); R("titty","titties"); sn "vagina"; sn "bot";
	sn "butt"; R("foot","feet"); R("moose","moose"); sn "daughter"; sn "cunt";
	sn "Bolshevik"; sn "goat"; sn "tentacle"; sn "uncle"; sn "queen"; sn "peer"; 
	R("party","parties"); R("cooch","cooches"); R("snooch","snooches"); sn "tit";
	V("ass","asses"); sn "gender"; sn "cop"; M "police"; sn "loser"; sn "king";
	sn "rifle"; sn "vibrator"; Pn "authorities"; R("box","boxes"); sn "orifice"; 
	sn "count"; sn "baron"; R("countess","countesses"); R("baroness","baronesses");
	R("thesis","theses"); M "praxis"; M "rope"; Pn "handcuffs"; sn "boob"; 
	sn "critique"; sn "slave"; sn "buttslut"; sn "idea"; sn "revolver"; sn "corpse";
	R("ideology","ideologies"); sn "beast"; sn "youth"; sn "tail"; sn "bulge";
	sn "tty"; sn "dongle"; sn "shell"; sn "result"; sn "argument"; sn "guitar"; 
	R("class","classes"); V("advance","advance"); sn "restraint"; sn "nipple"; 
	sn "orb"; M "junk"; sn "array"; R("matrix","matrices"); sn "crack"; sn "fork"; 
	R("mistress","mistresses"); V("assignment","assignments");
	R("switch","switches"); sn "sin"; sn "creep"; sn "Pope";  sn "weeb";
	sn "submission"; sn "strap"; sn "noun"; sn "verb"; R("cross","crosses"); sn "whip"; 
	M "faith"; Pn "beliefs"; Pn "panties";	 V("implement","implements"); 
	sn "text"; sn "book"; sn "grimoire"; sn "twink"; sn "blog"; sn "scandal"; 
	Pn "drugs"; Mv "evil"; M "good"; sn "moron"; sn "fuck"; sn "neck"; sn "cad"; 
	sn "fucker"; sn "stalker"; R("beauty","beauties"); sn "jock"; sn "people";
	sn "bro"; sn "president"; sn "nerd"; sn "rival"; sn "hacker"; sn "johnson"; 
	V("illusion","illusions"); sn "hand"; R("ash","ashes"); M "love"; sn "father";
	sn "mother"; R("boundary","boundaries"); sn "callout"; sn "appendage"; 
	sn "callout post"; sn "death"; R("witch","witches"); sn "limb"; sn "loophole";
	V("attack surface","attack surfaces"); sn "claw"; M "democracy"; sn "cannon"; 
	R("woman","women"); M "shit"; Mv "artillery"; R("facility","facilities"); 
	R("man","men"); sn "blog post"; R("knife","knives"); sn "moon"; M "truth";
	R("fetish","fetishes"); R("tummy","tummies"); sn "bunker"; sn "pigeon";
	V("orgasm", "orgasms"); sn "startup"; sn "throat"; sn "wizard"; sn "robe";
	sn "spell"; sn "fanfic"; sn "rack"; sn "thumbscrew"; sn "ballot"; sn "campaign";
	sn "gay"; sn "lesbian"; sn "mommyblog"; sn "widget"; sn "spine"; sn "hell";
	sn "candidate"; sn "dog"; sn "pig"; R("Tory","Tories"); sn "prime minister";
	V("outrage","outrages"); V("elf","elves"); R("dwarf","dwarves"); V("orc","orcs");
	V("ork","orks"); M "discourse"; V("imbecile","imbeciles"); sn "monolith";
	sn "scepter"; V("obelisk","obelisks"); sn "clit"; R("clitoris","clitorises"); M "porn";
	sn "wound"; sn "relationship"; sn "probe"; sn "porn"; sn "secret"; R("lady","ladies");
	V("anxiety","anxieties"); M "scum"; M "dirt"; M "trash"; R("witch","witches");
	M "steam"; M "smoke"; R("senpai","senpai"); R("kohai","kohai"); M "vore";
	R("sensei","sensei"); sn "meat"; R("staff","staves"); sn "rod"; M "terror";
	V("anus","anuses"); R("church","churches"); sn "debate"; sn "console";
	M "bondage"; M "discipline"; sn "catboy"; sn "catgirl"; sn "top"; sn "bottom";
	sn "submissive"; sn "dom"; sn "domme"; sn "prole"; sn "car"; sn "hat";
	sn "commander"; sn "general"; sn "sergeant"; sn "lieutenant"; sn "ensign";
	sn "captain"; sn "admiral"; sn "doctor"; Pn "steel beams"; R("furry","furries");
	V("insecurity","insecurities"); sn "limit"; sn "law"; sn "enchantment";
	R("postmaster general","postmasters general"); R("wench","wenches");
	sn "shame cube"; sn "government"; sn "laser"; M "blood"; M "sex";
	sn "mace"; sn "flail"; sn "neg"; sn "dome"; V("atom","atoms"); sn "chest";
	M "space"; sn "flaw"; sn "failure"; R("booty","booties"); sn "beaver";
	sn "governor"; sn "nuke"; sn "nuclear missile"; sn "nuclear warhead";
	V("ICBM","ICBMs"); V("electrode","electrodes"); Mv "abuse";
	sn "machine"; sn "fucker"; R("boris","borises"); R("gary","garies");
	sn "doom"; sn "pimp"; sn "shitpost"; Pnv "evils"; Pn "Crime Hole";
	
	R ("[REDACTED]","[REDACTED]");
	V ("[REDACTED]","[REDACTED]");
|]
type word = A of string | An of string
let adjs = [|
	A "gleaming"; A "bleeding"; A "stupid"; A "useless"; A "sexy";
	A "tight"; A "wet"; A "hard"; A "kinky"; A "pervy"; A "Republican";
	A "naughty"; A "filthy"; A "slutty"; A "revolutionary"; A"nuclear";
	A "counterrevolutionary"; A "hopeless"; A "satanic"; A "sex";
	A "nuclear sex"; A "lusty"; A "noble"; A "witty"; A "hot"; A "soft";
	A "steamy"; A "Marxist"; A "horny"; A "slutty"; A "lustful";
	A "lawful"; A "bold"; A "sophisticated"; A "winsome"; A "dumb";
	A "bulging"; A "throbbing"; A "scrawny"; A "problematic";
	A "duly appointed"; A "wondrous"; A "scandalous"; A "papal";
	A "holy"; A "whimpering"; A "Bluetooth-enabled"; A "fuckable";
	A "sentient"; A "Turing-complete"; A "redneck"; A "corrective";
	A "lawless"; A "lunar"; A "solar"; A "luminous"; A "repressive";
	A "sustainable"; A "wise"; A "wizardly"; A "sorcerous"; A "wizard";
	A "magic"; A "presidential"; A "campaign"; A "gay"; A "lesbian";
	A "regressive"; A "psychic"; A "sad"; A "happy"; A "humble";
	A "Tory"; A "sinister"; A "sick"; A "twisted"; A "moderate";
	A "horrific"; A "horrifying"; A "conservative"; A "sensible";
	A "meaningless"; A "luscious"; A "lucrative"; A "terror";
	A "secret"; A "snobby"; A "bratty"; A "mystical"; A "$300";
	A "$700"; A "$1000"; A "100-carat"; A "cool"; A "rad";
	A "radical"; A "terrorist"; A "firm"; A "dead"; A "decaying";
	A "submissive"; A "dominant"; A "moist"; A "humiliating"; 
	A "government sex"; A "government"; A "sext"; A "ballistic";
	A "government sext"; A "glistening"; A "blood"; A "strategic";
	A "laser"; A "government blood"; A "+1"; A "cursed"; A "space";
	A "space sex"; A "monumental"; A "restrained"; A "helpless";
	A "boring"; A "heterosexual"; A "monogamous"; A "hairy";
	A "sin"; A "sinful"; A "tactical"; A "rectal"; A "fucking";
	A "dread"; A "dread sex"; A "dread government"; A "pimp";
	A "dread government sex"; A "doom"; A "government doom";
	
	An "awful"; An "electronic"; An "electric"; An "ugly";
	An "illegal"; An "unlawful"; An "arcane"; An "undulating";
	An "appropriate"; An "inappropriate"; An "appropriative";
	An "eminent"; An "ominous"; An "oppressive"; An "anal";
	An "unsustainable"; An "outrageous"; An "insensitive";
	An "elfin"; An "elvish"; An "elfin sex"; An "elvish sex";
	An "esoteric"; An "exotic"; An "abusive"; An "austere";
	An "embarrassing"; An "erotic"; An "imperial";
	An "immaculate"; An "evil"; An "evil government";
	An "evil sex"; An "evil elf"; An "evil gay";
|]
let pick (r : 'a array) : 'a = r.(Random.int(Array.length r))
let coin () = if Random.int 2 = 0 then true else false
let getform p noun = match noun with 
		| Mv (n) | M(n) -> n
		| Pn (n) | Pnv(n) -> n
		| V(sg,pl) -> (if p then pl else sg)
		| R(sg,pl) -> (if p then pl else sg);;
		
let stat noun = let plural = match noun with 
		| Mv (_) | M(_) -> false
		| Pn (_) | Pnv(_) -> true
		| _ -> coin() in
	let form, vl = match noun with
		| V(sg,pl) -> if plural then pl,true else sg,true
		| R(sg,pl) -> if plural then pl,false else sg,false
		| Mv(n) -> n,true
		| M(n) -> n,false 
		| Pn(n) -> n,true 
		| Pnv(n) -> n,true in plural, form, vl;;

let bnp force_sg : string * bool = let noun = pick nouns in
	let p, form, vl = stat noun in
	let plural = if force_sg then false else p in
	let dets = Array.append [| "my"; "your"; "the"; "some"; |]
		(if plural then [| "these"; "those"; |] else [| "this"; "that"; |]) in
	let adj = if coin () then None else Some (pick adjs) in
	(if Random.int 5 = 0 then
		if plural then form else match adj with
		| None -> if vl then "an "^form else "a "^form
		| Some(A(n)) -> "a "^n^" "^form
		| Some(An(n)) -> "an "^n^" "^form
	else (pick dets) ^(
		match adj with
			| None -> ""
			| Some(A(n)) | Some(An(n)) -> " "^n
	)^" "^form),plural;;
	

type form = Bare | Sg | Ppl | Ing
type verb = (form -> string option -> string)
let actions' : verb array ref = ref [||]
let np () = let base, number = bnp false in 
	let n = match Random.int 30 with
		| 0 -> base ^ " of " ^ (let b,_ = bnp false in b)
		| 1 -> base ^ " of " ^ ((pick !actions') Ing (if coin() then None else Some (
			getform true (pick nouns)
		)))
		| 2 -> base ^ " of " ^ (match pick adjs with A(n) | An(n) -> n) ^
			" " ^ ((pick !actions') Ing None)
		| 3 -> (let b,_ = bnp true in b) ^ "'s " ^ (getform (coin()) (pick nouns))
		| _ -> base
	in (n,number);;
	
let strn () = let n,_ = np() in n

let svb (sg,pl,ing,ppl) : verb = (fun f obj -> let o = match obj with
		| None -> ""
		| Some x -> " "^x
	in (match f with
		| Bare -> sg
		| Sg -> pl
		| Ppl -> ppl
		| Ing -> ing)^o)
let phrvb (sg,pl,ing,ppl) prep = (fun f obj -> let o = match obj with
		| None -> ""
		| Some x -> " "^x
	in (match f with
		| Bare -> sg
		| Sg -> pl
		| Ppl -> ppl
		| Ing -> ing)^o^" "^prep)
let ppvb (sg,pl,ing,ppl) prep = (fun f obj -> let o = match obj with
		| None -> ""
		| Some x -> " "^x
	in (match f with
		| Bare -> sg
		| Sg -> pl
		| Ppl -> ppl
		| Ing -> ing)^o^" "^prep^" "^(strn()))
let svt x = (x,x^"s",x^"ing",x^"ed")
let svte x = (x^"e",x^"es",x^"ing",x^"ed")
let evt x = (x,x^"es",x^"ing",x^"ed")

let simple_verbs : verb array = [|
	svb (svt "yank");
	svb (svte "delet");
	svb (svt "compress");
	svb (svt "fuck");
	svb (svt "sext");
	svb (svt "spank");
	svb (svt "smack");
	svb (svt "fork");
	svb ("slap", "slaps", "slapping", "slapped");
	svb (evt "publish");
	svb (evt "punish");
	svb (evt "kiss");
	svb (svt "stay");
	svb (svt "laser");
	svb (svt "censor");
	svb (svt "tweet");
	svb ("vore","vores","voring","vored");
	svb ("bite","bites","biting","bitten");
	svb (evt "dox");
	svb ("police", "polices", "policing", "policed");
	svb (svt "inspect");
	svb ("defile", "defiles", "defiling", "defiled");
	svb ("@", "@s", "@'ing", "@'ed");
	svb ("shoot","shoots","shooting","shot");
	svb ("ship","ships","shipping","shipped");
	svb ("stun","stuns","stunning","stunned");
	svb (svte "mutilat");
	svb (svte "criticiz");
	svb ("debunk","debunks","debunking","debunked");
	svb (svte "critiqu");
	svb ("smite", "smites", "smiting", "smitten");
	svb ("verify", "verifies", "verifying", "verified");
	svb (svt "restrain");
	svb ("inflect", "inflects", "inflecting", "inflected");
	svb ("whip", "whips", "whipping", "whipped");
	svb (svte "squeez");
	svb (svt "pull");
	svb (svt "flatten");
	svb (svt "crush");
	svb (svte "abus");
	svb ("cut", "cuts", "cutting", "cut");
	svb ("dispel", "dispels", "dispelling", "dispelled");
	svb ("split", "splits", "splitting", "split");
	svb (svte "throttl");
	svb (svte "strangl");
	svb (svt "slaughter");
	svb (svte "grop");
	svb (svte "vap");
	svb (svt "sever");
	svb (svt "stalk");
	svb (svt "mock");
	svb ("stab", "stabs", "stabbing", "stabbed");
	svb (svt "snort");
	svb ("ban", "bans", "banning", "banned");
	svb ("oppress", "oppresses", "oppressing", "oppressed");
	svb ("suppress", "suppresses", "suppressing", "suppressed");
	svb ("depress", "depresses", "depressing", "depressed");
	svb (svt "sadden");
	svb (svte "curs");
	svb (svte "vot");
	svb (svt "disrupt");
	svb (svte "humbl");
	svb (svt "fucc");
	svb (svt "69");
	svb (svt "cuck");
	svb ("snap", "snaps", "snapping", "snapped");
	svb (svte "pleasur");
	svb (svte "pleas");
	svb (svt "cuff");
	svb (svt "melt");
	svb (svte "deprecat");
	svb (svte "debat");
	svb (svt "dick");
	svb ("bleed", "bleeds", "bleeding", "bled");
	svb (svt "finger");
	svb (svt "exploit");
	svb ("portscan", "portscans", "portscanning", "portscanned");
	svb ("bully", "bullies", "bullying", "bullied");
	svb (svt "enchant");
	svb ("steal", "steals", "stealing", "stolen");
	svb (svt "yiff");
	phrvb (svt "yiff") "up";
	svb (svt "duel");
	svb (svt "repeal");
	svb (svt "twist");
	svb (svt "abolish");
	svb (svte "punctur");
	svb (svte "roboticiz");
	svb ("wiretap", "wiretaps", "wiretapping", "wiretapped");
	svb ("do", "does", "doing", "done");
	svb (svt "dial");
	svb (svte "enslav");
	svb ("neg", "negs", "negging", "negged");
	svb (svt "slander");
	svb (svt "smear");
	svb (svt "sex");
	svb (svte "censur");
	svb (svte "exoticiz");
	svb (svte "romanticiz");
	svb (svt "bombard");
	svb (svte "seduc");
	svb (svt "despoil");
	svb (svt "destroy");
	svb (svte "ravag");
	svb (svt "ravish");
	svb (svt "plunder");
	svb ("[REDACTED]","[REDACTED]","[REDACTED]","[REDACTED]");
	svb (svte "delud");
	svb (svt "redact");
	svb (svte "denigrat");
	svb (svte "expung");
	svb (svt "insert");
	ppvb (svt "insert") "in";
	svb (svt "lick");
	svb (svt "defeat");
	svb (svt "defend");
	svb (svte "interrogat");
	svb (svte "tortur");
	svb (svt "shock");
	svb (svte "scandaliz");
	svb ("beat","beats","beating","beaten");
	svb (svt "obey");
	svb (svt "disobey");
	svb (svt "doom");
	svb (svt "pimp");
	svb (svt "dissect");
	svb (svt "transcend");
	svb (svte "exorcis");
	svb (svte "compil");
	svb (svte "decompil");
|]

let complex_verbs : verb array = [|
	svb ("laugh at","laughs at","laughing at","laughed at");
	svb ("shoot at","shoots at","shooting at","shot at");
	svb ("shout at","shouts at","shouting at","shouted at");
	phrvb (svt "fuck") "up";
	phrvb (evt "mess") "up";
	phrvb ("hold","holds","holding","held") "down";
	phrvb (evt "push") "down";
	phrvb (svt "knock") "down";
	phrvb ("tie","ties","tying","tied") "down";
	phrvb ("tie","ties","tying","tied") "up";
	ppvb ("tie","ties","tying","tied") "up with";
	ppvb ("tie","ties","tying","tied") "to";
	phrvb ("take","takes","taking","taken") "offline";
	phrvb ("take","takes","taking","taken") "apart";
	ppvb ("take","takes","taking","taken") "out of";
	phrvb ("take","takes","taking","taken") "out";
	ppvb ("take","takes","taking","taken") "out for";
	phrvb ("beat","beats","beating","beaten") "up";
	phrvb ("beat","beats","beating","beaten") "off";
	ppvb ("beat","beats","beating","beaten") "up with";
	ppvb (svte "shov") "onto";
	ppvb (svte "shov") "off";
	ppvb (svte "shov") "out of";
	ppvb (svte "shov") "down";
	ppvb (svt "smack") "in";
	ppvb (svt "smack") "right in";
	ppvb (svt "smack") "with";
	ppvb ("slap", "slaps", "slapping", "slapped") "with";
	ppvb ("slap", "slaps", "slapping", "slapped") "in";
	ppvb ("slap", "slaps", "slapping", "slapped") "right in";
	phrvb ("slap", "slaps", "slapping", "slapped") "silly";
	phrvb ("slap", "slaps", "slapping", "slapped") "off";
	ppvb (evt "punish") "with";
	ppvb (evt "kiss") "on";
	phrvb (svt "connect") "to the internet";
	ppvb (svt "connect") "to";
	ppvb (svt "disconnect") "from";
	phrvb (svt "disconnect") "from the internet";
	ppvb ("put","puts","putting","put") "in";
	ppvb (svt "lock") "in";
	phrvb ("shoot","shoots","shooting","shot") "down";
	ppvb ("shoot","shoots","shooting","shot") "in";
	phrvb ("set","sets","setting","set") "on fire";
	phrvb ("set","sets","setting","set") "to 'stun'";
	phrvb ("get","gets","getting","gotten") "all over";
	ppvb ("get","gets","getting","gotten") "all over";
	phrvb ("spill","spills","spilling","spilt") "all over";
	ppvb ("spill","spills","spilling","spilt") "all over";
	phrvb ("strap","straps","strapping","strapped") "down";
	ppvb ("strap","straps","strapping","strapped") "to";
	phrvb ("keep","keeps","keeping","kept") "out";
	ppvb ("keep","keeps","keeping","kept") "in";
	phrvb ("keep","keeps","keeping","kept") "down";
	ppvb ("keep","keeps","keeping","kept") "out of";
	svb ("beg for","begs for","begging for","begged for");
	ppvb (svte "forc") "into";
	ppvb ("ship","ships","shipping","shipped") "with";
	svb ("submit", "submits", "submitting", "submitted");
	svb ("submit to", "submits to", "submitting to", "submitted to");
	svb ("conjugate", "conjugates", "conjugating", "conjugated");
	svb ("decline", "declines", "declining", "declined");
	ppvb ("inflict", "inflicts", "inflicting", "inflicted") "on";
	ppvb (svt "restrain") "with";
	ppvb ("whip", "whips", "whipping", "whipped") "with";
	svb ("bind", "binds", "binding", "bound");
	ppvb ("bind", "binds", "binding", "bound") "with";
	ppvb ("bind", "binds", "binding", "bound") "to";
	svb (svt "respect");
	svb (svt "disrespect");
	svb (svte "dictat");
	ppvb (svte "dictat") "to";
	svb ("control", "controls", "controlling", "controlled");
	svb (svt "follow");
	svb (svt "unfollow");
	svb (svte "simulat");
	svb (svte "stimulat");
	svb (svte "relocat");
	ppvb (svte "reloca") "to";
	svb (svte "lik");
	svb (svte "crav");
	svb ("deny", "denies", "denying", "denied");
	ppvb (svte "argu") "with";
	svb ("argue with", "argues with", "arguing with", "argued with");
	svb (svte "conjur");
	phrvb (svte "conjur") "up";
	svb ("conjure upon", "conjures upon", "conjuring upon", "conjured upon");
	svb (svt "detect");
	ppvb (svte "disabus") "of";
	ppvb ("cut", "cuts", "cutting", "cut") "with";
	ppvb ("cut", "cuts", "cutting", "cut") "up with";
	phrvb ("cut", "cuts", "cutting", "cut") "up";
	phrvb ("cut", "cuts", "cutting", "cut") "off";
	svb (svte "disassembl");
	svb (svt "clean");
	phrvb ("tidy", "tidies", "tidying", "tidied") "up";
	svb ("tidy", "tidies", "tidying", "tidied");
	ppvb (svte "disassembl") "with";
	phrvb (svt "mock") "online";
	phrvb (svt "mock") "on the internet";
	phrvb (svt "mock") "on Twitter";
	phrvb (svt "call") "out";
	phrvb (svt "call") "names";
	svb ("sin with", "sins with", "sinning with", "sinned with");
	phrvb (svt "call") "out";
	svb ("jerk it to", "jerks it to", "jerking it to", "jerked it to");
	svb ("get off on", "gets off on", "getting off on", "got off on");
	phrvb (svt "exploit") "for sex";
	svb (svte "eviscerat");
	svb (svt "dismember");
	svb (svte "dislocat");
	svb (svte "decriminaliz");
	svb (svte "legaliz");
	svb (svte "disparag");
	svb (svte "evolv");
	svb ("evolve into", "evolves into", "evolving into", "evolved into");
	svb ("devolve into", "devolves into", "devolving into", "devolved into");
	svb (svte "appropriat");
	svb (svte "downvot");
	svb (svte "upvot");
	
	svb (svte "standardiz");
	svb ("commune with", "communes with", "communing with", "communed with");

	svb (svt "devour");
	svb (svte "demoniz");
	phrvb (svte "vot") "into office";
	phrvb (svte "vor") "into office";
	svb ("vote for", "votes for", "voting for", "voted for");
	svb ("spit on", "spits on", "spitting on", "spat on");
	svb ("shit on", "shits on", "shitting on", "shat on");
	svb ("sit on", "sits on", "sitting on", "sat on");
	svb (svte "demoraliz");
	svb ("whisper to", "whispers to", "whispering to", "whispered to");
	svb (svt "discern");
	svb (svt "disgust");
	svb (svt "offend");
	svb (svt "disdain");
	svb (svt "resent");
	svb ("lie to", "lies to", "lying to", "lied to");

	ppvb ("rub", "rubs", "rubbing", "rubbed") "with";
	ppvb ("rub", "rubs", "rubbing", "rubbed") "on";
	ppvb ("rub", "rubs", "rubbing", "rubbed") "all over";
	ppvb ("rub", "rubs", "rubbing", "rubbed") "down with";
	phrvb ("rub", "rubs", "rubbing", "rubbed") "down";
	ppvb ("grind", "grinds", "grinding", "ground") "on";
	ppvb (svt "fill") "with";
	svb (svt "fill");
	phrvb ("snap", "snaps", "snapping", "snapped") "off";
	svb ("bleed on", "bleeds on", "bleeding on", "bled on");
	svb (svt "wound");
	svb (svt "harm");
	svb (svte "prob");
	ppvb (svte "prob") "for";
	svb (svte "automat");
	svb ("watch", "watches", "watching", "watched");
	svb (svt "monitor");
	svb (svte "observ");
	svb ("expel", "expels", "expelling", "expelled");
	ppvb ("expel", "expels", "expelling", "expelled") "from";
	svb ("throw", "throws", "throwing", "thrown");
	phrvb ("throw", "throws", "throwing", "thrown") "out";
	ppvb ("throw", "throws", "throwing", "thrown") "into";
	svb ("sing about", "sings about", "singing about", "sung about");
	svb ("sing for", "sings for", "singing for", "sung for");
	svb ("sing with", "sings with", "singing with", "sung with");
	svb (svt "deflect");
	svb (svte "resembl");
	svb (svte "consol");
	svb ("write about", "writes about", "writing about", "written about");
	svb (svt "honor");
	ppvb (svt "honor") "with";
	svb (svt "dishonor");
	ppvb (svt "dishonor") "with";
	svb ("extol the virtues of", "extols the virtues of", "extolling the virtues of", "extolled in virtue");
	svb (svte "disciplin");
	svb (svte "dominat");
	svb ("top", "tops", "topping", "topped");
	svb (svte "servic");
	svb (svte "serv");
	svb (svt "download");
	svb (svt "upload");
	svb (svt "hack");
	svb (svte "friendzon");
	svb (svte "vindicat");
	svb (svte "shame cub");
	svb (svte "sham");
	svb ("fux", "fuxes", "fuxing", "fuxed");
	phrvb (svt "duel") "to the death";
	ppvb (svt "duel") "for";
	ppvb (svt "duel") "to death for";
	ppvb (svt "duel") "to the death for";
	svb (svte "kinksham");
	ppvb (svte "punctur") "with";
	ppvb (svte "penetrat") "with";
	svb (svt "enter");
	phrvb (svt "dial") "up";
	phrvb (svt "tweet") "up";
	svb ("tweet at","tweets at","tweeting at","tweeted at");
	svb (svte "placat");
|]

let trverbs = Array.append simple_verbs complex_verbs;;

actions' := simple_verbs

let trvp (f : form) : string = if Random.int 15 != 0 then ((pick trverbs) f (Some (strn ())))
	else ((pick simple_verbs) f (Some (strn ()))) ^ " to death"
let vp (f : form) : string = ((pick trverbs) f None)

let titles = [| 
	"mistress"; "master"; "lady"; "lord"; "señora"; "mademoiselle"; "señor"; "monsieur"; "bro";
	"daddy"; "mommy"; "slave"; "girl"; "boy"; "fucktoy"; "senator"; "fuckslave"; "manslave";
	"slut"; "buttslut"; "uncle"; "buttslave"; "professor"; "princess"; "prince"; "father"; "sir";
	"friar"; "president"; "dear"; "your holiness"; "your grace"; "your excellency"; "your worship";
	"your honor"; "milady"; "milord"; "mister"; "missy"; "congressman"; "your eminence";
	"your imperial majesty"; "your majesty"; "miss"; "babe"; "Mr. Chairman"; "Mr. President";
	"Madam Secretary"; "Madam President"; "cuntslave"; "prime minister"; "minister"; "sire";
	"senpai"; "kohai"; "sensei"; "commander"; "general"; "sergeant"; "lieutenant"; "ma'am";
	"captain"; "admiral"; "doctor"; "ensign"; "madame"; "maîtresse"; "maître"; "cap'n"; "baby";
	"babe"; "comrade"; "citizen";
|]
let bareadj () = match pick adjs with A(a) | An(a) -> a;;

let clause () = let n, pl = np () in
	n ^ " " ^ (trvp (if pl then Bare else Sg));;
let (^^) s c = s ^ (String.make 1 c);;
let capitalize_each s = 
	let rec loop (i : int) (o : string) (sp : bool) = 
		if i = (String.length s) then o
		else match s.[i] with
			| ' ' -> loop (i+1) (o^^' ') true
			| 'a'..'z' as c -> if sp
				then loop (i+1) (o^^(Char.uppercase_ascii c)) false
				else loop (i+1) (o^^c) false
			| _ as c -> loop (i+1) (o^^c) false
	in loop 0 "" true
let spell () = let name = (pick trverbs) Bare (Some(match pick nouns with
	| R(sg,pl) | V(sg,pl) -> pick [|sg;pl|]
	| M(n) | Mv(n) | Pn(n) | Pnv(n) -> n)) in capitalize_each name
let ivb f = pick [|
	(fun () -> (pick trverbs) f (Some "you"));
	(fun () -> (pick trverbs) f (Some "you"));
	(fun () -> (pick trverbs) f (Some "ye"));
	(fun () -> (pick trverbs) f (Some "myself"));
	(fun () -> (pick trverbs) f (Some "myself"));
	(fun () -> (pick trverbs) f (Some "meself"));
	(fun () -> (trvp f));
	(fun () -> (trvp f));
|]();;
let uvb f = pick [|
	(fun () -> (pick trverbs) f (Some "yourself"));
	(fun () -> (pick trverbs) f (Some "me"));
	(fun () -> (pick trverbs) f (Some "yourself"));
	(fun () -> (pick trverbs) f (Some "me"));
	(fun () -> (pick trverbs) f (Some "yeself"));
	(fun () -> (trvp f));
|]();;
let rec tpls = [|
	(fun () -> clause());
	(fun () -> "I like "^(strn()));
	(fun () -> "I'm "^(strn()));
	(fun () -> "I'm always "^(strn()));
	(fun () -> "I'm always a slut for "^(strn()));
	(fun () -> "I'm always "^(strn())^" for "^(strn()));
	(fun () -> "I'm always "^(bareadj())^" for "^(strn()));
	(fun () -> "I, um, I "^(ivb Bare));
	(fun () -> "I, um, "^(ivb Bare));
	(fun () -> "you, um, you "^(uvb Bare));
	(fun () -> "you, um, "^(uvb Bare));
	(fun () -> "I like to "^(ivb Bare));
	(fun () -> "I like to, how you say, "^(ivb Bare));
	(fun () -> "I'm gonna "^((pick simple_verbs) Bare (Some "you"))^" silly and call you \""^(pick titles)^"\"");
	(fun () -> "you "^((pick simple_verbs) Bare (Some "me"))^" silly and call me \""^(pick titles)^"\"");
	(fun () -> ((pick simple_verbs) Bare (Some "me"))^" silly and call me \""^(pick titles)^"\"");
	(fun () -> "you want to be "^((pick simple_verbs) Ppl None)^" silly and called \""^(pick titles)^"\"");
	(fun () -> "I want to "^(ivb Bare));
	(fun () -> "let me "^(ivb Bare));
	(fun () -> "I wanna "^(ivb Bare));
	(fun () -> "I'm gonna "^(ivb Bare));
	(fun () -> "I'm going to "^(ivb Bare));
	(fun () -> "I need to "^(ivb Bare));
	(fun () -> "I gotta "^(ivb Bare));
	(fun () -> "you need to "^(uvb Bare));
	(fun () -> "you need to be "^((pick trverbs) Ppl None));
	(fun () -> "you gotta "^(uvb Bare));
	(fun () -> "you must not "^(uvb Bare));
	(fun () -> "you wouldn't "^(uvb Bare));
	(fun () -> "don't make me "^(ivb Bare));
	(fun () -> "I force you to "^(uvb Bare));
	(fun () -> "you force me to "^(ivb Bare));
	(fun () -> "I'm "^(bareadj ()));
	(fun () -> "I'm gonna make you "^(bareadj ()));
	(fun () -> "you're "^(bareadj ()));
	(fun () -> "this is "^(bareadj ()));
	(fun () -> "this is very "^(bareadj ()));
	(fun () -> "this is deeply "^(bareadj ()));
	(fun () -> "you have to "^(uvb Bare)^" if you want to be my "^(pick titles));
	(fun () -> "I "^(ivb Bare));
	(fun () -> "I cast "^(spell ()));
	(fun () -> "I need to cast "^(spell ()));
	(fun () -> "don't make me cast "^(spell ()));
	(fun () -> "I cast "^(spell ())^" on you");
	(fun () -> "don't make me cast "^(spell ())^" on you");
	(fun () -> "I cast "^(spell ())^" on myself");
	(fun () -> "I need to cast "^(spell ())^" on myself");
	(fun () -> "you cast "^(spell ()));
	(fun () -> "you need to cast "^(spell ()));
	(fun () -> "you cast "^(spell ())^" on me");
	(fun () -> "you need to cast "^(spell ())^" on me");
	(fun () -> "you cast "^(spell ())^" on yourself");
	(fun () -> "you need to cast "^(spell ())^" on yourself");
	(fun () -> "I'm "^(ivb Ing));
	(fun () -> "I've "^(ivb Ppl));
	(fun () -> "you've "^(uvb Ppl));
	(fun () -> "you "^(uvb Bare));
	(fun () -> "look me in the eye when I "^(pick trverbs) Bare (Some "you"));
	(fun () -> "keep your eyes on "^(strn())^" while I "^(ivb Bare));
	(fun () -> "you must really want to be "^(vp Ppl)^(if coin() then "" else " by "^(strn())));
	(fun () -> "you must really want me to "^(ivb Bare));
	(fun () -> "you must really want "^(strn())^" to "^(trvp Bare));
	(fun () -> "you're gonna get "^(vp Ppl));
	(fun () -> (if coin() then "please " else "") ^ "put "^(strn())^" in "^(strn())^(if coin() then "" else ", and then "^(trvp Bare)));
	(fun () -> (trvp Bare));
	(fun () -> "please " ^ (trvp Bare));
	(fun () -> ((pick trverbs) Bare (Some "me")) ^ " and " ^ ((pick trverbs) Bare (Some "me")));
	(fun () -> (pick tpls)() ^" so I can "^(ivb Bare));
	(fun () -> (pick tpls)() ^" hard");
	(fun () -> (pick tpls)() ^" harder");
	(fun () -> (pick tpls)() ^", if that's alright");
	(fun () -> (pick tpls)() ^", in the Biblical sense");
	(fun () -> (pick tpls)() ^" - in the Biblical sense");
	(fun () -> (pick tpls)() ^", if you don't mind");
	(fun () -> (pick tpls)() ^", if you know what I mean");
	(fun () -> "um, " ^ (pick tpls)());
	(fun () -> "arrrr, " ^ (pick tpls)());
	(fun () -> "yarrr, " ^ (pick tpls)());
	(fun () -> "well, " ^ (pick tpls)());
	(fun () -> "you know, " ^ (pick tpls)());
	(fun () -> "haha, " ^ (pick tpls)());
|]
let epithets = [| "lover"; "punk"; "slut"; "slave"; "fuck"; "fucker"; "toy"; "eater"; "snob"; "lord"; "-ass"; "boy"; "girl"; "bro"; "-man"; "man";|]
let rec mtpls = [| (* haaaaack *)
	(fun () -> (pick tpls)());
	(fun () -> (pick tpls)());
	(fun () -> (pick tpls)());
	(fun () -> (pick tpls)()^"~");
	(fun () -> (pick tpls)()^"?");
	(fun () -> (pick tpls)() ^", right?");
	(fun () -> (pick tpls)() ^" - no homo");
	(fun () -> (pick tpls)() ^" - no hetero");
	(fun () -> (pick tpls)() ^", but no homo");
	(fun () -> (pick tpls)() ^", yeah?");
	(fun () -> (pick tpls)() ^", alright?");
	(fun () -> "wanna "^(uvb Bare)^"?");
	(fun () -> "wanna "^(uvb Bare)^", if you know what I mean?");
	(fun () -> (pick tpls)() ^", "^(pick titles));
	(fun () -> (pick tpls)() ^", "^(pick titles)^"~");
	(fun () -> "hey "^(pick titles)^", "^(pick tpls)());
	(fun () -> (pick tpls)() ^", "^(pick titles)^"-san");
	(fun () -> (pick tpls)() ^", "^(pick titles)^"-kun");
	(fun () -> (pick tpls)() ^", "^(pick titles)^"-sama");
	(fun () -> (pick tpls)() ^", "^(pick titles)^"-chan");
	(fun () -> (pick tpls)() ^", "^(pick titles)^"-tan");
	(fun () -> (pick tpls)() ^", "^(pick titles)^"-senpai");
	(fun () -> "please, "^(pick tpls)() ^", "^(pick titles)^"-san");
	(fun () -> "please, "^(pick titles)^"-san, "^(pick tpls)());
	(fun () -> (pick tpls)() ^", "^(match pick nouns with R(n,_) | V(n,_) | M(n) | Mv(n) | Pn(n) | Pnv(n) -> n)^"-san"); (* yeesh *)
	(fun () -> (pick tpls)() ^", you "^(match pick nouns with R(n,_) | V(n,_) | M(n) | Mv(n) | Pn(n) | Pnv(n) -> n)^(if coin() then "" else (pick epithets))); (* yeesh *)
	(fun () -> (pick tpls)() ^", you "^
		(match pick adjs with A(a) | An(a) -> a)^" "^
		(match pick nouns with R(n,_) | V(n,_) | M(n) | Mv(n) | Pn(n) | Pnv(n) -> n)
		^(if coin() then "" else (pick epithets))); (* yeeeeeeeeeeesh *)
|]
let rec ntpls = [|
	(fun name -> (pick tpls)() ^", "^name);
	(fun name -> (pick tpls)() ^", "^name);
	(fun name -> (pick tpls)() ^", "^name);
	(fun name -> (pick tpls)() ^", "^name);
	(fun name -> (pick tpls)() ^", "^name);
	(fun name -> (pick tpls)() ^", "^name^"~");
	(fun name -> (pick tpls)() ^", "^name^"~");
	(fun name -> (pick tpls)() ^", "^name^" - no homo");
	(fun name -> (pick tpls)() ^", "^name^" - no hetero");
	(fun name -> "Hey "^name^", "^(pick tpls)());
	(fun name -> "Hey "^name^", "^(pick tpls)());
	(fun name -> "Hey "^name^", "^(pick tpls)());
	(fun name -> "Hey "^name^", "^(pick tpls)());
	(fun name -> "Hey "^name^", "^(pick tpls)()^"~");
	(fun name -> "Hey "^name^", "^(pick tpls)()^" - no homo");
	(fun name -> "Hey "^name^", "^(pick tpls)()^" - no hetero");
	(fun name -> "Hey "^name^", "^(trvp Bare));
	(fun name -> "Hey "^name^", "^(trvp Bare));
	(fun name -> "Hey "^name^", "^(trvp Bare));
	(fun name -> "Hey "^name^", "^(trvp Bare));
	(fun name -> "Hey "^name^", "^(trvp Bare)^"~");
	(fun name -> "Hey "^name^", "^(trvp Bare)^" - no homo");
	(fun name -> "Hey "^name^", "^(trvp Bare)^" - no hetero");
|]
let () = Random.self_init ();
	if (Array.length Sys.argv = 1) || (Sys.argv.(1) = "") then print_string (String.capitalize_ascii ((pick mtpls)()))
	else print_string (String.capitalize_ascii ((pick ntpls) (String.trim Sys.argv.(1))));
	print_string "\n";
	
