KGRKJGETMRETU895U-589TY5MIGM5JGB5SDFESFREWTGR54TY
Server : Apache/2.4.62
System : FreeBSD fbsdweb2.web.rcn.net 14.1-RELEASE FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC amd64
User : www ( 80)
PHP Version : 8.3.8
Disable Function : NONE
Directory :  /domains/markrose/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /domains/markrose/gtg.html
<HTML> 
<HEAD>
<meta http-equiv="content-type" content="text-html; charset=utf-8">
<TITLE>gtg -  Generative Tree Gadget</TITLE>

<style>
	h2
		{color:#A60000;}
	h3
		{color:#C08700;}
	h4
		{color:#C08700;}
	h5
		{color:#C08700;}
	h6
		{color:#C08700;}
	tt
		{color:#A60000;
		font-weight:bold;
		font-family:"Gentium";}
	
</style>

</HEAD> 

<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<form action="" name="theform">
<script language="javascript" type="text/javascript">

// Script (C) 2018 by Mark Rosenfelder.

// Use Lexicon to build argument structure
// Morphology should be done in some easy way
// Build VP struture, use xforms to 'make it real'

var theform;
var lex;
var psr;
var showpsr = false;
var fullform = false;
var embedding = false;
var inf = false;

// Random int from 0 to n
function randomInt(max) 
{
  return Math.floor(Math.random() * max) ; 
}

// Return the word portion of a lexeme (before the :)
function theword(s) 
{
	if (s == null || s == "") return "";

	var i = s.indexOf(':');
	if (i == -1) return s;
	return s.substr(0,i);
}

// Return the category of a lexeme (just after the :)
function thehead(s) 
{
	if (s == null || s == "") return "";

	var spp = s.split(":")
	if (spp.length < 2) return s;
	
	return spp[1];
}

// Return the third parameter of a lexical item
function thearg(s)
{
	var spp = s.split(":")
	if (spp.length < 2) return "";

	return spp[2];
}

// Create a node in the tree
function Node(h, left, mid, right) {

	var node = {head:"X", left:"", mid:"", right:""};
	node.head = h;
	node.left = left;
	node.mid = mid;
	node.right = right;
}

// Is this a left bracket?
function Bra(t) {
	return t.charAt(0) == '[';
}

// Is this a right bracket?
function Ket(t) {
	return t == "]";
}

// General function: replace the word in a w[] entry.
// That is, replace just the part up to the first :
function ReplaceWord(wd, tgt) {
	var colon = wd.indexOf(':');
	return tgt + wd.substr(colon);
}

// Similar, but replaces parameter n
// If n is 0, use ReplaceWord, it's faster 
function ReplaceParm(wd, n, tgt) {
	var partz = wd.split(":");

	var s = "";
	for (var i = 0; i < partz.length; i++) {
	    if (s != "") s += ":";
	    if (i == n)
		s += tgt;
	    else
		s += partz[i];		
	}
	return s;
}

// Given a verb and the desired form, change the verb to that form.
// Example:
//	tgt = Prog
//	sit:V:PP:s sits Past sat Prog sitting Perf sat
// change "sit" to "sitting"
function Inflect(wd, tgt) 
{
	var vpp = wd.split(":");
	if (vpp.length < 4) return wd;

	// STD this should probly be in xform lg instead
	// For N/Pron, insert number as well
	if (vpp[1] == "N" || vpp[1] == "Pron")
		tgt = theNumber(wd) + tgt;

	var forms = vpp[3].split(" ");
	for (var i = 0; i < forms.length; i += 2) {
	    if (forms[i] == tgt) 
		return ReplaceWord(wd, forms[i+1]);
	}

	return wd;
}

// Does this space-separated list contain element tgt or tgt2?
function Includes(s, tgt, tgt2) {
	var spp = s.split(" ");
	for (var i = 0; i < spp.length; i++) {
	    if (spp[i] == tgt || spp[i] == tgt2) return true;
	}

	return false;
}


var t;
var o = null;
var oo = null;
var w = null;

// Apply a rule
// If rule doesn't apply, this will do nothing
function Apply(r) {

	oo = null;

	var partz = r.split("=");
	if (partz.length < 2) return false;

	var doMe = new Array(o.size);
	var doSome = false;

	// Mark elements that are selected by this rule	
	for (var i = 0; i < o.length; i++) {
	    var word = o[i];
	    doMe[i] = theword(word) == partz[0];
	    if (doMe[i])
		doSome = true;
	}

	if (!doSome) 
	    return false;

	// Some rules only apply about 1/3 the time
	if (partz.length > 2)
	    if (partz[2] == "?")
		if (Math.random() < 0.667)
		    return false;

	// Expand target(s)
	oo = new Array();

	for (var i = 0; i < o.length;i++) {
	
	    if (doMe[i]) {
		// This one matches the target; expand it
		oo.push("[" + partz[0]);
		
		var expans = partz[1];
		var pipe = expans.indexOf('|');
		if (pipe != -1) {
		    // Multiple choice. Bias toward first one
		    var altz = expans.split("|");
		    if (Math.random() < 0.33)
			expans = altz[0];
		    else {
			expans = altz[randomInt(altz.length)];
			// Embed sentences only one level deep
			if (embedding && Includes(expans, "S", "Sinf"))
			    expans = altz[0];
		    }
		}

		compz = expans.split(" ");
		for (var j = 0; j < compz.length; j++) {
		    var tgt = compz[j];
		    if (tgt.charAt(0) == '?') {
			// ?X means sometimes insert X
			if (Math.random() < 0.33)
			    oo.push(tgt.substr(1));
		    } else if (tgt.charAt(0) == '(') {
			// (X) means insert 0 to 2 copies of X
			tgt = tgt.substr(1, tgt.length - 2);
			var r3 = randomInt(3);
		        for (var k = 0; k < r3; k++)
			    oo.push(tgt);
		    } else {
			oo.push(tgt);
		    }
		}
		oo.push("]");
	    } else {
		oo.push(o[i]);
	    }
	}
	return true;
}

// Does element o[i] or w[i] match str?
// Elements syntax: X is a category; :X is a word; X:Y is a word X of category X
// For an XP, write e.g. [NP 
function Match(i, str)
{
	var cat = str;
	var word = "";
	var colon = str.indexOf(':');
	if (colon != -1) {
	    cat = str.substr(0,colon);
	    word = str.substr(colon+1);   
	}
	
	var catmatch = cat == "" || theword(o[i]) == cat;
	var wordsame = word == "" || theword(w[i]) == word;
	return catmatch && wordsame;
}

var matches = null;

// Find the sequence str within our sentence (o and w)
// Str can be more than one element
// Return the location within the o array, or -1 if not found
function OFind(o, str) 
{
	var tgt = str.split(" ");
	matches = new Array(tgt.length + 1);

	for (var i = 0; i < o.length; i++) {
	    var ok = false;
	    var iOrig = i;
	    for (var j = 0; j < tgt.length && i < o.length; j++) {
		ok = Match(i, tgt[j]);
		if (!ok) break;

		matches[j] = i;

		if (Bra(tgt[j])) {
		    // This is an XP; skip to its end
		    var level = 0;
		    for (; i < o.length; i++) {
			if (Bra(o[i])) level++;
			else if (Ket(o[i])) level--;
			if (level == 0) break;
		    }
		}
		i++;
	    }
	    matches[tgt.length] = i;
	
	    i = iOrig;
	    if (ok) return i;
	}

	return -1;
}



// Apply a transformation 
function Transform(ins, outs)
{
	if (OFind(o, ins) == -1) {
	    t += " - Target not found";
	    return false;
	}

	t += " - " + ins + " > " + outs;

	oo = new Array();
	var ww = new Array();

	var remloc = matches[matches.length - 1];
	
	for (var i = 0; i < matches[0]; i++) {
	    oo.push(o[i]);
	    ww.push(w[i]);
	}

	var orig = ins.split(" ");
	var repz = outs.split(" ");
	for (var i = 0; i < repz.length; i++) {
	    var el = repz[i];
	    var el0 = el.charAt(0);
	    if (el0 == '»') {
		// Lexicon lookup
		var elz = el.substr(1).split(":");
		var wd = Lookup(elz[0]);
		if (wd != "") {
		    if (elz.length == 1)
		    	oo.push(thehead(wd));
		    else
		    	oo.push(elz[1]);
		    ww.push(wd);
		}
	    }
	    else if ('0123456789'.indexOf(el0) == -1) {
		// Category
		oo.push(el);
		ww.push("");
	    } else {
		var r = parseInt(el);
		// Element from input string (by number)
		if (r >= 0 && r < orig.length) {
		    for (var j = matches[r]; j < matches[r+1]; j++) {
			var wd = w[j];
			oo.push(o[j]);
			ww.push(wd);
		    }
		}
	    }
	}

	for (var i = remloc; i < o.length; i++) {
	    oo.push(o[i]);
	    ww.push(w[i]);
	}

	o = oo;
	w = ww;

	return true;
}

// Return the clausemates of this V
// STD: decide what direction to go - this could be a checkbox
function VP(o, i) {

	var level = 0;
	var u = "";
	
	for (var j = i + 1; j < o.length; j++) {
	    var t = o[j];
	    if (Bra(t)) {
		if (level == 0) u += " " + t.substr(1);
		level++;
	    }
	    else if (Ket(t)) {
		level--;
	    }
	    else if (level == 0) u += " " + t;
	}

	if (u != "") u = u.substr(1);
	return u;
}

// Inflect word for plural
function Pluralize(wd)
{
	wd = Inflect(wd, "p");

	// Add to arg so we know we changed this
	wd = ReplaceParm(wd, 2, thearg(wd) + " p");

	return wd;
}

// Select lexical items
function Lexicalize(o) {
	var w = new Array(o.length);

	// For each word in the sentence
	for (var i = 0; i < o.length; i++) {
	    w[i] = "";

	    // Brackets don't get words	
	    if (Bra(o[i]) || Ket(o[i])) {
	        continue;
	    }

	    // Go through lexicon
	    var ll = new Array();
	    for (var j = 0; j < lex.length; j++) {
		var wd = lex[j];

	    	if (o[i] == thehead(wd)) {
		    if (o[i] == "Comp" && inf) {
			wd = "inf:Comp";
		    }
		    if ((o[i] == "N" || o[i] == "Pron") && Math.random() < 0.33) {
			// Select plural for nouns, sometimes
			wd = Pluralize(wd);
		    }
		    if (o[i] == "V") {
			// Verbs must match # of arguments
			var vp = VP(o, i);
			if (vp != thearg(wd))
			    continue;
		    }
		    ll.push(wd);
		}
	    }
	    if (ll.length == 0) 
		continue;
	    
	    // Select one randomly
	    var m = randomInt(ll.length);

	    w[i] = ll[m];
		if (w[i] == null) t += "<br/>NULL";
	}

	return w;
}


// Output tree as unreadable string
// Set fullform to output entire word rather than 1st section
function Stringize(o, w) {

	var s = "";
	var level = 0;

	for (var i = 0; i < o.length; i++) {
	    var t = o[i];
	    if (Bra(t)) {
		level++;

		var c = "Purple";
		if (t == "[NP") c = "red";
		else if (t == "[PP") c = "orange";
		else if (t == "[S") c = "blue";
		else if (t == "[TP") c = "green";

		s += '<span style="color:' + c + '">';
	    }

	    s += t + " ";
	
	    if (Ket(t)) {
		level--;
		s += "</span>";
	    }

	    if (w != null && w[i] != null) {
		s += '<span style="color:black;font-weight:bold;">';
		if (fullform) s += w[i];
		else s += theword(w[i]);
		s += '</span> ';
	    }
	}

	return s;
}

// Output tree as even more unreadable string for phpSyntaxTree
// Should be same as Stringize but: no colors; brackets round words; spaces > %20
function wordbrax(o, w) {
	var s = "";

	for (var i = 0; i < o.length; i++) {
	    if (Bra(o[i]) || Ket(o[i]) || w[i] == null)
		s += o[i];
	    else
	        s += "[" + o[i] + "%20" + w[i] + "]";
	}

	return s;
}

// Output pronounced words only
function Pronounce(w) {

	var s = "";
	var punct = ".";

	for (var i = 0; i < w.length; i++) {
	    if (w[i] == null || w[i] == "") continue;

	    var wd = theword(w[i]);
	    if (wd == "Q")
		punct = "?";
	    else if (wd != "ø" && wd != "inf" && wd != "past" && wd != "pres") {
		if (s != "") s += " ";
		s += wd;
	    }
	}

	s += punct;

	return s.italics();

}

// Find the first element of category cat 
function FindFirst(cat) {

	var catz = cat.split("|");
	
	for (var i = 0; i < o.length; i++) {
	    for (var c = 0; c < catz.length; c++) 
		if (theword(o[i]) == catz[c])
		    return i;
	}

	return -1;
}

// Find the first element of word w 
function FindFirstWord(tgt) {

	for (var i = 0; i < o.length; i++) {
	    if (w[i] != null && theword(w[i]) == tgt)
		return i;
	}

	return -1;
}

// Insert a word just at a location in both o[] and w[]
function Insert(tgt, wd, cat) {
	w.splice( tgt, 0, wd);
	o.splice( tgt, 0, cat);
}

// Find first item of class c from position i
// c can list multiple classes separated by |
// special class Aux is in third position
function FindNext(c, i, dir)
{
	if (i == -1) i = 0;

	var incr = 1;
	var iOrig = i;
	if (dir == "-") incr = -1;

	var cc = c.split("|");

	// For each word in the indicated direction
	for (i += incr; i >= 0 && i < w.length; i += incr) {

	    for (var j = 0; j < cc.length; j++) {
		if (o[i] == cc[j] || thehead(w[i]) == cc[j])
		    return i;
	    }
	}

	// ±: if + direction failed, try -
	if (dir == "±") 
	    return FindNext(c, iOrig, "-");

	return -1;	
}

// Find the next word 
function NextWord(i) 
{
	for (i++; i < w.length; i++) {
	    if (w[i] != null && w[i] != "" && theword(w[i]) != "ø")
		return i;
	}

	return -1;
}

// Find the last element of this constituent
function FindEnd(tgt)
{
	var level = 0;
	for (var i = tgt + 1; i < o.length; i++) {
	    if (Bra(o[i]))
		level++;
	    else if (Ket(o[i])) {
	    	level--;
		if (level < 0) 
		    return i + 1;
	    }
	}

	return o.length;
}

// Flip two constituents
function Flip(t1b, t2b) 
{
	if (t2b < t1b) {
	    var temp = t2b;
	    t2b = t1b;
	    t1b = temp;
	}

	var t1e = FindEnd(t1b);
	var t2e = FindEnd(t2b);

	oo = new Array();
	ww = new Array();

	// Portion before t1 is copied as is
	var i = 0;
	for (; i < t1b && i < o.length; i++) 
	{    oo.push(o[i]); ww.push(w[i]);   }

	// Copy t2 into t1's spot
	for (i = t2b; i < t2e && i < o.length; i++) 
	{    oo.push(o[i]); ww.push(w[i]);   }

	// Portion in between is copied as is
	for (i = t1e; i < t2b && i < o.length; i++) 
	{    oo.push(o[i]); ww.push(w[i]);   }

	// Copy t1 into t2's spot
	for (i = t1b; i < t1e && i < o.length; i++) 
	{    oo.push(o[i]); ww.push(w[i]);   }

	// Portion after t2 is copied as is
	for (i = t2e; i < o.length; i++) 
	{    oo.push(o[i]); ww.push(w[i]);   }

	o = oo;
	w = ww;
}

// Lexicon lookup
function Lookup(item) {
	for (var l = 0; l < lex.length; l++) {
	    if (theword(lex[l]) == item) 
		return lex[l];
	}
	return "";
}

// Safe lookahead
function Look(partz, i)
{
	if (i + 1 < partz.length)
	    return partz[i + 1];
	else
	    return "";
}

var rcheck = false;

// Apply a rule, e.g.
// 	if Prog find V inflect ing
function Xform(x)
{
	var partz = x.split(" ");

	var tgt = -1;
	var clip = "";
	var loop = -1;
	var nloop = 0;

	for (var i = 0; i < partz.length; i++) {
	    var cmd = partz[i];	

	    if (cmd == "sub") {
		if (!embedding)
		    return false;
	    }
	    if (cmd == "main") {
		if (embedding)
		    return false;
	    }
	    if (cmd == "maybe") {
		// Optional transformations happen at a fixed 1/3 rate
		if (Math.random() < 0.667)
		    return false;
	    }
	    if (cmd == "checkif") {
		var ins = "";
		for (i = i + 1; i < partz.length; i++) {
		    if (ins != "") ins += " "; 
		    ins += partz[i];
		}
		rcheck = OFind(o, ins) != -1;
		t += " check is " + rcheck;
		return;
	    }
	    if (cmd == "yes") {
		if (!rcheck) return;
	    }
	    if (cmd == "no") {
		if (rcheck) return;
	    }
	    if (cmd == "start") {
		// Remember where we are
		loop = i;
	    }
	    if (cmd == "loop") {
		// Loop back to remembered location
		nloop++;
		if (nloop < 10)
		    i = loop;
	    }
	    if (cmd == "if") {
		// Existence check
		var want = true;
	        if (Look(partz, i) == "no") {
		    want = false;
		    i++;
		}

		var item = Look(partz, i); i++;
		if (item == "word") {
		    item = Look(partz,i); i++;
		    tgt = FindFirstWord(item);
		} else 
		    tgt = FindFirst(item);

		t += " searching " + item + " " + tgt;
	
		// If that failed, exit
		if (want && tgt == -1)
		    return;
		if (!want && tgt != -1)
		    return;
		continue;
	    }
	    if (cmd == "find") {
		// Find an item; save it as the target
		// STD word
		var item = Look(partz, i); i++;

	        var start = 0;
		var dir = "+";
		if (item == "next") {
		    start = tgt;
		    item = Look(partz, i); i++;
		} else if (item == "previous") {
		    start = tgt;
		    item = Look(partz, i); i++;
		    dir = "-";
		}

		tgt = FindNext(item, start, dir);
t += " finding " + tgt;
		if (tgt == -1)
		    return;

		continue;
	    }
	    if (cmd == "object") {
		// Find the sentence's  object (its [NP)
		tgt = FindNext("[NP", o.length, "-");
		if (tgt < FindNext("[VP", o.length, "-"))
		    tgt = -1;  // we found the subject
		if (tgt == -1) return;
	    }
	    if (cmd == "subject") {
		// Find the sentence's  subject (its [NP)
		tgt = FindNext("[NP", 0, "+");
		if (tgt == -1) return;
	    }
	    if (cmd == "ifword" && tgt != -1) {
		// Is the next actual word equal to the one specified?
		while (tgt < o.length && theword(w[tgt]) == "")
		    tgt++;

		var item = Look(partz, i); i++;
		t += " ifword " + item + " " + theword(w[tgt]);
		if (item != theword(w[tgt])) 
		    return;
	    }
	    if (cmd == "inflect" && tgt != -1) {
		// Inflect current word with the given inflection
		var afx = Look(partz, i); i++;
		if (afx == "clip") afx = clip;
		t += " inflecting " + theword(w[tgt]) + "+" + afx;
		w[tgt] = Inflect(w[tgt], afx);
		continue;
	    }
	    if (cmd == "transform") {
		// Transform one structure into another
		var ins = "";
		for (i = i + 1; i < partz.length; i++) {
		    if (partz[i] == "into") break;
		    if (ins != "") ins += " "; 
		    ins += partz[i];
		}
		var outs = "";
		for (i = i + 1; i < partz.length; i++) {
		    if (partz[i] == "end") break;
		    if (outs != "") outs += " "; 
		    outs += partz[i];
		}
		Transform(ins, outs);
	    }
	    if (cmd == "copy" && tgt != -1) {
		// Copy word information to clipboard
		if (Look(partz, i) == "num") {
		    i++;
		    clip = theNumber(w[tgt]);
		} else {
		    clip = w[tgt];
		    if (clip == "")
			clip = "#" + tgt;
		}
	    }
	    if (cmd == "cut" && tgt != -1) {
		// Copy plus zero out old contents
		clip = w[tgt];
		w[tgt] = "ø";
	    }
	    if (cmd == "paste" && tgt != -1 && clip != "") {
		// Paste clipboard to target word
		t += " paste to " + theword(w[tgt]);
		if (w[tgt] == null || w[tgt] == "" || w[tgt] == "ø")
		    w[tgt] = clip;
		else {
		    if (clip == "s" || clip == "p") {
		    	w[tgt] = Pluralize(w[tgt]);
		    } else if (o[tgt] == "T") {
		        w[tgt] = theword(w[tgt]) + "+" + clip;
		    } else
			w[tgt] = clip;
		}
	    }
	    if (cmd == "lex") {
		// Look up a lexical item; add it to the clipboard
		var item = Look(partz, i); i++;
		clip = Lookup(item);
	    }
	    if (cmd == "cuttense" && tgt != -1) {
		// Copy tense from this word to the clipboard
		var ew = theword(w[tgt]);
	        var plus = ew.indexOf("+");
		if (plus == -1) {
		    clip = ew;
		    w[tgt] = "ø";
		} else {
		    clip = ew.substr(0, plus);
		    var rem = ew.substr(plus+1);
		    w[tgt] = ReplaceWord(w[tgt], rem);
		}
		t += " copying tense " + clip;
	    }
	    if (cmd == "numclip") {
		// Add subject number to clipboard
		clip += FindNumber();
	    }
	    if (cmd == "insert" && tgt != -1 && clip != "") {
		// Insert clipboard as new word after current location
		var cat = Look(partz, i); i++;
		if (cat == "") cat = thehead(clip);
		t += " inserting " + theword(clip);
		Insert(tgt + 1, clip, cat);
	    }
	    if (cmd == "append" && clip != "") {
		// Insert clipboard as new word at end
		t += " appending " + theword(clip);
		o.push(thehead(clip));
		w.push(clip);
	    }
	    if (cmd == "prepend" && clip != "") {
		// Insert clipboard as new word at beginning, i.e., just after [S
		t += " prepending " + theword(clip);
		Insert(1, clip, thehead(clip))
	    }
	    if (cmd == "flip" && clip != "" && tgt != "") {
		// Switch two constituents 
		// STD word level not done
		if (clip.charAt(0) == '#') {
		    var n = parseInt(clip.substr(1));
		    t += " flipping " + n + " and " + tgt;
		    Flip(n, tgt);
		}
	    }
	}
}

// Given a word, return its number s/p
// If it's not defined, return ""
function theNumber(wd)
{
	var arg = thearg(wd);
	args = arg.split(" ");
	for (var i = 0; i < args.length; i++) {
	    if (args[i] == "s" || args[i] == "p")
		return args[i];
	}
	return "";
}


// Find the inflection of the subject, which is stored in thearg of the word
function FindNumber() {

	// Find the inflection of the subject, if any
	var n = FindFirst("N|Pron");

t += " findnumber " + n + " - " + thearg(w[n]);
	
	if (n != -1)
	    return theNumber(w[n]);

	return "";
}

// Used by DoDefine. Apply ins > outs for each sep-separated argument in s.
function DoArgs(s, sep, ins, outs) 
{
	var args = s.split(sep);
	var s = "";
	for (var j = 0; j < args.length; j++) {
	    if (s != "") s += sep;
	    if (args[j] == ins)
	 	s += outs;
	    else {
		if (sep == " " && args[j].indexOf("|") != -1)
		    s += DoArgs(args[j], "|", ins, outs);
		else
		    s += args[j];
	    }
	}
	return s;
}

// Apply a definition to remaining rules
function DoDefine(def, xx, i) {

	var sp = def.indexOf(" ");
	var eq = def.indexOf("=", sp + 1);
	if (sp == -1 || eq == -1) return;

	sp++;
	var ins = def.substr(sp, eq - sp);
	var outs = def.substr(eq + 1);

t += "<br/>Replacing " + ins + " with " + outs;

	for (; i < xx.length; i++)
	    if (xx[i].charAt(0) != '*')
	    	xx[i] = DoArgs(xx[i], " ", ins, outs);
}


// Generate a sentence. Uses globals o[], w[]
function GenerateS(psr, xx) 
{
	// Always start with a bare S
	o = new Array();
	o.push("S");

	w = null;

	// Apply phrase structure rules till we have a sentence
	for (var r = 0; r < psr.length; r++) {
	
	   if (Apply(psr[r])) {
		if (showpsr) t += "<br/>" + Stringize(o, w);
		o = oo;
	   }
	}

	w = Lexicalize(o);

	t += "<p><b>Deep structure:</b> " + Stringize(o, w);

	// Apply transformations
	for (var x = 0; x < xx.length; x++) {
	    var xform = xx[x];
	    if (xform.charAt(0) == '*')
		t += "<br/>" + xform;
	    if (xform.substr(0,6) == "define") {
		DoDefine(xform, xx, x + 1);
	    } else
		Xform(xform);
	}

	t += "<p><b>Surface structure:</b> " + Stringize(o, w);
}

// Embed one S (o/w) within another (oo/ww) at location tgt
// Repalce o/w with the combined sentence
function Embed(oo, ww, tgt) {
	
	var o2 = new Array();
	var w2 = new Array();

	for (var i = 0; i < tgt; i++) {
	    o2.push(oo[i]);
	    w2.push(ww[i]);
	}

	for (var i = 0; i < o.length; i++) {
	    o2.push(o[i]);
	    w2.push(w[i]);
	}

	for (var i = tgt + 1; i < oo.length; i++) {
	    o2.push(oo[i]);
	    w2.push(ww[i]);
	}
	
	o = o2;
	w = w2;
}

// User hit the Generate button
function process()
{
	//Read parameters
	theform = document.theform;
	var text = document.getElementById("mytext");

	// Read the lexicon
	var s = theform.lex.value;
	lex = s.split("\n");

	// Read the phrase structure rules
	s = theform.psr.value;
	psr = s.split("\n");

	// Read the transformations
	s = theform.xform.value;
	xx = s.split("\n");

	t = "";
	embedding = false;
	inf = false;

	// Generate a sentence
	GenerateS(psr, xx);

	// Embedded sentences
	emb = FindFirst("S|Sinf");
	if (emb != -1) {
	    var oo = o;
	    var ww = w;
	
	    t += "<p><b>Creating embedded sentence</b>";

	    embedding = true;
	    if (oo[emb] == "Sinf") {
		inf = true;
		oo[emb] = "S";
	    }

	    GenerateS(psr, xx);

	    Embed(oo, ww, emb);

	    t += "<p><b>Embedded:</b> " + Stringize(o, w);
	}

	// Link to drawing program
	var url = "http://ironcreek.net/phpsyntaxtree/?" + wordbrax(o, w);
	t += '<p><a href="' + url + '" target="_blank"><b>Draw tree</b></a>';

	// Final output
	t = "<b>Final:</b> " + Pronounce(w) + t;
	
	// Output
	text.innerHTML = t;
}

function helpme() 
{
	window.open("gtghelp.html"); 
}


</script>

<table width="100%">
<tr><td bgcolor="#EEC25A">
<h2><br>&nbsp;&nbsp;<a href="kit.html"><img src="liltree.gif" border=0 align="absmiddle" height="53" width="60"></a>&nbsp;gtg</h2></td></tr>
</td></tr>
</table>

<i>This is a Javascript program which allows you to define a generative grammar.  Press Generate to test, and Help for documentation.

<blockquote><span style="color:red;"><b>Warning:</b> This program is <b>in progress</b> and apt to change at any time.
</span></blockquote>

<p>Also see: <A href="markov.html">Markov generator</a>; <a href="ggg.html">Generative Grammar Gadget</a>; <a href="mg.html">Minimalism gadget</a>.
<p>&#8212;Mark Rosenfelder, 2018</i>

<hr>

<table width="100%">

<tr>
<td>
Lexicon:
<br><textarea id="lex" name="lex" rows="15" cols="30">
Q:Comp
ø:Comp
the:D
this:D::p these
that:D::p those
cat:N::p cats
dog:N::p dogs
mouse:N::p mice
man:N:m:p men
woman:N:f:p women
frog:N::p frogs
monster:N::p monsters
boy:N:m:p boys
girl:N:f:p girls
past:T:
pres:T:
not:Neg:
must:Modal:
can:Modal:
have:Perf::pres has past had pastp had ing having en had
be:Prog::pres is presp are past was pastp were ing being en been
do:V:NP:pres does past did pastp did ing doing en done
sit:V:PP:pres sits past sat pastp sat ing sitting en sat
sleep:V:pres sleeps past slept pastp slept ing sleeping en slept
hate:V:NP:pres hates past hated pastp hated ing hating en hated
love:V:NP:pres loves past loved pastp loved ing loving en loved
chase:V:NP:pres chases past chased pastp chased ing chasing en chased
give:V:NP NP:pres gives past gave pastp gave ing giving en given
think:V:S:pres thinks past thought pastp thought ing thinking en thought
know:V:S:pres knows past knew pastp knew ing knowing en known
want:V:Sinf:pres wants past wanted pastp wanted ing wanting en wanted
put:V:NP PP:pres puts past put pastp put ing putting en put
care:V::pres cares past cared pastp cared ing caring en cared
by:P
near:P
to:P
big:A
little:A
nice:A
nasty:A
beautiful:A
ugly:A
happy:A
sad:A
who:Pron::
he:Pron:m:acc him p they pacc them
she:Pron:f:acc her p they pacc them
everyone:Pron::
someone:Pron::
</textarea>
</td>
<td width="20px">&nbsp;</td>

<td>
Phrase structure:
<br><textarea id="psr" name="psr" rows="15" cols="30">
S=Comp TP
TP=NP T VP
VP=Modal VP=?
VP=Perf VP=?
VP=Prog VP=?
VP=V (NP)|V NP PP|V S|V Sinf
PP=P NP
NP=D ?A N|Pron
</textarea>
</td>
<td width="20px">&nbsp;</td>


<td>
Transformations:
<br><textarea id="xform" name="xform" rows="15" cols="55">
define Aux=Modal|Perf|Prog|Pass
* suppress questions in subclauses
sub lex ø if word Q paste
* plural form of determiners
start find next N copy num find previous D paste find next N loop
* negative
maybe if Aux lex not insert Neg
maybe if no Aux find T lex not insert Neg
* passive
checkif V [NP [NP
yes transform V [NP [NP into »be:Pass [VP 0 1 [PP »by 2 ] ] end subject copy object flip
no transform V [NP into »be:Pass [VP 0 [PP »by 1 ] ] end subject copy object flip
* wh-question
main object ifword who cut prepend transform Comp into »Q
main subject ifword who transform Comp into »ø
* dative movement
maybe transform [NP [NP into 1 [PP »to 0 ]
* question formation
if word Q transform [NP T into 1 0
if word Q find Aux cut find T paste
* object forms of pronouns
find V start find next Pron inflect acc loop
if word inf find V find last Pron inflect acc
* passive inflection
if Pass find next V inflect en
* progressive
if Prog find next V|Pass inflect ing
* perfect
if Perf find next V|Pass|Prog inflect en
* Infinitive S: suppress modal, add to
if word inf find Modal cut
if word inf find T lex to insert
* Do support
if no Aux lex do if Neg find T paste
if no Aux lex do if no Neg if word Q find T paste
* verbal inflection
if no word inf if T cuttense numclip find V|Aux inflect clip
</textarea> 
</td>

<!-- 
:Q=[NP T=1+Aux 0
Prog:+:V:ing:Progressive
Perf:+:V|Aux:en:Perfect
T:≠:V|Aux:^do:Do-Support
T:+:Neg≠Aux:^do:Neg Do-Support
T:+:V|Aux:TENSE:Verbal Inflection
Neg:±:T|Aux:+n't:Negative Contraction

* tag question
if no word Q lex tag append QQ
if QQ transform QQ into [S 0 T »someone ]
if QQ find Modal|Perf|Prog copy find next T paste
if QQ if no Modal|Perf|Prog find T find next T lex do paste

this doesn't even work yet!  3 cases
NP ø Aux, Aux he?  -- copied correctly
NP gave, didn't he?  -- do is inserted, but not inflected right
NP did not give, did he? -- ditto

PLUS we don't handle the pronoun
PLUS we don't handle the "n't" 

We really need to handle m/f so we can do a) reflexives; b) tag Q; c) French.

-->


<td>
<p><input type="button" value="Generate" onClick="process();">

<p><input type="button" value="Help me!" onClick="helpme();">


</td>
</tr></table>

<hr>

<h3>Output</h3>
<br><div id="mytext"> </div>


</form>

<hr>

<center><A HREF="default.html"><img src="homeg.gif" border=0 alt="Home"></A></center>

</body>
</html>

Anon7 - 2021