let verbs = [|
	"repel"; "assail"; "bugger"; "degauss"; "murder";
	"slay"; "abort"; "avenge"; "fuck"; "defile"; "devour";
	"slaughter"; "spoil"; "eat"; "spank"; "seize"; "respect";
	"sacrifice"; "return"; "pursue"; "deny"; "purchase"; "buy";
	"inspect"; "despoil"; "censure"; "flog"; "elect"; "summon";
	"oust"; "expel"; "extirpate"; "hire"; "fire"; "assassinate";
	"torture"; "extract"; "rescue"; "incite"; "rouse"; "arouse";
	"eliminate"; "arrest"; "kidnap"; "confine"; "condemn";
	"import"; "export"; "exclude"; "make out with"; "kiss";
	"slap"; "punch"; "whip"; "evict"; "install"; "isolate";
	"compile"; "gather"; "banish"; "exile"; "defeat"; "battle";
	"alert"; "go after"; "track down"; "hunt down"; "locate";
	"find"; "transport"; "tolerate"; "impede"; "incinerate";
	"defend"; "impale"; "demoralize"; "pleasure"; "bomb";
	"lay waste to"; "raze"; "inspire"; "worship"; "exalt";
	"repair"; "rectify"; "duplicate"; "clone"; "avert"; "prevent";
	"pervert"; "cast out"; "throw down"; "bang"; "screw"; "do";
	"enslave"; "butcher"; "download"; "upload"; "kill"; "eradicate";
	"fight"; "stab"; "cut"; "steal"; "lacerate"; "chew"; "digest";
	"impound"; "impanel"; "gnaw on"; "respect";
|]

let adjs = [|
	"sleeping"; "thoughtful"; "insipid"; "thoughtless"; "wretched";
	"wrathful"; "Republican"; "Democratic"; "royal"; "earnest";
	"imperial"; "American"; "inspired"; "immoral"; "wistful"; "wondrous";
	"cheerful"; "giggling"; "wonderful"; "angry"; "silly"; "desperate";
	"warped"; "rotting"; "rancid"; "raging"; "cool"; "clever";
	"sneering"; "eternal"; "timeless"; "ancient"; "indecent"; "delightful";
	"scented"; "sexy"; "hot"; "arousing"; "rampant"; "randy"; "evil";
	"sacred"; "holy"; "satanic"; "unholy"; "blasphemous"; "repellent";
	"repulsive"; "fucking"; "worthless"; "grotesque"; "weeping";
	"goddamn"; "rebellious"; "revolutionary"; "young"; "national";
	"federal"; "government"; "presidential"; "international"; "public";
	"current"; "medical"; "fascist"; "buxom"; "apocalyptic";
	"boastful"; "boring"; "effulgent"; "exuberant"; "lugubrious";
	"noisome"; "German"; "germanic"; "cloned"; "perverted"; "fanatic";
	"arrogant"; "magic"; "magical"; "slutty"; "orgasmic"; "obedient";
	"frantic"; "wandering"; "exalted"; "luminous"; "towering";
	"little"; "communist"; "socialist"; "neoliberal"; "master's";
	"grand";
|]

type noun = R of string | M of string | I of string * string | P of string
let nouns = [|
	R "spanner"; R "clown"; R "beetle"; R "candidate"; R "asshole";
	R "queen"; R "king"; R "advisor"; R "sausage"; M "garbage";
	R "book"; I("cockroach","cockroaches"); R "virgin"; I("clitoris","clitorises");
	R "parking lot"; R "parking space"; R "coin meter"; R "car";
	R "burglar"; I("sheep","sheep"); R "bear"; M "rabble";
	R "burger"; R "waterfall"; R "hammer"; R "doorknob";
	R "pig"; R "cop"; R "bagel"; R "mayor"; R "president";
	R "detective"; R "inquisitor"; M "police"; R "teen";
	R "mustache"; R "heterosexual"; P "Inquisition"; R "general";
	I("titty","titties"); R "monkey"; I("empress","empresses"); R "emperor";
	R "dowager"; R "elixir"; R "cipher"; R "code"; R "secret";
	M "heterosexuality"; R "dudebro"; P "opposition"; I("cactus","cacti");
	R "candelabra"; I("furry","furries"); P "gays"; P "spawn"; I("roach","roaches");
	P "debt"; M "indecency"; R "waste"; M "yaoi"; R "American"; R "Russian";
	R "German"; R "fascist"; M "software"; R "pigeon"; R "king"; R "mob";
	P "mafia"; P "apocalypse"; R "clone"; R "pervert"; R "fucker"; R "dude";
	R "fanatic"; I("army","armies"); R "wall"; R "slut"; I("sorceress","sorceresses");
	R "sorcerer"; R "mage"; I("elf","elves"); I("industry","industries");
	R "orgasm"; R "bastard"; R "cult"; R "volunteer"; I("knife","knives");
	R "spire"; I("mistress","mistresses"); R "master"; R "communist"; R "socialist";
	R "conservative"; R "liberal"; I("volcano","volcanoes"); P "means of production";
	I("jury","juries"); R"imperative";
|]

let ppl = [|
	"asshole"; "jackass"; "mom"; "dad"; "mommy"; "daddy"; "granny";
	"auntie"; "senator"; "general"; "captain"; "ma'am"; "sir"; "your majesty";
	"milady"; "milord"; "sire"; "soldier"; "private"; "fool"; "you fool";
	"you idiots"; "girls"; "ladies"; "boys"; "men"; "folks"; "minister";
	"prime minister"; "mayor"; "inquisitor";
|]
let isVowel (x:char) : bool = List.mem x ['a';'e';'i';'o';'u';'A';'E';'I';'O';'U']
type articles = Definite | Indefinite | Zero
let rand a = a.(Random.int(Array.length a))
let np () : string = if (Random.int 5) == 0 then
		rand [|"me";"yourself";"her";"him";"them"|]
	else let n, art = match rand nouns with
		| R s -> rand [|
			s, rand [|Definite;Indefinite|];
			s^"s", rand [|Definite;Zero|];
		|]
		| I(s,p) -> rand [|
			s, rand [|Definite;Indefinite|];
			p, rand [|Definite;Zero|];
		|]
		| P x -> x, Definite
		| M x -> x, rand [|Definite;Zero|] in
	let sp = rand [|n; (rand adjs)^" "^n|] in match art with
		| Definite -> "the " ^ sp
		| Indefinite -> (if isVowel sp.[0] then "an " else "a ") ^ sp
		| Zero -> sp

type seqe = T of string | S | A of string array | F of (unit -> string) | R of seqe array | O of seqe | B of seqe list
let syntax = B [A verbs; S; F np;]
let seqs = R [|
	B[syntax; R[|
		B[T ". that is an order, "; A ppl;];
		B[T ", "; A ppl];
		B[T ", "; A ppl; T ". that is an order"];
	|]; R[| T "."; T "!"; |];];
	B[O(T"i command you, "); A ppl; T ", "; syntax; R[|
		T ".";
		T ". that is an order!";
		T ". it is the only option.";
		T ". and god help us all.";
		T ". otherwise, we're dead.";
		T " or die trying.";
		T "! now!";
	|];];
	B[
		O(T"it is imperative that you "); syntax;
		O(T " or die trying"); O(B[T", ";A ppl]); R[|
		T ".";
		T ". it is the only option.";
		T ". otherwise, god help us all.";
		T ". otherwise, we're dead.";
	|];];
	B[T "this is your last chance, "; A ppl; T ". "; syntax; O(R[|
			T " or you're a dead man";
			T " or you're a dead woman";
			T " or else";
			T " or you find out what we do to people who screw us";
			T " or we go after your family";
		|]); T ".";
	];
	B[ R[|
		T "you shouldn't ";
		T "you mustn't ";
		T "don't ";
		T "we mustn't ";
		T "we cannot allow you to ";
	|]; syntax; O(B[T ", "; A ppl]); T ".";];
	B[syntax; O(B[T ", "; A ppl]); T ", and to hell with the consequences!"];
	B[T "man up and "; syntax; O(B[T ", "; A ppl]); T "."];
	B[syntax; O(B[T ", "; A ppl]); T ", and face your death like a man!"];
	B[T "we're dead anyway, we might as well ";syntax;T".";];
	B[T "you're dead anyway, you might as well ";syntax;T".";];
|]
(* val eval : seqe -> string *)
let rec eval s = match s with
	| T x -> x
	| S -> " "
	| A arr -> rand arr
	| F f -> f ()
	| R s -> eval (rand s)
	| B s -> (List.fold_left (^) "" (List.map eval s))
	| O s -> if Random.int 2 = 0 then eval s else ""

let rec times i x = x (); if i > 0 then times (i-1) x
let () = Random.self_init();
	print_string (eval seqs);
	(* (times 10 (fun () -> print_string ("- "^(eval seqs)^"\n")));; *)

