let range min max = (Random.int (max-min)) + min
let chance n = range 0 n = 0
let pick (r: 'a array) : 'a = r.(range 0 (Array.length r));;

let prefixes = [|
    "anarcho"; "diabolo"; "psycho"; "neuro"; "socio"; "ego"; "mesmo";
|]
let suffixes = [|
    "phrenia"; "pathy"; "sis"; "tism"; "clasm";
|]
let adjs = [|
    "eboulliant"; "gangrenous"; "hysterical"; "malicious"; "diabolical"; "injunctive"; "gregarious"; "apocalyptic"; "felonious"; "oppositional"; "defiant"; "dextrous"; "harmonious"; "disharmonious"; "defective"; "reactive"; "magnificent"; "misogynistic"; "egalitarian"; "paraphilic"; "deviant"; "subjunctive"; "indicative"; "optative"; "jussive"; "judicial"; "precarious"; "disjunctive"; "redactive"; "[REDACTED]"; "criminal"; "illegal"; "psychotic"; "delusional"; "lawful"; "unlawful"; "inferior"; "superior"; "psychotic"; "histrionic"; "borderline"; "schizoid"; "theoretic"; "theoretical"; "Marxist"; "Leninist"; "Chomskyite"; "selective"; "clinical"; "sub-clinical"; "dominant"; "latent"; "submissive"; "orgasmic"; "orgiastic"; "optimistic"; "pessimistic"; "depressive"; "manic"; "dysfunctional"; "redundant"; "reciprocal"; "reflexive"; "didactic"; "syntonic"; "asymptomatic"; "asymptotic"; "infinite"; "diabetic"; "carcinogenic"; "diabetic"; "adiabatic";
|]
let parts = [| 
    "ego"; "id"; "superego"; "posterior"; "hindbrain"; "forebrain"; "forehead"; "kidney"; "appendix"; "elbow"; "intestinal tract"; "bile"; "ichor"; "blood";
|]
let dtnames = [|
    "kreutz"; "hammar"; "feld"; "holtz"; "mann"; "eich"; "berger"; "wald"; "grund"; "weiss"; "schmerz"; "welt"; "sturm"; "blitz"; "reich"; "blitzen"; "brauch"; "ratten"; "huber"; "bliss"; "blatt"; "gott"; "zeit"; "leute"; "haupt"; "bann"; "eich"; "schaft"; "hund"; "stein"; "pferd"; "wurst"; "brot"; "lauf"; "glück"; "freund"; "feldt"; "stadt"; "dorf"; "bahn"; "euch"; "brandt"; "blut"; "knorpel";
|]
let names = [| "Chomsky"; "Marx"; "Lenin"; "Mao"; "Freud"; "Asperger";|]
let name () = if chance 6 then (pick names) else String.capitalize_ascii ((pick dtnames) ^ (pick dtnames))

let kinds = [|
    "disorder";
    "defect";
    "dysfunction";
    "personality disorder";
    "syndrome";
    "personality defect";
    "defect";
    "illness";
    "psychopathy";
    "sociopathy";
    "tendency";
    "delusion";
    "hysteria";
    "psychosis";
    "neurosis";
    "dementia";
    "schizophrenia";
    "effect";
    "mutism";
    "autism";
    "corruption";
    "mania";
|]



let rec subform () = match range 0 12 with
    | 0 -> (pick adjs) ^ " " ^ (pick kinds)
    | 1 -> (pick adjs) ^ "-" ^ (pick adjs) ^ " " ^ (pick kinds)
    | 2 -> (name ()) ^ " " ^ (pick kinds)
    | 3 -> (name ()) ^ " " ^ (subform ())
    | 4 -> (name ()) ^ "-type " ^ (subform ())
    | 5 -> (subform()) ^ " of the " ^ (pick parts)
    | 6 -> (pick adjs) ^ " " ^ (subform ())
    | 7 -> (pick adjs) ^ " " ^ (pick prefixes) ^ (pick suffixes)
    | 8 -> (pick prefixes) ^ "-" ^ (pick adjs) ^ " " ^ (pick kinds)
    | 9 -> (pick parts) ^ " " ^ (pick kinds)
    | 10 -> (name ()) ^ "-" ^ (subform ())
    | 11 -> (pick parts) ^ "-" ^ (pick adjs) ^ " " ^ (pick kinds)
    | _ -> assert false

let modifiers = [|
    "a peculiar case of";
    "a peculiar form of";
    "an unusual case of";
    "an unusual form of";
    "a remarkable case of";
    "a remarkable form of";
|]
let form () = (if chance 4 then (pick modifiers) ^ " " else "") ^ match range 0 3 with
    | 0 -> subform ()
    | 1 -> (name ()) ^ "'s " ^ (subform ())
    | 2 -> "the " ^ (subform ())
    | _ -> assert false

let dxs = [|
    "suffering from";
    "afflicted by";
    "displaying";
    "displaying the characteristics of";
    "displaying the characteristic behavior of";
    "crippled by";
    "under the influence of";
|]
let msg () = match (if chance 4 then 0 else range 0 5) with 
    | 0 -> (pick [|
        "You appear to be";
        "You would appear to be";
        "You seem to be";
        "You would seem to be";
        "I can only hypothesize that you are";
        "You are";
        "It seems you are";
        "I can only come to the conclusion that you are";
        "The only conclusion I can come to is that you are";
        "I can conclude only that you are";
        "Clearly, you are";
        "You are clearly";|]) ^ " " ^ (pick dxs) ^ " " ^ (form())
    | 1 -> "As clear a case of " ^ (form ()) ^ " as I've ever seen"
    | 2 -> "Clearly a case of " ^ (form ())
    | 3 -> "Clearly a sad case of " ^ (form ())
    | 4 -> "The symptoms are remarkably reminiscent of " ^ (form()) ^ ", as described by " ^ (name()) ^ " in his famous treatise"
    | 5 -> "The obvious diagnosis is, of course, " ^ (form()) ^ (if chance 2 then ", though I remain skeptical" else "")
    | _ -> assert false

let () = Random.self_init (); print_string (msg ())
