My experiments with prolog have been progressing. See http://www.w3.org/pub/WWW/MarkUp/Math/Group/math.pl Prolog allows you to define operators and provides the operator precedence parser that parses input strings into prolog terms. Its not precisely what we need but close enough to experiment with. First there are some operator definitions, covering + - / etc. which are built into prolog. I have extended this set: ?-op(980, xfy, becomes). ?-op(800, xfy, over). ?-op(650, yfx, of). ?-op(650, yfx, wrt). ?-op(650, yfx, from). ?-op(650, yfx, to). ?-op(550, fy, sqrt). ?-op(200, xfy, up). ?-op(200, xfy, down). Here, the number defines the precedence as an integer in the range 0 to 1200. The next argument determines whether the operator is prefix, infix or postfix and how it associates. The third argument gives the name of the operator. I have defined a number of assertions that say how to map terms into an internal representation: map(var(a) * var(b) becomes times(var(a), var(b))). map(var(a) + var(b) becomes plus(var(a), var(b))). map((var(a)/var(b)) becomes div(var(a), var(b))). map((var(a) over var(b)) becomes over(var(a), var(b))). map((sqrt var(v)) becomes sqrt(var(v))). map((var(a)^var(b)) becomes up(var(a), var(b))). map((var(a) up var(b)) becomes up(var(a), var(b))). map((var(a) down var(b)) becomes down(var(a), var(b))). map(integral of var(a) wrt var(b) becomes integral(var(a), var(b))). map(integral of var(a) becomes integral(var(a))). map(integral from var(a) to var(b) of var(c) wrt var(d) becomes integral(var(a), var(b), var(c), var(d))). Non-terminals are represented using var(slot-name). These assertions are compiled into rules that can be executed to reduce input terms. This allows you to make queries like: a) ?- reduce(1/2, X). X = div(1, 2). b) ?- reduce((integral from 0 to pi/2 of sin(x) wrt x), X). X = integral(0, div(pi, 2), sin(x), x) The reduce predicate maps the input term into the internal representation. The mapping rules provide a knowledgebase with which to interpret the input strings allowing us to end up with a representation in which the semantics are more clearly defined than when we started. The mapping rule: map(var(a) * var(b) becomes times(var(a), var(b))). is compiled into: (X*Y) becomes times(X1, Y1) :- reduce(X, X1), reduce(Y, Y1). This is used by the reduce predicate to solve the query. reduce(X, Y) :- X becomes Y, !. reduce(X, X). Notice that the prolog cut operator is used to prune search to the first solution. In otherwords search is depth-first and deterministic. This means we could use Java or C++ for applying the rules. The internal representation used above is based on the following: plus(X, Y) e.g. X + Y minus(X, Y) e.g. X - Y times(X, Y) e.g. X * Y div(X, Y) e.g. X / Y over(X, Y) e.g. X / Y sqrt(X) e.g. sqrt X up(Base, Script) e.g. X up 2 down(Base, Script) e.g. X down 1 integral(Integrand, X) e.g. integral of sin(x) wrt x integral(Lower, Upper, Integrand, WRT) e.g. integral from 0 to pi/2 of sin(x) wrt x Note that I haven't yet explored the practicalities of multiple integrals, but full nesting will certainly work, e.g. integral from l to u of (integral from l1 to u1 of f(x, y) wrt x) wrt y This becomes: integral(l, u, integral(l1, u1, f(x, y), x), y). Which is isomorphic to Patrick's example: Int[l, u, Int[l1, u1, f(x, y), dx], dy] Except that my representation uses x and y instead of dx and dy. It would be nice to weaken the need for explicit nesting but this can't be done while I continue to rely on prolog's in-built term parser. My goal is to be very flexible as to the syntax for such things. The important part is the internal representation not the surface syntax, as the internal representation is the basis for rendering and exchange with math manipulation packages. The next step is to define the lexical syntax and to create a full blown operator precedence parser which will allow us to implement the full notation, without the restrictions imposed by the syntax for prolog terms, e.g. prolog won't let you use `_' as an operator. Once this has been done, then I will be in a position to experiment with inferring times(x, y) from "x y", and to support `_' for subscripts and `{' and `}' for invisible brackets etc. I also look forward to experimenting with how identifier declarations can be exploited to control inference of semantics, e.g. for raising and lowering operators. Note that the internal representation has some redundancies (e.g. div and over) that are needed to preserve the visual distinctions for rendering purposes. -- Dave Raggett <dsr@w3.org> tel: +1 (617) 258 5741 fax: +1 (617) 258 5999 World Wide Web Consortium, 545 Technology Square, Cambridge, MA 02139 url = http://www.w3.org/People/RaggettReceived on Friday, 12 April 1996 15:18:53 UTC
This archive was generated by hypermail 2.4.0 : Saturday, 15 April 2023 17:19:56 UTC