--- /dev/null
+### BiMetaTrans 1.0
+
+BiMetaTrans(Prolog, RuleML) is a bidirectional translator capable of
+parsing and generating a well-formed sublanguage of RuleML/XML to/from
+a metalogical encoding of our own design called Prolog/'$V'. For later
+ease of reference:
+
+* Prolog/'$V' stands for "Metalogic Prolog with variable-as-'$V'-term encoding"
+* RuleML/XML stands for "RuleML in XML with any kind of rendering"
+* RuleML/xmL stands for "RuleML in minified XML"
+* RuleML/Xml stands for "RuleML in indented XML"
+
+"Minified XML" refers to XML with only necessary whitespace, between
+element names and attributes, and pairs of attributes, with all
+indentation stripped out. "Indented XML" contains indentation and
+newlines, and is usually formatted for human readers.
+
+The specification of Prolog/'$V', and of the NafHornlogEq sublanguage
+of RuleML/XML targeted by BiMetaTrans, is contained in the preprint
+[Invertible Bidirectional Metalogical Translation Between Prolog and
+RuleML/XML for Knowledge Representation and
+Querying](http://ruleml.org/papers/RuleMLXMLBiDirTransScryer.pdf) and
+its accompanying talk
+[slides](http://ruleml.org/talks/RuleMLXMLBiDirTransScryer-talk.pdf). The
+preprint and talk also describe the implementation of BiMetaTrans
+found here, and outlines a strategy for proving the invertibility of
+BiMetaTrans.
+
+BiMetaTrans exports a single public predicate subsuming its user
+API, `parse_ruleml/3`. It has two modes, each corresponding to a single
+direction of translation:
+
+```
+parse_ruleml(+AssertItems, +QueryItems, ?XML) (Prolog->RuleML)
+parse_ruleml(?AssertItems, ?QueryItems, +XML) (RuleML->Prolog)
+```
+
+The modes constrain the inputs to fit one of two patterns, the
+first where AssertItems and QueryItems are instantiated and XML is
+possibly a variable, and conversely for the second. Instantiated
+inputs are expected to be ground, meaning they should not contain
+free variables.
+
+We explore several examples of its use in Scryer Prolog.
+
+Loading BiMetaTrans from the Scryer REPL:
+
+```
+?- use_module('src/examples/bimetatrans/bimetatrans').
+```
+
+Using `write/1` to print the string to standard output (`write/1` is used
+because it does not print strings with escape characters (ie. `\"` for
+double quote)):
+
+```
+?- parse_ruleml([people('Alex',male),people('Alex',female),people('Siri',female)], [], XML),
+ write(XML).
+"<Assert mapClosure="universal"><Atom><Rel>people</Rel><Ind>Alex</Ind><Data iso:type="symbol">male</Data></Atom><Atom><Rel>people</Rel><Ind>Alex</Ind><Data iso:type="symbol">female</Data></Atom><Atom><Rel>people</Rel><Ind>Siri</Ind><Data iso:type="symbol">female</Data></Atom></Assert>" XML = "<Assert mapClosure= ...".
+```
+
+Note that the XML input can contain extraneous whitespace and
+indentation while generated XML never does (ie., the XML generated by
+BiMetaTrans is always Ruleml/xmL). `\` is used to continue ISO Prolog
+strings to the next line but is never stored to the string by the
+Prolog reader.
+
+Performing the inverse translation of the previous example, in
+RuleML/Xml:
+
+```
+?- parse_ruleml(AssertItems, QueryItems,
+ "<Assert mapClosure=\"universal\">\
+ <Atom>\
+ <Rel>people</Rel>\
+ <Ind>Alex</Ind>\
+ <Data iso:type=\"symbol\">male</Data>\
+ </Atom>\
+ <Atom>\
+ <Rel>people</Rel>\
+ <Ind>Alex</Ind>\
+ <Data iso:type=\"symbol\">female</Data>\
+ </Atom>\
+ <Atom>\
+ <Rel>people</Rel>\
+ <Ind>Siri</Ind>\
+ <Data iso:type=\"symbol\">female</Data>\
+ </Atom>\
+ </Assert>").
+ AssertItems = [people('Alex',male),people('Alex',female),people('Siri',female)], QueryItems = [].
+```
+
+Non-empty AssertItems and QueryItems lists generated to RuleML/xmL
+simultaneously:
+
+```
+?- parse_ruleml([a(item), b(item), c(item)], [(?- p, q, r(1), s(-2.222342432), t("attached")), (?- u, v('$V'(q)))], XML),
+ write(XML).
+"<Assert mapClosure="universal"><Atom><Rel>a</Rel><Data iso:type="symbol">item</Data></Atom><Atom><Rel>b</Rel><Data iso:type="symbol">item</Data></Atom><Atom><Rel>c</Rel><Data iso:type="symbol">item</Data></Atom></Assert><Query closure="existential"><And><Atom><Rel>p</Rel></Atom><Atom><Rel>q</Rel></Atom><Atom><Rel>r</Rel><Data iso:type="number">1</Data></Atom><Atom><Rel>s</Rel><Data iso:type="number">-2.222342432</Data></Atom><Atom><Rel>t</Rel><Data iso:type="string">"attached"</Data></Atom></And></Query><Query closure="existential"><And><Atom><Rel>u</Rel></Atom><Atom><Rel>v</Rel><Var>q</Var></Atom></And></Query>" XML = "<Assert mapClosure= ...".
+```
+
+To insert escape characters into the printed RuleML/xmL, we use
+`writeq/1` in place of `write/1`:
+
+```
+?- parse_ruleml([a(item), b(item), c(item)], [(?- p, q, r(1), s(-2.222342432), t("attached")), (?- u, v('$V'(q)))], XML),
+ writeq(XML).
+"<Assert mapClosure=\"universal\"><Atom><Rel>a</Rel><Data iso:type=\"symbol\">item</Data></Atom><Atom><Rel>b</Rel><Data iso:type=\"symbol\">item</Data></Atom><Atom><Rel>c</Rel><Data iso:type=\"symbol\">item</Data></Atom></Assert><Query closure=\"existential\"><And><Atom><Rel>p</Rel></Atom><Atom><Rel>q</Rel></Atom><Atom><Rel>r</Rel><Data iso:type=\"number\">1</Data></Atom><Atom><Rel>s</Rel><Data iso:type=\"number\">-2.222342432</Data></Atom><Atom><Rel>t</Rel><Data iso:type=\"string\">\"attached\"</Data></Atom></And></Query><Query closure=\"existential\"><And><Atom><Rel>u</Rel></Atom><Atom><Rel>v</Rel><Var>q</Var></Atom></And></Query>" XML = "<Assert mapClosure= ...".
+```
+
+XML can be pretty printed using a [free online XML pretty
+printer](https://codebeautify.org/xmlviewer), as here:
+
+```
+<Assert mapClosure=\"universal\">
+ <Atom>
+ <Rel>a</Rel>
+ <Data iso:type=\"symbol\">item</Data>
+ </Atom>
+ <Atom>
+ <Rel>b</Rel>
+ <Data iso:type=\"symbol\">item</Data>
+ </Atom>
+ <Atom>
+ <Rel>c</Rel>
+ <Data iso:type=\"symbol\">item</Data>
+ </Atom>
+</Assert>
+<Query closure=\"existential\">
+ <And>
+ <Atom>
+ <Rel>p</Rel>
+ </Atom>
+ <Atom>
+ <Rel>q</Rel>
+ </Atom>
+ <Atom>
+ <Rel>r</Rel>
+ <Data iso:type=\"number\">1</Data>
+ </Atom>
+ <Atom>
+ <Rel>s</Rel>
+ <Data iso:type=\"number\">-2.222342432</Data>
+ </Atom>
+ <Atom>
+ <Rel>t</Rel>
+ <Data iso:type=\"string\">\"attached\"</Data>
+ </Atom>
+ </And>
+</Query>
+<Query closure=\"existential\">
+ <And>
+ <Atom>
+ <Rel>u</Rel>
+ </Atom>
+ <Atom>
+ <Rel>v</Rel>
+ <Var>q</Var>
+ </Atom>
+ </And>
+</Query>
+```
+
+The AssertItems and QueryItems lists can then be recovered using this
+RuleML/Xml string, with the `\` character added to the end of each
+line:
+
+```
+?- parse_ruleml(AssertItems, QueryItems,
+ "<Assert mapClosure=\"universal\">\
+ <Atom>\
+ <Rel>a</Rel>\
+ <Data iso:type=\"symbol\">item</Data>\
+ </Atom>\
+ <Atom>\
+ <Rel>b</Rel>\
+ <Data iso:type=\"symbol\">item</Data>\
+ </Atom>\
+ <Atom>\
+ <Rel>c</Rel>\
+ <Data iso:type=\"symbol\">item</Data>\
+ </Atom>\
+ </Assert>\
+ <Query closure=\"existential\">\
+ <And>\
+ <Atom>\
+ <Rel>p</Rel>\
+ </Atom>\
+ <Atom>\
+ <Rel>q</Rel>\
+ </Atom>\
+ <Atom>\
+ <Rel>r</Rel>\
+ <Data iso:type=\"number\">1</Data>\
+ </Atom>\
+ <Atom>\
+ <Rel>s</Rel>\
+ <Data iso:type=\"number\">-2.222342432</Data>\
+ </Atom>\
+ <Atom>\
+ <Rel>t</Rel>\
+ <Data iso:type=\"string\">\"attached\"</Data>\
+ </Atom>\
+ </And>\
+ </Query>\
+ <Query closure=\"existential\">\
+ <And>\
+ <Atom>\
+ <Rel>u</Rel>\
+ </Atom>\
+ <Atom>\
+ <Rel>v</Rel>\
+ <Var>q</Var>\
+ </Atom>\
+ </And>\
+ </Query>").
+ AssertItems = [a(item),b(item),c(item)], QueryItems = [(?-p,q,r(1),s(-2.222342432),t("attached")),(?-u,v('$V'(q)))].
+```