xref: /plan9/sys/src/games/festoon.c (revision 7d7728c9ff780bb29e70ac5c0f1bb4c0d6187a9b)
1 #include <u.h>
2 #include <libc.h>
3 #include <stdio.h>
4 
5 #define R rand()&32767
6 #define T 0.125
7 #define CHOOSE(x) (x[(R)%(sizeof x / sizeof x[0])])
8 #define EQ(a,b) (strcmp(a,b)==0)
9 #define LAST(x) (x[strlen(x)-1])
10 #define VOWEL(x) (x=='a'||x=='e'||x=='i'||x=='o'||x=='u')
11 #define N 8
12 
13 typedef struct xyz {
14 	char           *type;
15 	union {
16 		struct xyz     *x[N];
17 		char           *s[N];
18 	}               list;
19 }              *X, XX;
20 typedef struct {
21 	char           *number, *ending, *tense, *an, *unspec, *passive;
22 }              *E, EE;
23 
24 char           *tense(), *number();
25 char            buff[1000];
26 int             io;
27 int             flag;
28 int		eqn=0, tbl=0, pic=0;
29 double          makeup = -1.;
30 
31 X np(E);
32 X aux(E);
33 X passive(E);
34 X passprep(void);
35 X vp(E);
36 X art(E);
37 X modal(E);
38 X perf(E);
39 X prog(E);
40 X verb(E);
41 X noun(E);
42 X nounal(E);
43 char *prefix(void);
44 char *root(void);
45 int prob(double);
46 char *tense(void);
47 char *number(void);
48 X getxx(void);
49 X verbal(E);
50 X adverb(void);
51 X adjective(void);
52 X adjph(E);
53 X prep(void);
54 X comp(E);
55 X advp(E);
56 X vprep(void);
57 E getenvq(void);
58 X comma(E);
59 X conjadv(void);
60 X lconjadv(void);
61 X conjsub(void);
62 X lconjsub(void);
63 X conj(void);
64 X nomz(void);
65 X equation();
66 X turgid(E);
67 void pr(X);
68 void out(char *);
69 void caps(void);
70 void abo(void);
71 char *splitup(char *);
72 
73 X
74 nomq(E env) {
75 	X               v = getxx();
76 	v->type = "-nomq";
77 	if (EQ(env->number, "sing")) {
78 		if (EQ(tense(), "past"))
79 			v->list.s[0] = "there was";
80 		else
81 			v->list.s[0] = "there is";
82 	} else {
83 		if (EQ(tense(), "past"))
84 			v->list.s[0] = "there were";
85 		else
86 			v->list.s[0] = "there are";
87 	}
88 	if (prob(0.2))
89 		v->list.s[1] = " not";
90 	return v;
91 }
92 
93 X
94 rel(void) {
95 	static char    *c[] = {"that", "which"};
96 	X               v = getxx();
97 	v->type = "-rel";
98 	v->list.s[0] = CHOOSE(c);
99 	return v;
100 }
101 
102 X
103 sent(E env) {
104 	X               sentv = getxx();
105 	sentv->type = "sent";
106 	if (prob(0.09)) {
107 		env->unspec = "";
108 		sentv->list.x[1] = np(env);
109 		sentv->list.x[3] = aux(env);
110 		sentv->list.x[4] = vp(env);
111 		sentv->list.x[0] = nomq(env);
112 		sentv->list.x[2] = rel();
113 		return sentv;
114 	}
115 	sentv->list.x[0] = np(env);
116 	sentv->list.x[1] = aux(env);
117 	sentv->list.x[2] = vp(env);
118 	return sentv;
119 }
120 
121 X
122 nomy(void) {
123 	X               v = getxx();
124 	v->type = "-nomq";
125 	v->list.s[0] = "the fact that";
126 	return v;
127 }
128 
129 X
130 np(env)
131 	E               env;
132 {
133 	X               npv = getxx();
134 	EE              nenv;
135 	static EE       empty;
136 	npv->type = "np";
137 	if (prob(0.025)) {
138 		nenv = empty;
139 		npv->list.x[0] = nomy();
140 		npv->list.x[1] = sent(&nenv);
141 		if (env->number == 0)
142 			env->number = "sing";
143 		return npv;
144 	}
145 	npv->list.x[1] = nounal(env);
146 	npv->list.x[0] = art(env);
147 	return npv;
148 }
149 
150 X
151 aux(E env) {
152 	X               auxv = getxx();
153 	int             i = 0;
154 	auxv->type = "aux";
155 	if (env->tense == 0)
156 		env->tense = env->ending = tense();
157 	if (prob(0.25))
158 		auxv->list.x[i++] = modal(env);
159 	if (prob(0.25))
160 		auxv->list.x[i++] = perf(env);
161 	if (prob(0.25))
162 		auxv->list.x[i++] = prog(env);
163 	USED(i);
164 	return auxv;
165 }
166 
167 X
168 passive(env)
169 	E               env;
170 {
171 	X               v = getxx();
172 	v->type = "-passive";
173 	if (env->tense == 0)
174 		env->tense = env->ending = tense();
175 	if (env->number == 0)
176 		env->number = number();
177 	if (EQ(env->ending, "modal"))
178 		v->list.s[0] = "be";
179 	else if (EQ(env->ending, "-en"))
180 		v->list.s[0] = "been";
181 	else if (EQ(env->ending, "-ing"))
182 		v->list.s[0] = "being";
183 	else {
184 		if (EQ(env->tense, "past"))
185 			v->list.s[0] = EQ(env->number, "sing") ? "was" : "were";
186 		else
187 			v->list.s[0] = EQ(env->number, "sing") ? "is" : "are";
188 	}
189 	env->passive = env->ending = "pass";
190 	return v;
191 }
192 
193 X
194 passprep(void) {
195 	X               v = getxx();
196 	v->type = "-passprep";
197 	v->list.s[0] = "by";
198 	return v;
199 }
200 
201 X
202 vp(env)
203 	E               env;
204 {
205 	X               vpv = getxx();
206 	int             i = 0;
207 	vpv->type = "vp";
208 	if (prob(0.5))
209 		vpv->list.x[i++] = passive(env);
210 	vpv->list.x[i++] = verbal(env);
211 	vpv->list.x[i++] = comp(env);
212 	if (prob(0.10))
213 		vpv->list.x[i++] = advp(env);
214 	USED(i);
215 	return vpv;
216 }
217 
218 X
219 art(env)
220 	E               env;
221 {
222 	static char    *aspecsg[] = {"the", "the", "the", "the", "the", "this", "this", "that"};
223 	static char    *aspecpl[] = {"the", "the", "the", "the", "the", "these", "those"};
224 	static char    *aunssg[] = {"a", "a", "a", "a", "a", "a", "a", "much", "each", "any"};
225 	static char    *aunspl[] = {"some", "a few", "a couple", "several", "many", "all",
226 		"no",
227 		"an undue number of",
228 	"a number of"};
229 	X               artv = getxx();
230 	artv->type = "-art";
231 	if (env->number == 0)
232 		env->number = number();
233 	if (env->unspec == 0 && prob(0.33)) {
234 		if (EQ(env->number, "sing"))
235 			artv->list.s[0] = CHOOSE(aspecsg);
236 		else
237 			artv->list.s[0] = CHOOSE(aspecpl);
238 	} else if (prob(0.50) || env->an && EQ(env->number, "sing")) {
239 		if (EQ(env->number, "sing"))
240 			artv->list.s[0] = env->an ? "a" : CHOOSE(aunssg);
241 		else
242 			artv->list.s[0] = CHOOSE(aunspl);
243 		if (env->an && EQ(artv->list.s[0], "all"))
244 			artv->list.s[0] = "";
245 	} else
246 		artv->list.s[0] = "";
247 	env->unspec = 0;
248 	if (env->an && EQ(env->an, "an") && EQ(artv->list.s[0], "a"))
249 		artv->list.s[0] = "an";
250 	env->an = 0;
251 	return artv;
252 }
253 
254 X
255 modal(env)
256 	E               env;
257 {
258 	static char    *pres[] = {"can", "may", "must", "shall", "will"};
259 	static char    *past[] = {"could", "might", "should", "would"};
260 	X               modalv = getxx();
261 	modalv->type = "-modal";
262 	if (env->tense == 0)
263 		env->tense = env->ending = tense();
264 	if (EQ(env->ending, "pres"))
265 		modalv->list.s[0] = CHOOSE(pres);
266 	else
267 		modalv->list.s[0] = CHOOSE(past);
268 	env->ending = "modal";
269 	return modalv;
270 }
271 
272 X
273 perf(env)
274 	E               env;
275 {
276 	X               perfv = getxx();
277 	perfv->type = "-perf";
278 	if (env->tense == 0)
279 		env->tense = env->ending = tense();
280 	if (env->number == 0)
281 		env->number = number();
282 	if (EQ(env->ending, "past")) {
283 		perfv->list.s[0] = "had";
284 	} else if (EQ(env->ending, "pres")) {
285 		if (EQ(env->number, "sing"))
286 			perfv->list.s[0] = "had";
287 		else
288 			perfv->list.s[0] = "have";
289 	} else
290 		perfv->list.s[0] = "have";
291 	env->ending = "-en";
292 	return perfv;
293 }
294 
295 X
296 prog(env)
297 	E               env;
298 {
299 	X               progv = getxx();
300 	progv->type = "-prog";
301 	if (env->tense == 0)
302 		env->tense = env->ending = tense();
303 	if (env->number == 0)
304 		env->number = number();
305 	if (EQ(env->ending, "pres")) {
306 		if (EQ(env->number, "sing"))
307 			progv->list.s[0] = "is";
308 		else
309 			progv->list.s[0] = "are";
310 	} else if (EQ(env->ending, "past")) {
311 		if (EQ(env->number, "sing"))
312 			progv->list.s[0] = "was";
313 		else
314 			progv->list.s[0] = "were";
315 	} else if (EQ(env->ending, "-en")) {
316 		progv->list.s[0] = "been";
317 	} else if (EQ(env->ending, "modal")) {
318 		progv->list.s[0] = "be";
319 	}
320 	env->ending = "-ing";
321 	return progv;
322 }
323 
324 X
325 verb(env)
326 	E               env;
327 {
328 	/* they pres, he pres, they past, they perf, they prog, they pass */
329 	static char    *ends[][6] = {{"ate", "ates", "ated", "ated", "ating", "ated"},
330 	{"en", "ens", "ened", "ened", "ening", "ened"},
331 	{"esce", "esces", "esced", "esced", "escing", "esced"},
332 	{"fy", "fies", "fied", "fied", "fying", "fied"},
333 	{"ize", "izes", "ized", "ized", "izing", "ized"}};
334 	X               verbv = getxx();
335 	int             i;
336 	verbv->type = "-verb";
337 	if (env->tense == 0)
338 		env->tense = env->ending = tense();
339 	if (env->number == 0)
340 		env->number = number();
341 	if (0 && prob(0.1) && EQ(env->tense, env->ending)) {
342 		if (EQ(env->number, "sing")) {
343 			if (EQ(env->tense, "pres"))
344 				verbv->list.s[0] = "is";
345 			else
346 				verbv->list.s[0] = "was";
347 		} else {
348 			if (EQ(env->tense, "pres"))
349 				verbv->list.s[0] = "are";
350 			else
351 				verbv->list.s[0] = "were";
352 		}
353 	} else {
354 		verbv->list.s[0] = prefix();
355 		verbv->list.s[1] = root();
356 		if (EQ(env->ending, "pres") && EQ(env->number, "sing"))
357 			i = 1;
358 		else if (EQ(env->ending, "pres") || EQ(env->ending, "modal"))
359 			i = 0;
360 		else if (EQ(env->ending, "past"))
361 			i = 2;
362 		else if (EQ(env->ending, "-en"))
363 			i = 3;
364 		else if (EQ(env->ending, "-ing"))
365 			i = 4;
366 		else if (EQ(env->ending, "pass"))
367 			i = 5;
368 		else
369 			i = 0;
370 		verbv->list.s[2] = ends[R % (sizeof ends / sizeof *ends)][i];
371 	}
372 	env->ending = 0;
373 	return verbv;
374 }
375 
376 static char    *nounlist[] = {"final completion",
377 	"final ending", "final outcome",
378 	"adaptation", "appearance", "argument", "circumstance",
379 	"confession", "confidence", "delimitation", "dilution",
380 	"dissertation", "distribution", "duplication",
381 	"entertainment", "equipment", "evolution",
382 	"existence", "expression", "generation", "impression",
383 	"integration", "interaction", "investment", "judgment",
384 	"population", "provision", "solution", "statement",
385 	"tradition", "transmission",
386 	"final result", "added increment", "assistance",
387 	"beneficial assistance", "mutual cooperation",
388 	"projection", "future projection",
389 	"capability", "conjecture", "consensus of opinion",
390 	"general consensus", "absence", "deficiency",
391 	"inadequacy", "insufficience", "insufficiency",
392 	"growing importance", "renewed emphasis",
393 	"renewed interest", "changing behavior",
394 	"critical thinking", "careful thinking",
395 	"comprehensive survey", "high standard",
396 	"basic foundation", "system testing",
397 	"serious discussion", "serious concern",
398 	"organizational framework", "prototype model",
399 	"uniform nomenclature", "greater cooperation",
400 	"uniform consistency", "early expectation",
401 	"standardization", "great similarity",
402 	"shortage", "presence", "sufficiency",
403 	"consequent result", "construct", "disutility",
404 	"early beginning", "emotional feeling", "endeavor",
405 	"authorization", "order of magnitude", "preference",
406 	"impact", "joint cooperation", "joint partnership",
407 	"main essential", "methodology", "modification",
408 	"necessary requisite", "past history", "situation",
409 	"effectuation", "clarification", "new doubt",
410 	"policy", "encouragement", "preparation",
411 	"criterion", "material", "interest", "acceptance",
412 	"rejection", "publication", "circulation",
413 	"protection", "insurance",
414 	"assignment", "identification",
415 	"submission", "request",
416 	"guidance", "correspondence", "inclusion",
417 	"attachment", "assumption",
418 	"recommendation", "prescription", "approval",
419 	"discretion", "responsibility", "relevance",
420 	"issuance", "termination", "total effect",
421 	"deleterious effect", "consolidation",
422 	"aggregation", "definiteness", "commencement",
423 	"actual experience", "experience",
424 	"combination", "accord", "filing",
425 	"idea", "abstraction", "method", "procedure",
426 	"complaint", "maintenance", "finance", "travel",
427 	"purchase", "repair", "routine",
428 	"development", "cancellation",
429 	"partitioning", "development effort",
430 	"project", "automation", "multilevel architecture",
431 	"multilevel heirarchy", "data stream",
432 	"objective",
433 	"individual assignment", "mode of operation",
434 	"clear community", "attendant interest",
435 	"task division", "well defined interfacing",
436 	"team report", "meeting time", "effective use",
437 	"friction",
438 	"major objective", "ownership",
439 	"overall project time constraint",
440 	"functional division", "requirements analysis",
441 	"code development", "charter",
442 	"requirements definition", "vertical division",
443 	"broad range", "strong feeling",
444 	"considerable latitude", "overall project constraint",
445 	"sufficient resource", "assigned task", "expectation",
446 	"critical aspect", "clear understanding",
447 	"computing load", "clean interfacing", "natural basis",
448 	"team activity", "team responsibility",
449 	"main function", "predominant portion",
450 	"work plan", "major breakpoint", "work module",
451 	"achievable accuracy", "supplementary work",
452 	"field version", "internal establishment",
453 	"internal communication", "development progress",
454 	"internal meeting", "experience level",
455 	"high level autonomy", "adherence",
456 	"feasibility demonstration", "persistent problem",
457 	"internal objective", "idea sharing",
458 	"improved performance", "unfamiliar methodology",
459 	"new methodology", "development experience",
460 	"module specification", "good progress",
461 	"optimal number", "natural division",
462 	"good relationship", "cross attendance",
463 	"attendance", "necessary communication",
464 	"evolving organization", "basic principle",
465 	"complete revision", "general information",
466 	"primary objective", "load-carrying capacity",
467 	"necessary revision", "major change",
468 	"clarified interpretation", "subsequent attempt",
469 	"basic objective", "full utilization",
470 	"practical consideration",
471 	"proportionate quantity", "substantial change",
472 	"database design", "unified framework",
473 	"customer service", "strong interest",
474 	"unified description", "necessary background information",
475 	"provisioning", "physical coverage", "general observation",
476 	"new technology", "validity determination",
477 	"relation", "regulation", "verification",
478 	"impediment", "portal", "practice", "premise",
479 	"basis", "movement", "question",
480 	"issue", "input", "output", "observation",
481 	"input", "output", "input", "output",
482 	"mechanization", "function", "evaluation",
483 	"result", "further consideration", "category",
484 	"performance indicator", "early warning",
485 	"analysis purpose", "measurement", "replacement",
486 	"utilitarian purpose",
487 	"quota", "proposed enhancement", "enhancement",
488 	"interfacing", "team organization", "module",
489 	"guideline", "continuing study",
490 	"required assistance", "major advance",
491 	"proposal", "hierarchy",
492 	"current view", "refinement", "activity",
493 	"external description", "tight schedule pressure",
494 	"internal conflict", "internal issue",
495 	"reasonable compromise", "next phase",
496 	"goal", "time constraint", "constraint",
497 	"outcome", "important outcome",
498 	"considerable experience", "intelligent choice",
499 	"deliverable documentation", "discussion",
500 	"timely delivery", "design issue", "large quantity",
501 	"general environment", "protocol",
502 	"transitioning", "modeling",
503 	"considerable difficulty", "abstract interfacing",
504 	"data structure", "consideration", "difficulty",
505 	"statistical accuracy",
506 	"agenda", "technique", "reordering",
507 	"reauthorization", "current proposal",
508 	"significant change", "criteria", "validation",
509 	"validity",
510 	"terminology", "current understanding",
511 	"incorporation", "staffing impact",
512 	"schedule impact", "cost tradeoff",
513 	"system architecture",
514 	"adequate capacity", "centralization",
515 	"current task", "system deployment",
516 	"attendant uncertainty", "process",
517 	"potential usefulness", "proposed method",
518 	"basic assumption", "anomaly",
519 	"available data", "potential improvement",
520 	"registration", "exemption", "exception",
521 	"follow-up", "service",
522 	"installation", "construction", "necessity",
523 	"occasion", "instrumentation", "disposal",
524 	"attractiveness",
525 	"convenience", "sponsoring",
526 	"signification", "meaningfulness",
527 	"significantness", "individuality",
528 	"specification", "determination", "affirmation",
529 	"recruitment", "supervision", "management",
530 	"oversight", "overview", "environment",
531 	"effectation", "circumvention", "location",
532 	"execution", "effectiveness", "consciousness",
533 	"notation", "confirmation", "restriction",
534 	"organization", "realization", "actification",
535 	"activation", "reification", "beginning", "conclusion",
536 	"ending", "finishing", "teamwork", "motivation",
537 	"attitude", "good attitude",
538 	"progress", "milestone", "deadline", "schedule",
539 	"allocation", "resource", "command", "concern",
540 	"time", "time frame", "reality",
541 	"behaviour", "ability", "advent", "increment",
542 	"opportunity", "accomplishment", "aggregate",
543 	"analysis", "totality", "matter",
544 	"date", "duration", "centrality",
545 	"proximity", "collection", "elimination",
546 	"investigation", "opinion", "debate",
547 	"decision", "benefit", "difference", "discontinuity",
548 	"fabrication", "plan", "chart", "forecast",
549 	"simplicity", "simplification", "maximization",
550 	"minimization", "direction",
551 	"agreement",
552 	"amount", "quantity", "quality", "essence",
553 	"description", "violation", "purpose",
554 	"primary purpose", "automatic control", "redefinition",
555 	"uniform emphasis", "study activity", "work activity",
556 	"concept stage", "concept activity",
557 	"possible potential", "summarization", "system function",
558 	"rationale", "significant enhancement", "diverse need",
559 	"diverse organization", "comprehensive plan", "interim",
560 	"functional overview", "system configuration",
561 	"configuration", "failure", "quantitative result",
562 	"major obstacle", "conception",
563 	"effectiveness", "final evaluation",
564 	"interrelationship", "functional requirement",
565 	"system philosophy", "verbal interchange",
566 	"perceived inadequacy", "primary emphasis",
567 	"intermingling", "cooperation", "partnership",
568 	"adjustment", "application", "implementation",
569 	"contact", "mention", "power",
570 	"nature", "invention", "importance",
571 	"ground", "reason", "permission", "size",
572 	"report", "documentation", "priority",
573 	"pursuance", "recurrance", "resumption",
574 	"presupposition", "continuance",
575 	"substantiation", "success", "action", "truth",
576 	"past experience", "greater acceptability",
577 	"organizational structure", "clear distinction",
578 	"clear definition",
579 	"significant use", "unmet need", "centralized organization",
580 	"vague concept", "negative impact", "detrimental effect",
581 	"modularization", "submodularization",
582 	"effect", "consistancy",
583 	"inconsistancy", "completion", "utilization",
584 	"reference", "doubt", "evidence",
585 	"viewpoint",
586 	"actual fact",
587 	"true fact", "underlying purpose", "viable alternative"};
588 
589 static char    *adjlist[] = {"concrete", "abstract", "procedural",
590 	"real", "ideal", "functional", "prototype",
591 	"effective", "capable", "incremental",
592 	"perceived", "associated", "interdepartmental",
593 	"diverse", "characteristic", "worst-case",
594 	"qualitative", "fully automatic", "candidate",
595 	"consensual", "consequential", "conjectural",
596 	"constructive", "initial", "cooperative",
597 	"essential", "methodological", "requisite",
598 	"historical", "situational", "political",
599 	"prepared", "material", "defined", "well defined",
600 	"organizational", "projected", "overall",
601 	"accepted", "rejected", "corresponding",
602 	"committed", "environmental", "typical", "working", "timely",
603 	"growing", "unprecedented", "new", "renewed", "fresh",
604 	"rapid", "changing", "careful", "comprehensive", "broad",
605 	"massive", "huge", "enormous",
606 	"evaluated", "discresionary",
607 	"durable", "beneficial",
608 	"maximal", "tremendous", "minimal",
609 	"on-site", "standardized", "standard",
610 	"powerful", "natural", "necessary",
611 	"reasonable", "successful",
612 	"doubtful", "dubious", "certain",
613 	"unified", "different", "similar", "utilitarian",
614 	"realizable", "organizable", "motivated",
615 	"topical", "valuable", "feasible",
616 	"intelligent", "deliverable", "nontrivial",
617 	"worthwhile", "complicated",
618 	"organized", "organizing", "progressing",
619 	"schedulable", "resourceful", "commanding",
620 	"important", "allocatable", "temporal",
621 	"ponderable", "understandable", "comprehendable",
622 	"past", "present", "future",
623 	"obvious", "considerable", "finished", "completed",
624 	"unique", "abovementioned",
625 	"major", "minor", "tendentious", "activating",
626 	"actual", "added", "adequate", "affordable",
627 	"analyzable", "additional", "intuitive",
628 	"artificial", "good", "better",
629 	"worse", "bad", "basic", "fundamental", "brief",
630 	"general", "very unique", "extreme", "most unique",
631 	"central", "proximate", "approximate", "collected",
632 	"conductable", "comtemplatable",
633 	"continuing", "demonstrable", "desirable",
634 	"correctable", "foreseeable",
635 	"discontinued", "early", "beginning",
636 	"effectuated", "elucidated", "emotional",
637 	"enclosed", "enthused", "entire", "exact",
638 	"experimental", "fearful", "final",
639 	"following", "informative",
640 	"full", "complete", "indicated", "authorized",
641 	"modularized", "submodularized",
642 	"particular", "preferred", "satisfactory",
643 	"measurable", "referenced", "literal",
644 	"modified",
645 	"correct", "prioritized", "prolonged",
646 	"regrettable", "apparent",
647 	"continued", "subsequent", "sufficient",
648 	"suggestive", "true", "ultimate", "separate",
649 	"purposeful", "regarded", "resulting",
650 	"doubtful", "evident", "interesting", "worthy",
651 	"uniform", "vital", "viable",
652 	"worthwhile", "alternative",
653 	"sophisticated", "employed",
654 	"clear", "lucid", "simple", "perspicuous",
655 	"incomplete", "concerned"};
656 
657 X
658 noun(env)
659 	E               env;
660 {
661 	static char    *suff[] = {"ion", "sion", "tion", "age",
662 		"ness", "ment", "ure",
663 		"ity", "iety", "ty", "ence", "ency", "ance",
664 		"ancy", "tude", "hood", "ture", "ate", "art", "ard",
665 		"ism", "ine", "stress", "trix", "ess",
666 		"dom", "ship", "eer", "ster", "ant", "ent", "ary",
667 		"ery", "ory", "ette", "let", "ling", "ule", "kin",
668 		"ar", "or", "ist", "fulness",
669 		"kin", "cule", "icle", "y", "ability", "iosos"};
670 	X               nounv = getxx();
671 	int             i = 0;
672 	nounv->type = "-noun";
673 	if (env->number == 0)
674 		env->number = number();
675 	if (prob(makeup)) {
676 		if (prob(0.05)) {
677 			nounv->list.s[i++] = CHOOSE(adjlist);
678 			nounv->list.s[i++] = "ness";
679 		} else
680 			nounv->list.s[i++] = CHOOSE(nounlist);
681 	} else {
682 		nounv->list.s[i++] = prefix();
683 		nounv->list.s[i++] = root();
684 		nounv->list.s[i++] = CHOOSE(suff);
685 	}
686 	if (EQ(env->number, "plural")) {
687 		if (LAST(nounv->list.s[i - 1]) == 's')
688 			nounv->list.s[i] = "es";
689 		else if (LAST(nounv->list.s[i - 1]) == 'y')
690 			nounv->list.s[i] = "ies";
691 		else
692 			nounv->list.s[i] = "s";
693 	}
694 	return nounv;
695 }
696 
697 X
698 adjval(void) {
699 	X               adjvalv = getxx();
700 	int             i = 0;
701 	adjvalv->type = "adjval";
702 	if (prob(0.25)) {
703 		adjvalv->list.x[i++] = adverb();
704 	}
705 	do {
706 		adjvalv->list.x[i++] = adjective();
707 	} while (i < N - 1 && prob(0.25));
708 	return adjvalv;
709 }
710 
711 X
712 nounal(env)
713 	E               env;
714 {
715 	X               nounalv = getxx();
716 	int             i = 0;
717 	X               p;
718 	nounalv->type = "nounal";
719 	if (prob(0.15)) {
720 		nounalv->list.x[i++] = adjval();
721 	}
722 	nounalv->list.x[i++] = noun(env);
723 	if (prob(0.15)) {
724 		nounalv->list.x[i] = adjph(env);
725 	}
726 	env->an = "a";
727 	for (p = nounalv; p->type[0] != '-'; p = p->list.x[0]);
728 	for (i = 0; p->list.s[i]; i++) {
729 		if (p->list.s[i][0] == 0)
730 			continue;
731 		if (VOWEL(p->list.s[i][0])) {
732 			env->an = "an";
733 		}
734 		break;
735 	}
736 	return nounalv;
737 }
738 
739 char           *
740 prefix(void) {
741 	static char    *pref[] = {
742 		"amb", "ambi", "super", "hyper", "an", "tra", "trans", "post", "palim",
743 		"omni", "pan", "circ", "circum", "peri", "a", "ab", "abs", "de", "apo",
744 		"re", "ana", "mal", "ante", "pre", "fore", "pro", "infra", "para",
745 		"inter", "ultra", "extra", "trans", "cata", "de", "oct", "octa",
746 		"octo", "equi", "pseudo", "prim", "prot", "proto", "pent", "penta",
747 		"quin", "quint", "quinque", "pro", "tetr", "tetra", "quad", "quadr",
748 		"quadri", "quartet", "off", "bene", "hemi", "demi", "semi", "crypto",
749 		"cent", "centi", "hecto", "en", "em", "in", "im", "intro", "be",
750 		"macro", "poly", "mult", "multi", "neo", "nona", "novem", "ennea",
751 		"in", "un", "im", "il", "ir", "non", "a", "nil", "paleo", "mon", "mono",
752 		"uni", "e", "ex", "ec", "ef", "super", "supr", "sur", "hyper", "vic",
753 		"vice", "hept", "hepta", "sept", "septe", "septem", "septi", "hex",
754 		"hexa", "sex", "dis", "deca", "deka", "deci", "kilo", "mill", "milli",
755 		"tri", "per", "dia", "ad", "com", "di", "amphi", "bi", "bin", "bis",
756 	"sub", "hypo", "epi", "eu", "holo"};
757 	if (prob(0.65))
758 		return "";
759 	return CHOOSE(pref);
760 }
761 
762 char           *
763 root(void) {
764 	static char    *root[] = {
765 		"pan", "omni", "arch", "zo", "rog", "rogat", "cred", "flect", "flex",
766 		"test", "hem", "hemato", "nasc", "nat", "bibl", "fer", "voc", "port", "lat",
767 		"fortuna", "ped", "chrom", "vinc", "vict", "crea", "cise", "mort", "mors",
768 		"necr", "claim", "clam", "hetero", "pel", "puls", "vac", "iso", "phobe",
769 		"phobia", "prim", "prime", "flu", "flux", "sequ", "liber", "liver", "theo",
770 		"magna", "medi", "man", "manu", "pen", "pend", "pens", "eu", "capit",
771 		"iatr", "aud", "aus", "cor", "cord", "cour", "grav", "ten", "tain",
772 		"tent", "sacr", "sacer", "heiro", "sanct", "cide", "mega", "ultima",
773 		"ridi", "risi", "leg", "jus", "jur", "nom", "duc", "duct", "duce",
774 		"bio", "viv", "vivi", "vita", "lus", "lum", "luc", "photo",
775 		"min", "philo", "phile", "phila", "amic", "anthrop", "poly", "multi",
776 		"fac", "fact", "fic", "fect", "meter", "psych", "mod", "mot", "mov",
777 		"nov", "neo", "neg", "uni", "alter", "ali", "idio", "pop", "dem",
778 		"demo", "lic", "licit", "poten", "posse", "potes", "mem", "simul",
779 		"arch", "homo", "mar", "mer", "vis", "vid", "scope", "auto", "mitt",
780 		"miss", "ac", "acr", "brev", "clud", "clus", "dorm", "micro", "aster",
781 		"astro", "rect", "recti", "forc", "fort", "path", "cap", "cep", "cept",
782 		"put", "tempo", "tempor", "dent", "dont", "ver", "veri",
783 		"feder", "fide", "feal", "fid", "cosm", "migra", "hydro", "aqu",
784 		"endo", "gyn", "logo", "opus", "oper", "graph", "scrib", "scrip",
785 	"mis", "miso", "anni", "annu", "enni", "ced", "cede", "ceed", "cess"};
786 	return CHOOSE(root);
787 }
788 
789 prob(f)
790 	double          f;
791 {
792 	return (R) < (f * 32767.0);
793 }
794 
795 char           *
796 tense()
797 {
798 	return prob(0.5) ? "pres" : "past";
799 }
800 
801 char           *
802 number()
803 {
804 	return prob(0.25) ? "plural" : "sing";
805 }
806 
807 X
808 getxx()
809 {
810 	X               rv;
811 	static XX       empty;
812 
813 	rv = (X) malloc(sizeof *rv);
814 	if (rv == 0) {
815 		fprintf(stderr, "festoon: outa space\n");
816 		exits("space");
817 	}
818 	*rv = empty;
819 	return rv;
820 }
821 
822 X
823 verbal(env)
824 	E               env;
825 {
826 	X               verbalv = getxx();
827 	int             i = 0;
828 	verbalv->type = "verbal";
829 	if (prob(0.25))
830 		verbalv->list.x[i++] = adverb();
831 	verbalv->list.x[i] = verb(env);
832 	return verbalv;
833 }
834 
835 static char    *advlist[] = {"absolutely", "functionally",
836 	"accordingly", "broadly", "actionably", "actually",
837 	"additionally",
838 	"ambiguously", "amply",
839 	"analogously",
840 	"aperiodically",
841 	"apparently", "appreciably",
842 	"appropriately", "approximately",
843 	"arbitrarily",
844 	"associatively",
845 	"automatically",
846 	"awfully",
847 	"axiomatically",
848 	"badly", "barely", "basically",
849 	"beneficially",
850 	"blatantly",
851 	"capably", "carefully", "carelessly",
852 	"casually", "causally", "cautiously",
853 	"centrally", "certainly",
854 	"cheaply", "cleanly",
855 	"closely", "coarsely", "cognizantly",
856 	"coincidentally", "collectively", "collaterally",
857 	"comparably",
858 	"competently", "completely", "comprehensibly",
859 	"concededly", "conceivably",
860 	"concisely", "conclusively", "concretely",
861 	"concurrently", "conjecturally",
862 	"currently",
863 	"conscientously", "consequently", "consequentially",
864 	"consistently", "constantly",
865 	"contemporaneuosly", "constructively",
866 	"continually", "continuously", "contractually",
867 	"contrarily", "contributatively", "conveniently",
868 	"conventionally",
869 	"correctively",
870 	"correctly",
871 	"crudely",
872 	"curiously",
873 	"decidedly",
874 	"deeply",
875 	"deficiently", "demandingly",
876 	"dependably", "desireably",
877 	"determinately", "diagnostically",
878 	"differentially", "differently",
879 	"directly", "discernibly",
880 	"distinctly", "doubtfully", "dramatically",
881 	"dynamically",
882 	"economically",
883 	"effecaciously", "efficiently",
884 	"elegantly",
885 	"emphatically", "encouragingly",
886 	"endlessly", "endurably",
887 	"entirely", "epistomologically",
888 	"functionally", "immediately",
889 	"equably", "equally", "equitably", "erroneously",
890 	"esoterically", "eternally", "evenly", "eventfully",
891 	"eventually", "evidently",
892 	"exceedingly", "exactly", "excellently",
893 	"exceptionally", "excessively", "exclusively",
894 	"experimentally",
895 	"explicitly", "extremely",
896 	"factually", "faithfully",
897 	"faultlessly", "feasibly",
898 	"finitely", "firmly", "forcefully",
899 	"formally", "formerly", "frankly", "freely",
900 	"frugally", "fully", "generally",
901 	"globally", "gradually",
902 	"harmlessly",
903 	"helpfully",
904 	"highly", "homogeneously",
905 	"hopefully",
906 	"ideally", "identically", "ideologically",
907 	"idiomatically", "idiosyncratically", "idly",
908 	"imaginably", "immaterially", "immensely",
909 	"impartially", "imperceptably", "imperfectly", "importantly",
910 	"improperly", "imprudently", "inaccurately", "inappropriately",
911 	"accurately",
912 	"inclusively", "incompletely", "incorrectly",
913 	"increasingly", "independently",
914 	"indirectly", "ineffectively", "ineffectually", "inefficiently",
915 	"infallibly", "instantaneously", "instantly",
916 	"insufficiently", "internally", "likely", "only",
917 	"invaluably", "inversely", "irrelevantly", "irrespectively",
918 	"largely", "lastly", "legitimately", "literally",
919 	"locally", "loosely", "manageably", "markedly",
920 	"memorably", "mildly", "mindfully", "moderately",
921 	"momentarily", "naturally", "needfully", "needlessly",
922 	"nominally", "normally", "objectively", "occasionally",
923 	"temporarily",
924 	"officially", "oppositely", "ordinarily", "ostensibly",
925 	"partially", "permissibly",
926 	"personally", "pertinently",
927 	"physically", "plainly", "plainly",
928 	"pleasingly", "politically",
929 	"potentially", "predictively",
930 	"predominantly", "prematurely", "preparedly", "presently",
931 	"previously", "primarily",
932 	"primely", "principally", "problematically",
933 	"productively", "promptly", "proportionately",
934 	"provably", "purely", "quickly", "radically", "randomly", "recently",
935 	"repeatedly", "secondarily", "separately",
936 	"usually", "specifically",
937 	"redundantly", "regardlessly", "reliably",
938 	"remarkably", "remotely", "respectively",
939 	"probably",
940 	"robustly", "seemingly",
941 	"sensibly", "singularly", "steadily",
942 	"strikingly", "substantially", "successfully",
943 	"supposedly", "systematically", "understandably",
944 	"necessarily", "unfortunately",
945 	"unnecessarily", "unmistakably", "usefully", "weakly"};
946 
947 X
948 adverb(void) {
949 	static char    *wordy[] = {"very ", "extremely ", "generally ",
950 		"reasonably ", "fundamentally ", "essentially ", "particularly ",
951 		"very ",
952 		"very ", "very ",
953 		"very ", "very ",
954 		"very ", "very ",
955 		"very ", "very ",
956 		"very ", "very ",
957 		"very ", "very ",
958 		"very ", "very ",
959 		"entirely ",
960 		"rather ", "fairly ", "relatively ", "comparatively ",
961 		"moderately ",
962 		"totally ", "very ", "quite "};
963 	static char    *suff[] = {"wardly", "ably", "wisely",
964 		"ably", "ily", "ly", "ly", "ly"};
965 
966 	X               adverbv = getxx();
967 	int             i = 0;
968 
969 	adverbv->type = "-adverb";
970 	if (prob(0.150)) {
971 		adverbv->list.s[i] = prob(.5) ? "simply" : "easily";
972 		return adverbv;
973 	}
974 	if (prob(0.4))
975 		adverbv->list.s[i++] = CHOOSE(wordy);
976 	if (prob(makeup))
977 		adverbv->list.s[i] = CHOOSE(advlist);
978 	else {
979 		adverbv->list.s[i++] = prefix();
980 		adverbv->list.s[i++] = root();
981 		adverbv->list.s[i] = CHOOSE(suff);
982 	}
983 	return adverbv;
984 }
985 
986 X
987 adjective(void) {
988 	static char    *suff[] = {"ive", "ful", "ous", "some", "oid",
989 	"ine", "esque", "en", "an",
990 	"ile", "able", "ible", "istic", "ic",
991 	"an", "ian", "ish", "ite", "al", "less"};
992 	X               adjv = getxx();
993 	int             i = 0;
994 
995 	adjv->type = "-adjective";
996 	if (prob(0.2)) {
997 		adjv->list.s[i++] = "not ";
998 		adjv->list.s[i++] = "un";
999 	}
1000 	if (prob(makeup)) {
1001 		adjv->list.s[i] = CHOOSE(adjlist);
1002 		return adjv;
1003 	}
1004 	adjv->list.s[i++] = prefix();
1005 	adjv->list.s[i++] = root();
1006 	adjv->list.s[i] = CHOOSE(suff);
1007 	return adjv;
1008 }
1009 
1010 X
1011 adjph(env)
1012 	E               env;
1013 {
1014 	X               adjv = getxx();
1015 	EE              nenv;
1016 	static EE       empty;
1017 	int             i = 0;
1018 	adjv->type = "adjph";
1019 	if (prob(0.25)) {
1020 		nenv = *env;
1021 		nenv.tense = 0;
1022 		adjv->list.x[i++] = rel();
1023 		adjv->list.x[i++] = aux(&nenv);
1024 		adjv->list.x[i] = vp(&nenv);
1025 		return adjv;
1026 	}
1027 	nenv = empty;
1028 	adjv->list.x[i++] = prep();
1029 	adjv->list.x[i] = np(&nenv);
1030 	return adjv;
1031 }
1032 
1033 static char    *preplist[] = {"across", "by", "in", "of",
1034 	"near", "under", "over",
1035 	"in back of", "below", "behind", "of", "of", "of", "of",
1036 	"centered around", "centered about",
1037 	"in close proximity to", "following after",
1038 	"in between", "in conflict with", "in conjunction with",
1039 	"in the area of", "in the neighborhood of", "in the proximity of",
1040 	"in the field of", "for the purpose of",
1041 	"giving rise to", "based upon", "being caused by",
1042 	"of", "of", "of", "of",
1043 	"being effectuated by", "being aggrevated by",
1044 	"being used with",
1045 	"being collected together with", "being combined together with",
1046 	"connected up to", "exhibiting a tendency towards",
1047 	"being facilitated by",
1048 	"being employed with",
1049 	"having a deleterious effect upon", "impacting",
1050 	"being joined together with", "being merged together with",
1051 	"in the vicinity of"};
1052 
1053 X
1054 prep(void) {
1055 	X               pv = getxx();
1056 	pv->type = "-prep";
1057 	pv->list.s[0] = CHOOSE(preplist);
1058 	return pv;
1059 }
1060 
1061 X
1062 comp(env)
1063 	E               env;
1064 {
1065 	X               v = getxx();
1066 	EE              nenv;
1067 	static EE       empty;
1068 	int             i = 0;
1069 	nenv = empty;
1070 	v->type = "comp";
1071 	if (0 && prob(0.001))
1072 		v->list.x[i++] = adjective();
1073 	else if (prob(0.1))
1074 		v->list.x[i++] = advp(&nenv);
1075 	else {
1076 		if (env->passive)
1077 			v->list.x[i++] = passprep();
1078 		v->list.x[i++] = np(&nenv);
1079 		env->passive = 0;
1080 	}
1081 	if (0 && prob(0.05))
1082 		v->list.x[i++] = adverb();
1083 	USED(i);
1084 	return v;
1085 }
1086 
1087 X
1088 advp(env)
1089 	E               env;
1090 {
1091 	X               v = getxx();
1092 	v->type = "advp";
1093 	v->list.x[0] = vprep();
1094 	v->list.x[1] = np(env);
1095 	return v;
1096 }
1097 
1098 static char    *vpreplist[] = {"to", "at", "by", "from", "with", "for"};
1099 
1100 X
1101 vprep(void) {
1102 	X               v = getxx();
1103 	v->type = "-vprep";
1104 	v->list.s[0] = CHOOSE(vpreplist);
1105 	return v;
1106 }
1107 
1108 E
1109 getenvq()
1110 {
1111 	static EE       empty;
1112 	E               v;
1113 	v = (E) malloc(sizeof *v);
1114 	if (v == 0) {
1115 		printf("outa room\n");
1116 		exits("room");
1117 	}
1118 	*v = empty;
1119 	return v;
1120 }
1121 
1122 X
1123 comma(env)
1124 	E               env;
1125 {
1126 	X               v = getxx();
1127 	static EE       empty;
1128 
1129 	v->type = "-comma";
1130 	v->list.s[0] = ",";
1131 	*env = empty;
1132 	return v;
1133 }
1134 
1135 static char    *conjadvlist[] = {"we believe", "naturally", "therefore",
1136 	"moreover", "obviously"};
1137 
1138 X
1139 conjadv(void) {
1140 	X               v = getxx();
1141 
1142 	v->type = "-conjadv";
1143 	v->list.s[0] = CHOOSE(conjadvlist);
1144 	return v;
1145 }
1146 
1147 static char    *lconjlist[] = {"therefore", "however", "nevertheless",
1148 	"consequently", "also", "in addition", "moreover",
1149 	"accordingly", "essentially", "presumably", "actually",
1150 	"basically", "importantly", "clearly", "obviously",
1151 	"needless to say", "as already stated",
1152 	"generally", "approximately", "presently",
1153 	"hopefully", "usually", "in the great majority of cases",
1154 	"seen in the above light", "most significantly",
1155 	"when the need arises",
1156 	"in a large number of cases", "after this is accomplished",
1157 	"in all cases",
1158 	"having been made aware concerning these matters",
1159 	"as an example of this", "as a consequence of this",
1160 	"as a matter of fact", "as is often the case",
1161 	"as of this date", "assuming that this is the case",
1162 	"at the present moment in time", "at this time",
1163 	"as a consequent result of this", "as a desireable benefit of this",
1164 	"if at all possible", "similarly", "in the same connection",
1165 	"in large measure", "in many cases", "in rare cases",
1166 	"in some cases", "in the interim", "in the last analysis",
1167 	"in light of these facts", "in the majority of instances",
1168 	"in the not too distant future", "in the same way as described above",
1169 	"in this case", "for all intents and purposes",
1170 	"to arrive at an approximation", "for this reason",
1171 	"for many reasons, then",
1172 	"as is often the case", "last but not least",
1173 	"later on", "on a few occasions", "on this occasion",
1174 	"in summary", "taking this into consideration",
1175 	"with this in mind",
1176 	"substantially", "ultimately"};
1177 
1178 X
1179 lconjadv(void) {
1180 
1181 	X               v = getxx();
1182 	v->type = "-lconjadv";
1183 	v->list.s[0] = CHOOSE(lconjlist);
1184 	return v;
1185 }
1186 
1187 X
1188 conjsub(void) {
1189 	static char    *conjsublist[] = {"although", "even though",
1190 		"despite the fact that",
1191 		"for the simple reason that",
1192 		"because", "due to the fact that", "since",
1193 		"whether or not",
1194 		"inasmuch as",
1195 	"as"};
1196 	X               v = getxx();
1197 	v->type = "-conjsub";
1198 	v->list.s[0] = CHOOSE(conjsublist);
1199 	return v;
1200 }
1201 
1202 static char    *lconjsublist[] = {"although", "even though",
1203 	"despite the fact that",
1204 	"because", "due to the fact that", "since",
1205 	"if", "anytime that", "in the case that",
1206 	"as a consequence of the fact that",
1207 	"as regards the fact that",
1208 	"as a desireable benefit of the fact that",
1209 	"with reference to the fact that",
1210 	"as long as",
1211 	"as an important essential of the fact that",
1212 	"in conjunction with the fact that",
1213 	"in the light of the fact that",
1214 	"if", "if", "if", "if",
1215 	"leaving out of consideration the fact that",
1216 	"just as",
1217 	"inasmuch as", "until such time as",
1218 	"as soon as", "being as", "in the same way as",
1219 	"with the exception of the fact that",
1220 	"notwithstanding the fact that",
1221 	"on the grounds that",
1222 	"on the basis of the fact that",
1223 	"persuant to the fact that",
1224 	"although it seems apparent that",
1225 	"with regard to the fact that",
1226 	"as can be seen from the fact that",
1227 	"as"};
1228 
1229 X
1230 lconjsub(void) {
1231 	X               v = getxx();
1232 	v->type = "-lconjsub";
1233 	v->list.s[0] = CHOOSE(lconjsublist);
1234 	return v;
1235 }
1236 
1237 static char    *conjlist[] = {"and", "but", "yet", "and", "and"};
1238 
1239 X
1240 conj(void) {
1241 	X               v = getxx();
1242 	v->type = "-conj";
1243 	v->list.s[0] = CHOOSE(conjlist);
1244 	return v;
1245 }
1246 static char    *nomzlist[] = {"it is easy to see that",
1247 	"it is a basic fact that",
1248 	"it is obvious that", "it is not unimportant that",
1249 	"it is easy to overlook the fact that",
1250 	"it is within the realm of possibility that",
1251 	"it is apparent that",
1252 	"this is indicitive of the fact that",
1253 	"this is in substantial agreement with the fact that",
1254 	"this demonstrates the fact that",
1255 	"this leaves out of consideration the fact that",
1256 	"it is of the utmost importance that",
1257 	"the truth is that",
1258 	"the fact is that",
1259 	"it turns out that", "it will turn out to be true that",
1260 	"it should be noted that",
1261 	"it stands to reason that",
1262 	"it would not be unreasonable to assume that",
1263 	"it is interesting to note that",
1264 	"this can be proved by:",
1265 	"this is a trivial consequence of",
1266 	"it is assumed that",
1267 	"it remains to be shown that",
1268 	"it is left to the reader to prove"
1269 };
1270 
1271 X
1272 nomz(void) {
1273 	X               v = getxx();
1274 	v->type = "-nomz";
1275 	v->list.s[0] = CHOOSE(nomzlist);
1276 	return v;
1277 }
1278 
1279 X
1280 equation(void) {
1281 	X		v = getxx();
1282 	static char eqnbuff[100], x;
1283 	static char *eqnelem[] = {"int", "sum", "prod", "union", "inter"};
1284 	static char *eqnfn[] = { "sin", "cos", "tan", "arc", "det",
1285 		"log", "exp", "f", "g", "sinh", "O", "J sub 0", "J sub 1",
1286 		"P sub i", "gamma", "zeta" };
1287 	static char *eqnval[] = { "0", "DELTA", "GAMMA", "LAMBDA",
1288 		"OMEGA", "PHI", "PSI", "SIGMA", "THETA", "UPSILON",
1289 		"XI", "alpha", "beta", "gamma", "delta", "epsilon",
1290 		"eta", "kappa","lambda", "mu", "omega", "x", "zeta", "inf"};
1291 	static char *eqnrel[] = {"=", "<=", ">=", "==", "!=", "approx"};
1292 
1293 	x = 'a' + (R)%26;
1294 	v->type = "-eqn";
1295 	sprintf(eqnbuff,"$%s from %c=%d to %s %s ( %c ) d%c %s %s$",
1296 		CHOOSE(eqnelem), x, (R)&077, CHOOSE(eqnval), CHOOSE(eqnfn),
1297 		x, x, CHOOSE(eqnrel), CHOOSE(eqnval));
1298 	v->list.s[0] = eqnbuff;
1299 	return v;
1300 }
1301 
1302 X
1303 turgid(env)
1304 	E               env;
1305 {
1306 	X               v = getxx();
1307 	int             i = 0;
1308 
1309 	v->type = "turgid";
1310 	if (prob(T * 1.5)) {
1311 		v->list.x[i++] = lconjadv();
1312 		v->list.x[i++] = comma(env);
1313 		v->list.x[i++] = sent(env);
1314 	} else if (prob(2 * T)) {
1315 		v->list.x[i++] = turgid(env);
1316 		v->list.x[i++] = comma(env);
1317 		v->list.x[i++] = conj();
1318 		v->list.x[i++] = sent(env);
1319 	} else if (prob(1.5 * T)) {
1320 		v->list.x[i++] = lconjsub();
1321 		v->list.x[i++] = sent(env);
1322 		v->list.x[i++] = comma(env);
1323 		v->list.x[i++] = sent(env);
1324 	} else if (prob(T * .5)) {
1325 		v->list.x[i++] = sent(env);
1326 		v->list.x[i++] = comma(env);
1327 		v->list.x[i++] = conjadv();
1328 	} else if (prob(T)) {
1329 		v->list.x[i++] = turgid(env);
1330 		v->list.x[i++] = comma(env);
1331 		v->list.x[i++] = conjsub();
1332 		v->list.x[i++] = sent(env);
1333 	} else if (prob(.5 * T)) {
1334 		v->list.x[i++] = nomz();
1335 		if (eqn && prob(.5)) {
1336 			v->list.x[i++] = equation();
1337 			v->list.x[i++] = comma(env);
1338 			v->list.x[i++] = conj();
1339 		}
1340 		v->list.x[i++] = sent(env);
1341 	} else
1342 		v->list.x[i++] = sent(env);
1343 	USED(i);
1344 	return v;
1345 }
1346 
1347 char *
1348 splitup(char *strlab)  {
1349 	static char label[64];
1350 	int j, c;
1351 
1352 	label[0]='"';
1353 	for (j=1; j<60 &&
1354 		(c = *strlab++) != '\0'; j++)
1355 		if (c == ' ') {
1356 			label[j++]='"';
1357 			label[j++]=' ';
1358 			label[j]='"';
1359 		}
1360 		else
1361 			label[j] = c;
1362 	label[j++] = '"'; label[j] = '\0';
1363 	return(label);
1364 }
1365 
1366 void
1367 abo(void) {
1368 	fprintf(stderr, "usage: festoon [-pet] [-sSEED] [SENTENCES] [%%-invented-nouns]\n");
1369 	exits("usage");
1370 }
1371 
1372 void
1373 caps(void) {
1374 	int             i;
1375 	for (i = 1; i < io; i++)
1376 		if (buff[i - 1] == ' ' && buff[i] <= 'z' && buff[i] >= 'a')
1377 			buff[i] += 'A' - 'a';
1378 }
1379 
1380 void
1381 main(int argc, char *argv[]) {
1382 	static char    *furniture[] = {"WASTEBASKET", "ASHTRAY", "TABLE",
1383 	"DESK DRAWER", "COAT LOCKER", "BOOKSHELF"};
1384 
1385 	static char    *ccto[] = {
1386 		"J. N. Akkerhuis",
1387 		"J. J. Argosy",
1388 		"M. D. Banal",
1389 		"H. V. Bandersnatch",
1390 		"L. Bimmler",
1391 		"F. W. Blivet",
1392 		"Z. Brazen",
1393 		"M. Bushido",
1394 		"J. D. Carbuncle",
1395 		"N. Crab",
1396 		"R. H. deTruckle",
1397 		"R. L. Drechsler",
1398 		"C. B. Dudgeon",
1399 		"R. T. Dun",
1400 		"G. R. Emlin",
1401 		"W. G. Fallow",
1402 		"R. S. Flummox",
1403 		"R. N. Fribble",
1404 		"C. R. Glitch",
1405 		"R. H. Hardin",
1406 		"S. A. Hobble",
1407 		"B. W. Kernighan",
1408 		"D. B. Knudsen",
1409 		"C. L'Hommedieu",
1410 		"R. S. Limn",
1411 		"S. T. Livid",
1412 		"Mrs. B. R. Mauve",
1413 		"C. Mee",
1414 		"N-P. Nelson",
1415 		"C. H. Russet",
1416 		"M. Shayegan",
1417 		"M. H. Simper",
1418 		"B. R. Sorrel",
1419 		"G. Swale",
1420 		"R. R. Swarthy",
1421 		"P. Terra-Cotta",
1422 		"U. G. Winnow"};
1423 
1424 	static char	*picelem[] = { "box", "ellipse", "box", "box"};
1425 	static char	*piccon[] = { "arrow", "line", "line <-", "line <->",
1426 	"spline", "spline <-", "spline <->"};
1427 	static char	*picdir[] = { "right", "down right", "down",
1428 	"left", "up left", "left", "down", "down right", NULL};
1429 	E               env;
1430 	X               tree;
1431 	int             i, j = 0, k = 0;
1432 	int             lim = 0;
1433 	long            t = 0;
1434 	char            c, **str;
1435 	int		junk, junk2;
1436 
1437 	for (i = 1, ++argv; i < argc; i++, argv++)
1438 		if (*argv[0] == '-')	/* -pet -snnn */
1439 			while (c = *++argv[0])
1440 				switch (c) {
1441 				case 'z':
1442 					flag = 1;
1443 					continue;
1444 				case 'p':
1445 					pic = 1;
1446 					continue;
1447 				case 't':
1448 					tbl = 1;
1449 					continue;
1450 				case 'e':
1451 					eqn = 1;
1452 					continue;
1453 				case 's':
1454 				t = atoi(argv[0]+1); argv[0][1] = '\0';
1455 					continue;
1456 				default:
1457 					abo();	/* illegal option */
1458 				}
1459 		else if (lim == 0)
1460 			lim = atoi(argv[0]);
1461 		else
1462 			makeup = 1.0 - (float) atoi(argv[0]) / 100.0;
1463 	USED(i);
1464 	if (t == 0)
1465 		time(&t);
1466 	if (makeup < 0. || makeup > 1.0)
1467 		makeup = 1.0;
1468 	if (lim <= 0)
1469 		lim = 25;
1470 	srand((int) t);
1471 
1472 	printf(".TL\n");
1473 	env = getenvq();
1474 	tree = np(env);
1475 	io = 0;
1476 	pr(tree);
1477 	buff[io] = 0;
1478 	caps();
1479 	printf("%s\n", buff);
1480 	printf(".AU \"C. C. Festoon\" CCF Headquarters %d\n", t);
1481 	if (eqn)
1482 		printf(".EQ\ndelim $$\n.EN\n");
1483 	printf(".AS\n");
1484 	free(env);
1485 	do {
1486 		env = getenvq();
1487 		tree = turgid(env);
1488 		io = 0;
1489 		pr(tree);
1490 		buff[io] = 0;
1491 		printf("%s.\n", buff);
1492 		free(env);
1493 	} while (prob(0.75));
1494 	printf(".AE\n");
1495 	printf(".MT \"MEMORANDUM FOR %s\"\n.hy 1\n",
1496 	       CHOOSE(furniture));
1497 	while (i++ < lim) {
1498 		if (i % 23 == 0) {	/* Time for a section header */
1499 			env = getenvq();
1500 			tree = np(env);
1501 			io = 0;
1502 			printf(".H 1 \"");
1503 			pr(tree);
1504 			buff[io] = 0;
1505 			caps();
1506 			printf("%s\"\n", buff);
1507 			free(env);
1508 		}
1509 		if (i % 27 == 0 && pic) {	/* Time for a picture */
1510 			printf(".DS CB\n.ps -1\n.PS\n");
1511 			str = &(CHOOSE(picdir));
1512 			if (*str == NULL) str = &picdir[0];
1513  			junk2 = (R&07) + 3;
1514 			for(junk = 1; junk < junk2; junk++) {
1515 				printf("%s; ", *str);
1516 				if (str == &picdir[0]) {
1517 					pic = 2; printf("A: ");
1518 				}
1519 				printf("%s %s ht %3.1f wid %3.1f\n",
1520 				CHOOSE(picelem), splitup(CHOOSE(nounlist)),
1521 				0.4+0.5/junk2, 0.8+0.6/junk2);
1522 				printf("%s %s %3.1f ",
1523 				CHOOSE(piccon), *str, 0.2+.3/junk2);
1524 				if (*++str == NULL) str = &picdir[0];
1525 				printf("then %s %3.1f %s\n",
1526 				*str, 0.3+.2/junk2,
1527 				splitup(CHOOSE(adjlist)));
1528 			}
1529 			printf("circle rad .3 \"process\" \"completion\"\n");
1530 			if (pic == 2) {
1531 				pic =1;
1532 				printf("line <- dashed up .25 from A.n\n");
1533 				printf("circle rad .3 \"process\" \"start\"\n");
1534 			}
1535 			printf(".PE\n.ps +1\n.DE\n");
1536 			printf(".ce\n\\fBFigure %d\\fP\n", i/27);
1537 		}
1538 		if (i % 41 == 0 && tbl) {	/* Time for a table */
1539 			printf(".TS\n");
1540 			printf("box, center;\nc\ts\ts\n");
1541 			printf("n | l | lw(%3.1fi).\n", 2.0+(41.0+(t&07))/i);
1542 			printf("Action Plan %d\n=\n", i);
1543 			printf("Item\tWho\tAction\n");
1544 			for (junk = 1; junk < (i&17)+4; junk++) {
1545 				printf("_\n%d\t", t/i+junk);
1546 				printf("%s\tT{\n", CHOOSE(ccto));
1547 				env = getenvq();
1548 				io = 0;
1549 				tree = sent(env);
1550 				pr(tree);
1551 				buff[io] = 0;
1552 				printf("%s.\nT}\n", buff);
1553 				free(env);
1554 			}
1555 			printf(".TE\n");
1556 			printf(".ce\n\\fBTable %d\\fP\n", i/41);
1557 		}
1558 		env = getenvq();
1559 		tree = turgid(env);
1560 		io = 0;
1561 		pr(tree);
1562 		buff[io] = 0;
1563 		if (++k % 13 == 0 && prob(0.35)) {	/* Bullet list */
1564 			printf("%s:\n", buff);
1565 			printf(".BL\n");
1566 			do {
1567 				printf(".LI\n");
1568 				free(env);
1569 				env = getenvq();
1570 				io = 0;
1571 				tree = sent(env);
1572 				pr(tree);
1573 				buff[io] = 0;
1574 				printf("%s.\n", buff);
1575 			} while (prob(.83));
1576 			printf(".LE\n");
1577 			printf(".P\n");
1578 		} else {
1579 			if (k % 11 == 0 && prob(.21)) {	/* do as footnote */
1580 				printf("%s\\*F.\n", buff);
1581 				free(env);
1582 				env = getenvq();
1583 				io = 0;
1584 				tree = sent(env);
1585 				pr(tree);
1586 				buff[io] = 0;
1587 				printf(".FS\n%s.\n.FE\n", buff);
1588 			}
1589 			else printf("%s.\n", buff);	/* normal flush */
1590 		}
1591 		if (++j > 2 && prob(0.4))
1592 			printf(".P\n"), j = 0;
1593 		free(env);
1594 	}
1595 	USED(i);
1596 	printf(".SG\n");
1597 	printf(".NS 0\n");
1598 	for (j = 0; j == 0;) {
1599 		for (i = 0; i < sizeof ccto / sizeof *ccto; i++) {
1600 			if (prob(.10))
1601 				j = 1, printf("%s\n", ccto[i]);
1602 		}
1603 	}
1604 	printf(".NE\n");
1605 	USED(i);
1606 	exits("");
1607 }
1608 
1609 void
1610 pr(tree)
1611 	X               tree;
1612 {
1613 	int             i;
1614 	if (flag ) {
1615 		out("<");
1616 		out(tree->type);
1617 		out(">");
1618 	}
1619 	if (tree->type[0] == '-') {
1620 		out(" ");
1621 		for (i = 0; tree->list.s[i]; i++) {
1622 			out(tree->list.s[i]);
1623 		}
1624 	} else
1625 		for (i = 0; tree->list.x[i]; i++) {
1626 			pr(tree->list.x[i]);
1627 		}
1628 	free(tree);
1629 	USED(i);
1630 	return;
1631 }
1632 
1633 void
1634 out(s)
1635 	char           *s;
1636 {
1637 	if (io == 0 && *s == ' ')
1638 		return;
1639 	if (io == 0) {
1640 		for (; s[io]; io++)
1641 			buff[io] = s[io];
1642 		buff[0] += 'A' - 'a';
1643 		return;
1644 	}
1645 	if ((buff[io - 1] == ' ' || buff[io - 1] == '\n' ) && *s == ' ')
1646 		return;
1647 	if (buff[io - 1] == ' ' && *s == ',') {
1648 		buff[io - 1] = ',';
1649 		buff[io++] = '\n';
1650 		return;
1651 	}
1652 	if (buff[io - 1] == 'y' && *s == 'i' && s[1] == 'e')
1653 		io--;
1654 	else if (*s == buff[io - 1] && *s != 's' && *s != 'n')
1655 		io--;
1656 	else if (*s == 'e' && buff[io - 1] == 'a')
1657 		io--;
1658 	for (; *s;)
1659 		buff[io++] = *s++;
1660 	return;
1661 }
1662