Recent changes to this wiki:

changes
diff --git a/cps.mdwn b/cps.mdwn
index 4c40a66..d7752f4 100644
--- a/cps.mdwn
+++ b/cps.mdwn
@@ -282,4 +282,5 @@ can mix and match:

This xform interleaves call-by-name and call-by-value in layers,
according to the depth of embedding.
-
+(Cf. page 4 of Reynold's 1974 paper ftp://ftp.cs.cmu.edu/user/jcr/reldircont.pdf (equation (4) and the
+explanation in the paragraph below.)


changes
diff --git a/cps.mdwn b/cps.mdwn
--- a/cps.mdwn
+++ b/cps.mdwn
@@ -252,3 +252,34 @@ term.

Excercise: what should the function ' be for the CBV xform?  Hint:
+
+
+Other CPS transforms
+--------------------
+
+It is easy to think that CBN and CBV are the only two CPS transforms.
+(We've already seen a variant on call-by-value one of the excercises above.)
+
+In fact, the number of distinct transforms is unbounded.  For
+instance, here is a variant of CBV that uses the same types as CBN:
+
+    <x> = x
+    <\xM> = \k.k(\x<M>)
+    <MN> = \k.<M>(\m.<N>(\n.m(\k.kn)k))
+
+Try reducing <(\x.x) ((\y.y) (\z.z))> I to convince yourself that
+this is a version of call-by-value.
+
+Once we have two evaluation strategies that rely on the same types, we
+can mix and match:
+
+    [x] = x
+    <x> = x
+    [\xM] = \k.k(\x<M>)
+    <\xM] = \k.k(\x[M])
+    [MN] = \k.<M>(\m.m<N>k)
+    <MN> = \k.[M](\m.[N](\n.m(\k.kn)k))
+
+This xform interleaves call-by-name and call-by-value in layers,
+according to the depth of embedding.
+


changes
diff --git a/cps.mdwn b/cps.mdwn
--- a/cps.mdwn
+++ b/cps.mdwn
@@ -180,8 +180,8 @@ Questions and exercises:

1. Prove that {(\x.y)(ww)} does not terminate.

-2. Why is the CBN xform for variables [x] = x' instead of something
-involving kappas?
+2. Why is the CBN xform for variables [x] = x instead of something
+involving kappas (i.e., k's)?

3. Write an Ocaml function that takes a lambda term and returns a
CPS-xformed lambda term.  You can use the following data declaration:
@@ -196,6 +196,10 @@ CBV) more completely and carefully.
5. What happens (in terms of evaluation order) when the application
rule for CBV CPS is changed to {MN} = \k.{N}(\n.{M}(\m.mnk))?

+6. A term and its CPS xform are different lambda terms.  Yet in some
+sense they "do" the same thing computationally.  Make this sense
+precise.
+

Thinking through the types
--------------------------


changes
diff --git a/cps.mdwn b/cps.mdwn
index a3f0459..6668b48 100644
--- a/cps.mdwn
+++ b/cps.mdwn
@@ -69,16 +69,16 @@ what the CPS is doing, and how.
In order for the CPS to work, we have to adopt a new restriction on
beta reduction: beta reduction does not occur underneath a lambda.
That is, (\x.y)z reduces to z, but \u.(\x.y)z does not reduce to
-\w.z, because the \w protects the redex in the body from
-reduction.  (In this context, a redex is a part of a term that matches
+\u.z, because the \u protects the redex in the body from
+reduction.  (In this context, a "redex" is a part of a term that matches
the pattern ...((\xM)N)..., i.e., something that can potentially be
the target of beta reduction.)

-reducing the leftmost lambda first: (\x.y)((\x.z)w)  ~~> y
+reducing the leftmost lambda first: (\x.y)((\x.z)u)  ~~> y

-reducing the rightmost lambda first: (\x.y)((\x.z)w)  ~~> (\x.y)z ~~> y
+reducing the rightmost lambda first: (\x.y)((\x.z)u)  ~~> (\x.y)z ~~> y

After using the following call-by-name CPS transform---and assuming
that we never evaluate redexes protected by a lambda---only the first
@@ -91,7 +91,7 @@ Here's the CPS transform defined:
[\xM] = \k.k(\x[M])
[MN] = \k.[M](\m.m[N]k)

-Here's the result of applying the transform to our problem term:
+Here's the result of applying the transform to our simple example:

[(\x.y)((\x.z)u)] =
\k.[\x.y](\m.m[(\x.z)u]k) =
@@ -109,13 +109,15 @@ trivial continuation, usually the identity function I = \x.x.
[\x.y](\m.m[(\x.z)u] I) =
(\k.k(\x.y))(\m.m[(\x.z)u] I)
*           *
-    (\x.y)[(\x.z)u] I
+    (\x.y)[(\x.z)u] I           --A--
*
y I

The application to I unlocks the leftmost functor.  Because that
-functor (\x.y) throws away its argument, we never need to expand the
-CPS transform of the argument.
+functor (\x.y) throws away its argument (consider the reduction in the
+line marked (A)), we never need to expand the
+CPS transform of the argument.  This means that we never bother to
+reduce redexes inside the argument.

Compare with a call-by-value xform:

@@ -125,7 +127,7 @@ Compare with a call-by-value xform:

This time the reduction unfolds in a different manner:

-    {(\x.y)((\x.z)w)} I =
+    {(\x.y)((\x.z)u)} I =
(\k.{\x.y}(\m.{(\x.z)u}(\n.mnk))) I
*
{\x.y}(\m.{(\x.z)u}(\n.mnI)) =
@@ -140,7 +142,7 @@ This time the reduction unfolds in a different manner:
{u}(\n.(\x.{z})n(\n.(\x.{y})nI)) =
(\k.ku)(\n.(\x.{z})n(\n.(\x.{y})nI))
*      *
-    (\x.{z})u(\n.(\x.{y})nI)
+    (\x.{z})u(\n.(\x.{y})nI)       --A--
*
{z}(\n.(\x.{y})nI) =
(\k.kz)(\n.(\x.{y})nI)
@@ -152,6 +154,9 @@ This time the reduction unfolds in a different manner:
*
I y

+In this case, the argument does get evaluated: consider the reduction
+in the line marked (A).
+
Both xforms make the following guarantee: as long as redexes
underneath a lambda are never evaluated, there will be at most one
reduction available at any step in the evaluation.


changes
diff --git a/cps.mdwn b/cps.mdwn
index f869b79..a3f0459 100644
--- a/cps.mdwn
+++ b/cps.mdwn
@@ -216,9 +216,9 @@ for functional types a->b, (a->b)' = ((a' -> &sigma;) -> &sigma;) -> (b' -> &sig

Terms                            Types

-    [x] = \k.xk                      [a] = (a'->&sigma;)->&sigma;
-    [\xM] = \k.k(\x[M])              [a->b] = ((a->b)'->&sigma;)->&sigma;
-    [MN] = \k.[M](\m.m[N]k)          [b] = (b'->&sigma;)->&sigma;
+    [x] = \k.xk                      [a] = (a'->o)->o
+    [\xM] = \k.k(\x[M])              [a->b] = ((a->b)'->o)->o
+    [MN] = \k.[M](\m.m[N]k)          [b] = (b'->o)->o

Remember that types associate to the right.  Let's work through the
application xform and make sure the types are consistent.  We'll have
@@ -227,14 +227,14 @@ the following types:
M:a->b
N:a
MN:b
-    k:b'->&sigma;
-    [N]:(a'->&sigma;)->&sigma;
-    m:((a'->&sigma;)->&sigma;)->(b'->&sigma;)->&sigma;
-    m[N]:(b'->&sigma;)->&sigma;
-    m[N]k:&sigma;
-    [M]:((a->b)'->&sigma;)->&sigma; = ((((a'->&sigma;)->&sigma;)->(b'->&sigma;)->&sigma;)->&sigma;)->&sigma;
-    [M](\m.m[N]k):&sigma;
-    [MN]:(b'->&sigma;)->&sigma;
+    k:b'->o
+    [N]:(a'->o)->o
+    m:((a'->o)->o)->(b'->o)->o
+    m[N]:(b'->o)->o
+    m[N]k:o
+    [M]:((a->b)'->o)->o = ((((a'->o)->o)->(b'->o)->o)->o)->o
+    [M](\m.m[N]k):o
+    [MN]:(b'->o)->o

Be aware that even though the transform uses the same symbol for the
translation of a variable (i.e., [x] = x), in general the variable


changes
diff --git a/cps.mdwn b/cps.mdwn
index 35d0680..f869b79 100644
--- a/cps.mdwn
+++ b/cps.mdwn
@@ -18,8 +18,8 @@ Evaluation order matters

We've seen this many times.  For instance, consider the following
reductions.  It will be convenient to use the abbreviation w =
-\x.xx.  I'll indicate which lambda is about to be reduced with a *
-underneath:
+\x.xx.  I'll
+indicate which lambda is about to be reduced with a * underneath:

<pre>
(\x.y)(ww)
@@ -68,10 +68,11 @@ what the CPS is doing, and how.

In order for the CPS to work, we have to adopt a new restriction on
beta reduction: beta reduction does not occur underneath a lambda.
-That is, (\x.y)z reduces to z, but \w.(\x.y)z does not, because
-the \w protects the redex in the body from reduction.
-(A redex is a subform ...(\xM)N..., i.e., something that can be the
-target of reduction.)
+That is, (\x.y)z reduces to z, but \u.(\x.y)z does not reduce to
+\w.z, because the \w protects the redex in the body from
+reduction.  (In this context, a redex is a part of a term that matches
+the pattern ...((\xM)N)..., i.e., something that can potentially be
+the target of beta reduction.)

@@ -92,23 +93,23 @@ Here's the CPS transform defined:

Here's the result of applying the transform to our problem term:

-    [(\x.y)((\x.z)w)] =
-    \k.[\x.y](\m.m[(\x.z)w]k) =
-    \k.(\k.k(\x.[y]))(\m.m(\k.[\x.z](\m.m[w]k))k) =
-    \k.(\k.k(\x.y))(\m.m(\k.(\k.k(\x.z))(\m.mwk))k)
+    [(\x.y)((\x.z)u)] =
+    \k.[\x.y](\m.m[(\x.z)u]k) =
+    \k.(\k.k(\x.[y]))(\m.m(\k.[\x.z](\m.m[u]k))k) =
+    \k.(\k.k(\x.y))(\m.m(\k.(\k.k(\x.z))(\m.muk))k)

-Because the initial \k protects the entire transformed term,
-we can't perform any reductions.  In order to see the computation
-unfold, we have to apply the transformed term to a trivial
-continuation, usually the identity function I = \x.x.
+Because the initial \k protects (i.e., takes scope over) the entire
+transformed term, we can't perform any reductions.  In order to watch
+the computation unfold, we have to apply the transformed term to a
+trivial continuation, usually the identity function I = \x.x.

-    [(\x.y)((\x.z)w)] I =
-    (\k.[\x.y](\m.m[(\x.z)w]k)) I
+    [(\x.y)((\x.z)u)] I =
+    (\k.[\x.y](\m.m[(\x.z)u]k)) I
*
-    [\x.y](\m.m[(\x.z)w] I) =
-    (\k.k(\x.y))(\m.m[(\x.z)w] I)
+    [\x.y](\m.m[(\x.z)u] I) =
+    (\k.k(\x.y))(\m.m[(\x.z)u] I)
*           *
-    (\x.y)[(\x.z)w] I
+    (\x.y)[(\x.z)u] I
*
y I

@@ -125,21 +126,21 @@ Compare with a call-by-value xform:
This time the reduction unfolds in a different manner:

{(\x.y)((\x.z)w)} I =
-    (\k.{\x.y}(\m.{(\x.z)w}(\n.mnk))) I
+    (\k.{\x.y}(\m.{(\x.z)u}(\n.mnk))) I
*
-    {\x.y}(\m.{(\x.z)w}(\n.mnI)) =
-    (\k.k(\x.{y}))(\m.{(\x.z)w}(\n.mnI))
+    {\x.y}(\m.{(\x.z)u}(\n.mnI)) =
+    (\k.k(\x.{y}))(\m.{(\x.z)u}(\n.mnI))
*             *
-    {(\x.z)w}(\n.(\x.{y})nI) =
-    (\k.{\x.z}(\m.{w}(\n.mnk)))(\n.(\x.{y})nI)
+    {(\x.z)u}(\n.(\x.{y})nI) =
+    (\k.{\x.z}(\m.{u}(\n.mnk)))(\n.(\x.{y})nI)
*
-    {\x.z}(\m.{w}(\n.mn(\n.(\x.{y})nI))) =
-    (\k.k(\x.{z}))(\m.{w}(\n.mn(\n.(\x.{y})nI)))
+    {\x.z}(\m.{u}(\n.mn(\n.(\x.{y})nI))) =
+    (\k.k(\x.{z}))(\m.{u}(\n.mn(\n.(\x.{y})nI)))
*             *
-    {w}(\n.(\x.{z})n(\n.(\x.{y})nI)) =
-    (\k.kw)(\n.(\x.{z})n(\n.(\x.{y})nI))
+    {u}(\n.(\x.{z})n(\n.(\x.{y})nI)) =
+    (\k.ku)(\n.(\x.{z})n(\n.(\x.{y})nI))
*      *
-    (\x.{z})w(\n.(\x.{y})nI)
+    (\x.{z})u(\n.(\x.{y})nI)
*
{z}(\n.(\x.{y})nI) =
(\k.kz)(\n.(\x.{y})nI)
@@ -156,27 +157,40 @@ underneath a lambda are never evaluated, there will be at most one
reduction available at any step in the evaluation.
That is, all choice is removed from the evaluation process.

+Now let's verify that the CBN CPS avoids the infinite reduction path
+discussed above (remember that w = \x.xx):
+
+    [(\x.y)(ww)] I =
+    (\k.[\x.y](\m.m[ww]k)) I
+     *
+    [\x.y](\m.m[ww]I) =
+    (\k.k(\x.y))(\m.m[ww]I)
+     *             *
+    (\x.y)[ww]I
+     *
+    y I
+
+
Questions and exercises:

-1. Why is the CBN xform for variables [x] = x' instead of something
+1. Prove that {(\x.y)(ww)} does not terminate.
+
+2. Why is the CBN xform for variables [x] = x' instead of something
involving kappas?

-2. Write an Ocaml function that takes a lambda term and returns a
+3. Write an Ocaml function that takes a lambda term and returns a
CPS-xformed lambda term.  You can use the following data declaration:

type form = Var of char | Abs of char * form | App of form * form;;

-3. What happens (in terms of evaluation order) when the application
-rule for CBN CPS is changed to [MN] = \k.[N](\n.[M]nk)?  Likewise,
-What happens when the application rule for CBV CPS is changed to
-{MN} = \k.{N}(\n.{M}(\m.mnk))?
+4. The discussion above talks about the "leftmost" redex, or the
+"rightmost".  But these words apply accurately only in a special set
+of terms.  Characterize the order of evaluation for CBN (likewise, for
+CBV) more completely and carefully.

-4. What happens when the application rules for the CPS xforms are changed to
+5. What happens (in terms of evaluation order) when the application
+rule for CBV CPS is changed to {MN} = \k.{N}(\n.{M}(\m.mnk))?

-<pre>
-   [MN] = \k.{M}(\m.m{N}k)
-   {MN} = \k.[M](\m.[N](\n.mnk))
-</pre>

Thinking through the types
--------------------------
@@ -196,15 +210,15 @@ the transform will be a function of type &rho; --> &sigma; for some
choice of &rho;.

We'll need an ancilliary function ': for any ground type a, a' = a;
-for functional types a->b, (a->b)' = ((a' -> o) -> o) -> (b' -> o) -> o.
+for functional types a->b, (a->b)' = ((a' -> &sigma;) -> &sigma;) -> (b' -> &sigma;) -> &sigma;.

Call by name transform

Terms                            Types

-    [x] = \k.xk                      [a] = (a'->o)->o
-    [\xM] = \k.k(\x[M])              [a->b] = ((a->b)'->o)->o
-    [MN] = \k.[M](\m.m[N]k)          [b] = (b'->o)->o
+    [x] = \k.xk                      [a] = (a'->&sigma;)->&sigma;
+    [\xM] = \k.k(\x[M])              [a->b] = ((a->b)'->&sigma;)->&sigma;
+    [MN] = \k.[M](\m.m[N]k)          [b] = (b'->&sigma;)->&sigma;

Remember that types associate to the right.  Let's work through the
application xform and make sure the types are consistent.  We'll have
@@ -213,16 +227,19 @@ the following types:
M:a->b
N:a
MN:b
-    k:b'->o
-    [N]:(a'->o)->o
-    m:((a'->o)->o)->(b'->o)->o
-    m[N]:(b'->o)->o
-    m[N]k:o
-    [M]:((a->b)'->o)->o = ((((a'->o)->o)->(b'->o)->o)->o)->o
-    [M](\m.m[N]k):o
-    [MN]:(b'->o)->o
-
-Note that even though the transform uses the same symbol for the
-translation of a variable, in general it will have a different type in
-the transformed term.
-
+    k:b'->&sigma;
+    [N]:(a'->&sigma;)->&sigma;
+    m:((a'->&sigma;)->&sigma;)->(b'->&sigma;)->&sigma;
+    m[N]:(b'->&sigma;)->&sigma;
+    m[N]k:&sigma;
+    [M]:((a->b)'->&sigma;)->&sigma; = ((((a'->&sigma;)->&sigma;)->(b'->&sigma;)->&sigma;)->&sigma;)->&sigma;
+    [M](\m.m[N]k):&sigma;
+    [MN]:(b'->&sigma;)->&sigma;
+
+Be aware that even though the transform uses the same symbol for the
+translation of a variable (i.e., [x] = x), in general the variable

(Diff truncated)

Modifications
diff --git a/cps.mdwn b/cps.mdwn
index bb478c6..35d0680 100644
--- a/cps.mdwn
+++ b/cps.mdwn
@@ -71,30 +71,30 @@ beta reduction: beta reduction does not occur underneath a lambda.
That is, (\x.y)z reduces to z, but \w.(\x.y)z does not, because
the \w protects the redex in the body from reduction.
(A redex is a subform ...(\xM)N..., i.e., something that can be the
-target of beta reduction.)
+target of reduction.)

reducing the leftmost lambda first: (\x.y)((\x.z)w)  ~~> y

-reducing the rightmost lambda first: (\x.y)((\x.z)w)  ~~> (x.y)z ~~> y
+reducing the rightmost lambda first: (\x.y)((\x.z)w)  ~~> (\x.y)z ~~> y

After using the following call-by-name CPS transform---and assuming
that we never evaluate redexes protected by a lambda---only the first
reduction path will be available: we will have gained control over the
order in which beta reductions are allowed to be performed.

-Here's the CPS transform:
+Here's the CPS transform defined:

-    [x] => x
-    [\xM] => \k.k(\x[M])
-    [MN] => \k.[M](\m.m[N]k)
+    [x] = x
+    [\xM] = \k.k(\x[M])
+    [MN] = \k.[M](\m.m[N]k)

Here's the result of applying the transform to our problem term:

-    [(\x.y)((\x.z)w)]
-    \k.[\x.y](\m.m[(\x.z)w]k)
-    \k.(\k.k(\x.[y]))(\m.m(\k.[\x.z](\m.m[w]k))k)
+    [(\x.y)((\x.z)w)] =
+    \k.[\x.y](\m.m[(\x.z)w]k) =
+    \k.(\k.k(\x.[y]))(\m.m(\k.[\x.z](\m.m[w]k))k) =
\k.(\k.k(\x.y))(\m.m(\k.(\k.k(\x.z))(\m.mwk))k)

Because the initial \k protects the entire transformed term,
@@ -102,11 +102,14 @@ we can't perform any reductions.  In order to see the computation
unfold, we have to apply the transformed term to a trivial
continuation, usually the identity function I = \x.x.

-    [(\x.y)((\x.z)w)] I
-    \k.[\x.y](\m.m[(\x.z)w]k) I
-    [\x.y](\m.m[(\x.z)w] I)
+    [(\x.y)((\x.z)w)] I =
+    (\k.[\x.y](\m.m[(\x.z)w]k)) I
+     *
+    [\x.y](\m.m[(\x.z)w] I) =
(\k.k(\x.y))(\m.m[(\x.z)w] I)
+     *           *
(\x.y)[(\x.z)w] I
+     *
y I

The application to I unlocks the leftmost functor.  Because that
@@ -115,28 +118,37 @@ CPS transform of the argument.

Compare with a call-by-value xform:

-    {x} => \k.kx
-    {\aM} => \k.k(\a{M})
-    {MN} => \k.{M}(\m.{N}(\n.mnk))
+    {x} = \k.kx
+    {\aM} = \k.k(\a{M})
+    {MN} = \k.{M}(\m.{N}(\n.mnk))

This time the reduction unfolds in a different manner:

-    {(\x.y)((\x.z)w)} I
+    {(\x.y)((\x.z)w)} I =
(\k.{\x.y}(\m.{(\x.z)w}(\n.mnk))) I
-    {\x.y}(\m.{(\x.z)w}(\n.mnI))
+     *
+    {\x.y}(\m.{(\x.z)w}(\n.mnI)) =
(\k.k(\x.{y}))(\m.{(\x.z)w}(\n.mnI))
-    {(\x.z)w}(\n.(\x.{y})nI)
+     *             *
+    {(\x.z)w}(\n.(\x.{y})nI) =
(\k.{\x.z}(\m.{w}(\n.mnk)))(\n.(\x.{y})nI)
-    {\x.z}(\m.{w}(\n.mn(\n.(\x.{y})nI)))
+     *
+    {\x.z}(\m.{w}(\n.mn(\n.(\x.{y})nI))) =
(\k.k(\x.{z}))(\m.{w}(\n.mn(\n.(\x.{y})nI)))
-    {w}(\n.(\x.{z})n(\n.(\x.{y})nI))
+     *             *
+    {w}(\n.(\x.{z})n(\n.(\x.{y})nI)) =
(\k.kw)(\n.(\x.{z})n(\n.(\x.{y})nI))
+     *      *
(\x.{z})w(\n.(\x.{y})nI)
-    {z}(\n.(\x.{y})nI)
+     *
+    {z}(\n.(\x.{y})nI) =
(\k.kz)(\n.(\x.{y})nI)
+     *      *
(\x.{y})zI
-    {y}I
+     *
+    {y}I =
(\k.ky)I
+     *
I y

Both xforms make the following guarantee: as long as redexes
@@ -144,7 +156,7 @@ underneath a lambda are never evaluated, there will be at most one
reduction available at any step in the evaluation.
That is, all choice is removed from the evaluation process.

-Questions and excercises:
+Questions and exercises:

1. Why is the CBN xform for variables [x] = x' instead of something
involving kappas?
@@ -177,22 +189,22 @@ well-typed.  But what will the type of the transformed term be?

The transformed terms all have the form \k.blah.  The rule for the
CBN xform of a variable appears to be an exception, but instead of
-writing [x] => x, we can write [x] => \k.xk, which is
+writing [x] = x, we can write [x] = \k.xk, which is
eta-equivalent.  The k's are continuations: functions from something
to a result.  Let's use &sigma; as the result type.  The each k in
the transform will be a function of type &rho; --> &sigma; for some
choice of &rho;.

We'll need an ancilliary function ': for any ground type a, a' = a;
-for functional types a->b, (a->b)' = a' -> (b' -> o) -> o.
+for functional types a->b, (a->b)' = ((a' -> o) -> o) -> (b' -> o) -> o.

Call by name transform

Terms                            Types

-    [x] => \k.xk                     [a] => (a'->o)->o
-    [\xM] => \k.k(\x[M])             [a->b] => ((a->b)'->o)->o
-    [MN] => \k.[M](\m.m[N]k)         [b] => (b'->o)->o
+    [x] = \k.xk                      [a] = (a'->o)->o
+    [\xM] = \k.k(\x[M])              [a->b] = ((a->b)'->o)->o
+    [MN] = \k.[M](\m.m[N]k)          [b] = (b'->o)->o

Remember that types associate to the right.  Let's work through the
application xform and make sure the types are consistent.  We'll have
@@ -202,11 +214,11 @@ the following types:
N:a
MN:b
k:b'->o
-    [N]:a'
-    m:a'->(b'->o)->o
+    [N]:(a'->o)->o
+    m:((a'->o)->o)->(b'->o)->o
m[N]:(b'->o)->o
m[N]k:o
-    [M]:((a->b)'->o)->o = ((a'->(b'->o)->o)->o)->o
+    [M]:((a->b)'->o)->o = ((((a'->o)->o)->(b'->o)->o)->o)->o
[M](\m.m[N]k):o
[MN]:(b'->o)->o


changes
diff --git a/cps.mdwn b/cps.mdwn
index a9842d1..bb478c6 100644
--- a/cps.mdwn
+++ b/cps.mdwn
@@ -115,27 +115,27 @@ CPS transform of the argument.

Compare with a call-by-value xform:

-    <x> => \k.kx
-    <\aM> => \k.k(\a<M>)
-    <MN> => \k.<M>(\m.<N>(\n.mnk))
+    {x} => \k.kx
+    {\aM} => \k.k(\a{M})
+    {MN} => \k.{M}(\m.{N}(\n.mnk))

This time the reduction unfolds in a different manner:

-    <(\x.y)((\x.z)w)> I
-    (\k.<\x.y>(\m.<(\x.z)w>(\n.mnk))) I
-    <\x.y>(\m.<(\x.z)w>(\n.mnI))
-    (\k.k(\x.<y>))(\m.<(\x.z)w>(\n.mnI))
-    <(\x.z)w>(\n.(\x.<y>)nI)
-    (\k.<\x.z>(\m.<w>(\n.mnk)))(\n.(\x.<y>)nI)
-    <\x.z>(\m.<w>(\n.mn(\n.(\x.<y>)nI)))
-    (\k.k(\x.<z>))(\m.<w>(\n.mn(\n.(\x.<y>)nI)))
-    <w>(\n.(\x.<z>)n(\n.(\x.<y>)nI))
-    (\k.kw)(\n.(\x.<z>)n(\n.(\x.<y>)nI))
-    (\x.<z>)w(\n.(\x.<y>)nI)
-    <z>(\n.(\x.<y>)nI)
-    (\k.kz)(\n.(\x.<y>)nI)
-    (\x.<y>)zI
-    <y>I
+    {(\x.y)((\x.z)w)} I
+    (\k.{\x.y}(\m.{(\x.z)w}(\n.mnk))) I
+    {\x.y}(\m.{(\x.z)w}(\n.mnI))
+    (\k.k(\x.{y}))(\m.{(\x.z)w}(\n.mnI))
+    {(\x.z)w}(\n.(\x.{y})nI)
+    (\k.{\x.z}(\m.{w}(\n.mnk)))(\n.(\x.{y})nI)
+    {\x.z}(\m.{w}(\n.mn(\n.(\x.{y})nI)))
+    (\k.k(\x.{z}))(\m.{w}(\n.mn(\n.(\x.{y})nI)))
+    {w}(\n.(\x.{z})n(\n.(\x.{y})nI))
+    (\k.kw)(\n.(\x.{z})n(\n.(\x.{y})nI))
+    (\x.{z})w(\n.(\x.{y})nI)
+    {z}(\n.(\x.{y})nI)
+    (\k.kz)(\n.(\x.{y})nI)
+    (\x.{y})zI
+    {y}I
(\k.ky)I
I y

@@ -157,13 +157,13 @@ CPS-xformed lambda term.  You can use the following data declaration:
3. What happens (in terms of evaluation order) when the application
rule for CBN CPS is changed to [MN] = \k.[N](\n.[M]nk)?  Likewise,
What happens when the application rule for CBV CPS is changed to
-<MN> = \k.<N>(\n.<M>(\m.mnk))?
+{MN} = \k.{N}(\n.{M}(\m.mnk))?

4. What happens when the application rules for the CPS xforms are changed to

<pre>
-   [MN] = \k.<M>(\m.m<N>k)
-   <MN> = \k.[M](\m.[N](\n.mnk))
+   [MN] = \k.{M}(\m.m{N}k)
+   {MN} = \k.[M](\m.[N](\n.mnk))
</pre>

Thinking through the types


changes
diff --git a/cps.mdwn b/cps.mdwn
index e1f7f58..a9842d1 100644
--- a/cps.mdwn
+++ b/cps.mdwn
@@ -161,9 +161,10 @@ What happens when the application rule for CBV CPS is changed to

4. What happens when the application rules for the CPS xforms are changed to

+<pre>
[MN] = \k.<M>(\m.m<N>k)
<MN> = \k.[M](\m.[N](\n.mnk))
-
+</pre>

Thinking through the types
--------------------------


changes
diff --git a/cps.mdwn b/cps.mdwn
index 259f412..e1f7f58 100644
--- a/cps.mdwn
+++ b/cps.mdwn
@@ -156,13 +156,13 @@ CPS-xformed lambda term.  You can use the following data declaration:

3. What happens (in terms of evaluation order) when the application
rule for CBN CPS is changed to [MN] = \k.[N](\n.[M]nk)?  Likewise,
-What happens when the application rule for CBV CPS is changed to <MN>
-= \k.[N](\n.[M](\m.mnk))?
+What happens when the application rule for CBV CPS is changed to
+<MN> = \k.<N>(\n.<M>(\m.mnk))?

4. What happens when the application rules for the CPS xforms are changed to

-    [MN] = \k.<M>(\m.m<N>k)
-    <MN> = \k.[M](\m.[N](\n.mnk))
+   [MN] = \k.<M>(\m.m<N>k)
+   <MN> = \k.[M](\m.[N](\n.mnk))

Thinking through the types


changes
diff --git a/cps.mdwn b/cps.mdwn
index 73edf0d..259f412 100644
--- a/cps.mdwn
+++ b/cps.mdwn
@@ -9,8 +9,7 @@ A lucid discussion of evaluation order in the
context of the lambda calculus can be found here:
[Sestoft: Demonstrating Lambda Calculus Reduction](http://www.itu.dk/~sestoft/papers/mfps2001-sestoft.pdf).
Sestoft also provides a lovely on-line lambda evaluator:
-[Sestoft: Lambda calculus reduction workbench]
-(http://www.itu.dk/~sestoft/lamreduce/index.html),
+[Sestoft: Lambda calculus reduction workbench](http://www.itu.dk/~sestoft/lamreduce/index.html),
which allows you to select multiple evaluation strategies,
and to see reductions happen step by step.

@@ -63,7 +62,7 @@ And we never get the recursion off the ground.
Using a Continuation Passing Style transform to control order of evaluation
---------------------------------------------------------------------------

-We'll exhibit and explore the technique of transforming a lambda term
+We'll present a technique for controlling evaluation order by transforming a lambda term
using a Continuation Passing Style transform (CPS), then we'll explore
what the CPS is doing, and how.

@@ -71,12 +70,14 @@ In order for the CPS to work, we have to adopt a new restriction on
beta reduction: beta reduction does not occur underneath a lambda.
That is, (\x.y)z reduces to z, but \w.(\x.y)z does not, because
the \w protects the redex in the body from reduction.
+(A redex is a subform ...(\xM)N..., i.e., something that can be the
+target of beta reduction.)

-reducing the leftmost lambda first: (\x.y)((\x.z)w)  ~~> y'
+reducing the leftmost lambda first: (\x.y)((\x.z)w)  ~~> y

-reducing the rightmost lambda first: (\x.y)((\x.z)w)  ~~> (x.y)z ~~> y'
+reducing the rightmost lambda first: (\x.y)((\x.z)w)  ~~> (x.y)z ~~> y

After using the following call-by-name CPS transform---and assuming
that we never evaluate redexes protected by a lambda---only the first
@@ -140,7 +141,7 @@ This time the reduction unfolds in a different manner:

Both xforms make the following guarantee: as long as redexes
underneath a lambda are never evaluated, there will be at most one
-reduction avaialble at any step in the evaluation.
+reduction available at any step in the evaluation.
That is, all choice is removed from the evaluation process.

Questions and excercises:
@@ -149,14 +150,14 @@ Questions and excercises:
involving kappas?

2. Write an Ocaml function that takes a lambda term and returns a
-CPS-xformed lambda term.
+CPS-xformed lambda term.  You can use the following data declaration:

type form = Var of char | Abs of char * form | App of form * form;;

3. What happens (in terms of evaluation order) when the application
rule for CBN CPS is changed to [MN] = \k.[N](\n.[M]nk)?  Likewise,
What happens when the application rule for CBV CPS is changed to <MN>
-= \k.[N](\n.[M](\m.mnk))'?
+= \k.[N](\n.[M](\m.mnk))?

4. What happens when the application rules for the CPS xforms are changed to

@@ -177,8 +178,8 @@ The transformed terms all have the form \k.blah.  The rule for the
CBN xform of a variable appears to be an exception, but instead of
writing [x] => x, we can write [x] => \k.xk, which is
eta-equivalent.  The k's are continuations: functions from something
-to a result.  Let's use $sigma; as the result type. The each k in -the transform will be a function of type &rho; --> &sigma; for some +to a result. Let's use &sigma; as the result type. The each k in +the transform will be a function of type &rho; --> &sigma; for some choice of &rho;. We'll need an ancilliary function ': for any ground type a, a' = a;  changes diff --git a/cps.mdwn b/cps.mdwn index 7f037ca..73edf0d 100644 --- a/cps.mdwn +++ b/cps.mdwn @@ -5,13 +5,14 @@ We know that evaluation order matters. We're beginning to learn how to gain some control over order of evaluation (think of Jim's abort handler). We continue to reason about order of evaluation. -A superbly clear and lucid discussion can be found here: -[Sestoft: Demonstrating Lambda Calculus Reduction](http://tinyurl.com/27nd3ub). -Sestoft also provides a really lovely lambda evaluator, +A lucid discussion of evaluation order in the +context of the lambda calculus can be found here: +[Sestoft: Demonstrating Lambda Calculus Reduction](http://www.itu.dk/~sestoft/papers/mfps2001-sestoft.pdf). +Sestoft also provides a lovely on-line lambda evaluator: +[Sestoft: Lambda calculus reduction workbench] +(http://www.itu.dk/~sestoft/lamreduce/index.html), which allows you to select multiple evaluation strategies, -and to see reductions happen step by step: -[Sestoft's lambda reduction webpage](http://ellemose.dina.kvl.dk/~sestoft/lamreduce/lamframes.html). - +and to see reductions happen step by step. Evaluation order matters ------------------------ @@ -59,67 +60,155 @@ Y (\f n. blah) = And we never get the recursion off the ground. -Restricting evaluation: call by name, call by value ---------------------------------------------------- +Using a Continuation Passing Style transform to control order of evaluation +--------------------------------------------------------------------------- -One way to begin to gain some control is by adjusting our notion of -beta reduction. This strategy has some of the flavor of adding types, -but is actually a part of the untyped calculus. +We'll exhibit and explore the technique of transforming a lambda term +using a Continuation Passing Style transform (CPS), then we'll explore +what the CPS is doing, and how. -In order to have a precise discussion, we'll need some vocabulary. -We've been talking about normal form (lambda terms that can't be -further reduced), and leftmost evaluation (the reduction strategy of -always choosing the left most reducible lambda); we'll need to refine -both of those concepts. +In order for the CPS to work, we have to adopt a new restriction on +beta reduction: beta reduction does not occur underneath a lambda. +That is, (\x.y)z reduces to z, but \w.(\x.y)z does not, because +the \w protects the redex in the body from reduction. -Kinds of normal form: ---------------------- +Start with a simple form that has two different reduction paths: -Recall that there are three kinds of lambda term. Let a be an -arbitrary variable, and let M and N be arbitrary terms: +reducing the leftmost lambda first: (\x.y)((\x.z)w) ~~> y' -<pre> -The pure untyped lambda calculus (again): +reducing the rightmost lambda first: (\x.y)((\x.z)w) ~~> (x.y)z ~~> y' - Form Examples -Variable a x, y, z -Abstract \aM \x.x, \x.y, \x.\y.y -Application MN (x x), ((\x.x) y), ((\x.x)(\y.y)) -</pre> +After using the following call-by-name CPS transform---and assuming +that we never evaluate redexes protected by a lambda---only the first +reduction path will be available: we will have gained control over the +order in which beta reductions are allowed to be performed. + +Here's the CPS transform: + + [x] => x + [\xM] => \k.k(\x[M]) + [MN] => \k.[M](\m.m[N]k) + +Here's the result of applying the transform to our problem term: + + [(\x.y)((\x.z)w)] + \k.[\x.y](\m.m[(\x.z)w]k) + \k.(\k.k(\x.[y]))(\m.m(\k.[\x.z](\m.m[w]k))k) + \k.(\k.k(\x.y))(\m.m(\k.(\k.k(\x.z))(\m.mwk))k) + +Because the initial \k protects the entire transformed term, +we can't perform any reductions. In order to see the computation +unfold, we have to apply the transformed term to a trivial +continuation, usually the identity function I = \x.x. + + [(\x.y)((\x.z)w)] I + \k.[\x.y](\m.m[(\x.z)w]k) I + [\x.y](\m.m[(\x.z)w] I) + (\k.k(\x.y))(\m.m[(\x.z)w] I) + (\x.y)[(\x.z)w] I + y I + +The application to I unlocks the leftmost functor. Because that +functor (\x.y) throws away its argument, we never need to expand the +CPS transform of the argument. + +Compare with a call-by-value xform: + + <x> => \k.kx + <\aM> => \k.k(\a<M>) + <MN> => \k.<M>(\m.<N>(\n.mnk)) + +This time the reduction unfolds in a different manner: -It will be helpful to define a *redex*, which is a lambda term of -the form ((\aM) N). That is, a redex is a form for which beta -reduction is defined (ignoring, as usual, the manouvering required in -order to avoid variable collision). + <(\x.y)((\x.z)w)> I + (\k.<\x.y>(\m.<(\x.z)w>(\n.mnk))) I + <\x.y>(\m.<(\x.z)w>(\n.mnI)) + (\k.k(\x.<y>))(\m.<(\x.z)w>(\n.mnI)) + <(\x.z)w>(\n.(\x.<y>)nI) + (\k.<\x.z>(\m.<w>(\n.mnk)))(\n.(\x.<y>)nI) + <\x.z>(\m.<w>(\n.mn(\n.(\x.<y>)nI))) + (\k.k(\x.<z>))(\m.<w>(\n.mn(\n.(\x.<y>)nI))) + <w>(\n.(\x.<z>)n(\n.(\x.<y>)nI)) + (\k.kw)(\n.(\x.<z>)n(\n.(\x.<y>)nI)) + (\x.<z>)w(\n.(\x.<y>)nI) + <z>(\n.(\x.<y>)nI) + (\k.kz)(\n.(\x.<y>)nI) + (\x.<y>)zI + <y>I + (\k.ky)I + I y -It will also be helpful to have names for the two components of an -application (M N): we'll call M the *functor*, and N the -*argument*. Note that functor position can be occupied by a variable, -since x is in the functor position of the term (x y). +Both xforms make the following guarantee: as long as redexes +underneath a lambda are never evaluated, there will be at most one +reduction avaialble at any step in the evaluation. +That is, all choice is removed from the evaluation process. -Ok, with that vocabulary, we can distinguish four different types of -normal form: +Questions and excercises: +1. Why is the CBN xform for variables [x] = x' instead of something +involving kappas? +2. Write an Ocaml function that takes a lambda term and returns a +CPS-xformed lambda term. + type form = Var of char | Abs of char * form | App of form * form;; +3. What happens (in terms of evaluation order) when the application +rule for CBN CPS is changed to [MN] = \k.[N](\n.[M]nk)? Likewise, +What happens when the application rule for CBV CPS is changed to <MN> += \k.[N](\n.[M](\m.mnk))'? +4. What happens when the application rules for the CPS xforms are changed to + [MN] = \k.<M>(\m.m<N>k) + <MN> = \k.[M](\m.[N](\n.mnk)) -Take Plotkin's CBN CPS: -[x] ~~> x -[\xM] ~~> \k.k(\x[M]) -[MN] ~~> \k.[M](\m.m[N]k) +Thinking through the types +-------------------------- + +This discussion is based on [Meyer and Wand 1985](http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.44.7943&rep=rep1&type=pdf). -let w = \x.xx in +Let's say we're working in the simply-typed lambda calculus. +Then if the original term is well-typed, the CPS xform will also be +well-typed. But what will the type of the transformed term be? -[(\xy)(ww)] ~~> -\k.[\xy](\m.m[ww]k) ~~> -\k.[\xy](\m.m(\k.[w](\m.m[w]k))k) ~~> -\k.[\xy](\m.m(\k.(\k.k(\x[xx]))(\m.m[w]k))k) ~~> beta* -\k.[\xy](\m.m(\k.(\x[xx])[w]k)k) ~~> -\k.[\xy](\m.m(\k.(\x(\k.[x](\m.m[x]k)))[w]k)k) ~~> -\k.[\xy](\m.m(\k.(\x(\k.x(\m.mxk)))[w]k)k) ~~> beta -\k.[\xy](\m.m(\k.[w](\m.m[w]k))k) --- same as second line! +The transformed terms all have the form \k.blah. The rule for the +CBN xform of a variable appears to be an exception, but instead of +writing [x] => x, we can write [x] => \k.xk, which is +eta-equivalent. The k's are continuations: functions from something +to a result. Let's use$sigma; as the result type.  The each k in
+the transform will be a function of type &rho; --> &sigma; for some
+choice of &rho;.
+
+We'll need an ancilliary function ': for any ground type a, a' = a;
+for functional types a->b, (a->b)' = a' -> (b' -> o) -> o.
+
+    Call by name transform
+
+    Terms                            Types

(Diff truncated)

diff --git a/cps.mdwn b/cps.mdwn
new file mode 100644
index 0000000..7f037ca
--- /dev/null
+++ b/cps.mdwn
@@ -0,0 +1,125 @@
+Gaining control over order of evaluation
+----------------------------------------
+
+We know that evaluation order matters.  We're beginning to learn how
+to gain some control over order of evaluation (think of Jim's abort handler).
+We continue to reason about order of evaluation.
+
+A superbly clear and lucid discussion can be found here:
+[Sestoft: Demonstrating Lambda Calculus Reduction](http://tinyurl.com/27nd3ub).
+Sestoft also provides a really lovely lambda evaluator,
+which allows you to select multiple evaluation strategies,
+and to see reductions happen step by step:
+[Sestoft's lambda reduction webpage](http://ellemose.dina.kvl.dk/~sestoft/lamreduce/lamframes.html).
+
+
+Evaluation order matters
+------------------------
+
+We've seen this many times.  For instance, consider the following
+reductions.  It will be convenient to use the abbreviation w =
+\x.xx.  I'll indicate which lambda is about to be reduced with a *
+underneath:
+
+<pre>
+(\x.y)(ww)
+ *
+y
+</pre>
+
+Done!  We have a normal form.  But if we reduce using a different
+strategy, things go wrong:
+
+<pre>
+(\x.y)(ww) =
+(\x.y)((\x.xx)w) =
+        *
+(\x.y)(ww) =
+(\x.y)((\x.xx)w) =
+        *
+(\x.y)(ww)
+</pre>
+
+Etc.
+
+As a second reminder of when evaluation order matters, consider using
+Y = \f.(\h.f(hh))(\h.f(hh)) as a fixed point combinator to define a recursive function:
+
+<pre>
+Y (\f n. blah) =
+(\f.(\h.f(hh))(\h.f(hh))) (\f n. blah)
+     *
+(\f.f((\h.f(hh))(\h.f(hh)))) (\f n. blah)
+       *
+(\f.f(f((\h.f(hh))(\h.f(hh))))) (\f n. blah)
+         *
+(\f.f(f(f((\h.f(hh))(\h.f(hh)))))) (\f n. blah)
+</pre>
+
+And we never get the recursion off the ground.
+
+
+Restricting evaluation: call by name, call by value
+---------------------------------------------------
+
+One way to begin to gain some control is by adjusting our notion of
+beta reduction.  This strategy has some of the flavor of adding types,
+but is actually a part of the untyped calculus.
+
+In order to have a precise discussion, we'll need some vocabulary.
+We've been talking about normal form (lambda terms that can't be
+further reduced), and leftmost evaluation (the reduction strategy of
+always choosing the left most reducible lambda); we'll need to refine
+both of those concepts.
+
+Kinds of normal form:
+---------------------
+
+Recall that there are three kinds of lambda term.  Let a be an
+arbitrary variable, and let M and N be arbitrary terms:
+
+<pre>
+The pure untyped lambda calculus (again):
+
+             Form     Examples
+Variable     a        x, y, z
+Abstract     \aM      \x.x, \x.y, \x.\y.y
+Application  MN       (x x), ((\x.x) y), ((\x.x)(\y.y))
+</pre>
+
+It will be helpful to define a *redex*, which is a lambda term of
+the form ((\aM) N).  That is, a redex is a form for which beta
+reduction is defined (ignoring, as usual, the manouvering required in
+order to avoid variable collision).
+
+It will also be helpful to have names for the two components of an
+application (M N): we'll call M the *functor*, and N the
+*argument*.  Note that functor position can be occupied by a variable,
+since x is in the functor position of the term (x y).
+
+Ok, with that vocabulary, we can distinguish four different types of
+normal form:
+
+
+
+
+
+
+
+Take Plotkin's CBN CPS:
+
+[x] ~~> x
+[\xM] ~~> \k.k(\x[M])
+[MN] ~~> \k.[M](\m.m[N]k)
+
+let w = \x.xx in
+
+[(\xy)(ww)] ~~>
+\k.[\xy](\m.m[ww]k) ~~>
+\k.[\xy](\m.m(\k.[w](\m.m[w]k))k) ~~>
+\k.[\xy](\m.m(\k.(\k.k(\x[xx]))(\m.m[w]k))k) ~~> beta*
+\k.[\xy](\m.m(\k.(\x[xx])[w]k)k) ~~>
+\k.[\xy](\m.m(\k.(\x(\k.[x](\m.m[x]k)))[w]k)k) ~~>
+\k.[\xy](\m.m(\k.(\x(\k.x(\m.mxk)))[w]k)k) ~~> beta
+\k.[\xy](\m.m(\k.[w](\m.m[w]k))k) --- same as second line!
+


diff --git a/index.iki b/index.iki
index 82ed0cc..cdcf132 100644
--- a/index.iki
+++ b/index.iki
@@ -8,11 +8,6 @@ the Linguistics building at 10 Washington Place, in room 104 (back of the first
One student session will be held every Wednesday from 3-4 on the
fourth floor at 10 Washington Place.

-Testing:
-
-    What happens in [[Translating between OCaml Scheme and Haskell]] code block?
-
-End of code block.

## Announcements ##


diff --git a/sandbox.mdwn b/sandbox.mdwn
index 4a28975..a8bf5f4 100644
--- a/sandbox.mdwn
+++ b/sandbox.mdwn
@@ -5,6 +5,13 @@ Here is [[!img y-combinator.jpg size="200x200" alt="clouds"]]. And rest of parag
Try some math:
<img src="/cgi-bin/mathtex.cgi?x=\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^\i}">. Okay, that's it!

+Testing:
+
+    What happens in [[Translating between OCaml Scheme and Haskell]] code block?
+
+End of code block.
+
+
----
[[!inline pages="tagged(foo)" show=0 archive=yes]]


diff --git a/index.iki b/index.iki
index 74fdec0..82ed0cc 100644
--- a/index.iki
+++ b/index.iki
@@ -8,8 +8,11 @@ the Linguistics building at 10 Washington Place, in room 104 (back of the first
One student session will be held every Wednesday from 3-4 on the
fourth floor at 10 Washington Place.

-This $$\int _a ^b f^{\prime}(x)\, dx = f(b) - f(a), -\qquad FTOC I$$ is enough for now.
+Testing:
+
+    What happens in [[Translating between OCaml Scheme and Haskell]] code block?
+
+End of code block.

## Announcements ##


diff --git a/index.iki b/index.iki
index b5c3cec..74fdec0 100644
--- a/index.iki
+++ b/index.iki
@@ -8,8 +8,8 @@ the Linguistics building at 10 Washington Place, in room 104 (back of the first
One student session will be held every Wednesday from 3-4 on the
fourth floor at 10 Washington Place.

-This $$\int \color{#8F001A} _a ^b f^{\prime}(x)\, dx = f(b) - f(a), -\qquad \textcolor{pinegreen}{\colorbox{yellow}{FTOC I}}$$ is enough for now.
+This $$\int _a ^b f^{\prime}(x)\, dx = f(b) - f(a), +\qquad FTOC I$$ is enough for now.

## Announcements ##


diff --git a/index.iki b/index.iki
index 2e8390e..b5c3cec 100644
--- a/index.iki
+++ b/index.iki
@@ -8,8 +8,8 @@ the Linguistics building at 10 Washington Place, in room 104 (back of the first
One student session will be held every Wednesday from 3-4 on the
fourth floor at 10 Washington Place.

-This $\int \color{#8F001A} _a ^b f^{\prime}(x)\, dx = f(b) - f(a), -\qquad \textcolor{pinegreen}{\colorbox{yellow}{FTOC I}}$ is enough for now.
+This $$\int \color{#8F001A} _a ^b f^{\prime}(x)\, dx = f(b) - f(a), +\qquad \textcolor{pinegreen}{\colorbox{yellow}{FTOC I}}$$ is enough for now.

## Announcements ##


diff --git a/index.iki b/index.iki
index cdcf132..2e8390e 100644
--- a/index.iki
+++ b/index.iki
@@ -8,6 +8,8 @@ the Linguistics building at 10 Washington Place, in room 104 (back of the first
One student session will be held every Wednesday from 3-4 on the
fourth floor at 10 Washington Place.

+This $\int \color{#8F001A} _a ^b f^{\prime}(x)\, dx = f(b) - f(a), +\qquad \textcolor{pinegreen}{\colorbox{yellow}{FTOC I}}$ is enough for now.

## Announcements ##


diff --git a/index.iki b/index.iki
index d714f00..cdcf132 100644
--- a/index.iki
+++ b/index.iki
@@ -8,7 +8,6 @@ the Linguistics building at 10 Washington Place, in room 104 (back of the first
One student session will be held every Wednesday from 3-4 on the
fourth floor at 10 Washington Place.

-Test some $\frac{a\pi^{2}}{\sqrt{b+c}}$.

## Announcements ##


diff --git a/index.iki b/index.iki
index 3a2b976..d714f00 100644
--- a/index.iki
+++ b/index.iki
@@ -8,6 +8,8 @@ the Linguistics building at 10 Washington Place, in room 104 (back of the first
One student session will be held every Wednesday from 3-4 on the
fourth floor at 10 Washington Place.

+Test some $\frac{a\pi^{2}}{\sqrt{b+c}}$.
+
## Announcements ##

<!--


diff --git a/gitweb.css b/gitweb.css
new file mode 100644
index 0000000..79d7eeb
--- /dev/null
+++ b/gitweb.css
@@ -0,0 +1,598 @@
+body {
+	font-family: sans-serif;
+	font-size: small;
+	border: solid #d9d8d1;
+	border-width: 1px;
+	margin: 10px;
+	background-color: #ffffff;
+	color: #000000;
+}
+
+a {
+	color: #0000cc;
+}
+
+a:hover, a:visited, a:active {
+	color: #880000;
+}
+
+span.cntrl {
+	border: dashed #aaaaaa;
+	border-width: 1px;
+	padding: 0px 2px 0px 2px;
+	margin:  0px 2px 0px 2px;
+}
+
+img.logo {
+	float: right;
+	border-width: 0px;
+}
+
+img.avatar {
+	vertical-align: middle;
+}
+
+a.list img.avatar {
+	border-style: none;
+}
+
+	height: 25px;
+	font-size: 150%;
+	font-weight: bold;
+	background-color: #d9d8d1;
+}
+
+	color: #0000cc;
+}
+
+	color: #880000;
+}
+
+div.page_nav {
+}
+
+div.page_nav a:visited {
+	color: #0000cc;
+}
+
+div.page_path {
+	font-weight: bold;
+	border: solid #d9d8d1;
+	border-width: 0px 0px 1px;
+}
+
+div.page_footer {
+	height: 17px;
+	background-color: #d9d8d1;
+}
+
+div.page_footer_text {
+	float: left;
+	color: #555555;
+	font-style: italic;
+}
+
+div#generating_info {
+	margin: 4px;
+	font-size: smaller;
+	text-align: center;
+	color: #505050;
+}
+
+div.page_body {
+	font-family: monospace;
+}
+
+div.title, a.title {
+	display: block;
+	font-weight: bold;
+	background-color: #edece6;
+	text-decoration: none;
+	color: #000000;
+}
+
+}
+
+a.title:hover {
+	background-color: #d9d8d1;
+}
+
+div.title_text {
+	border: solid #d9d8d1;
+	border-width: 0px 0px 1px;
+	font-family: monospace;
+}
+
+div.log_body {
+	padding: 8px 8px 8px 150px;
+}
+
+span.age {
+	position: relative;
+	float: left;
+	width: 142px;
+	font-style: italic;
+}
+
+span.signoff {
+	color: #888888;
+}
+
+	font-size: 70%;
+	font-family: sans-serif;
+	font-style: normal;
+	position: relative;
+	float: left;
+	width: 136px;
+}
+
+	border: solid #d9d8d1;
+	border-width: 1px 0px 0px;
+	font-style: italic;
+}
+
+.author_date, .author {
+	font-style: italic;
+}
+
+div.author_date {
+	border: solid #d9d8d1;
+	border-width: 0px 0px 1px 0px;
+}
+
+a.list {
+	text-decoration: none;
+	color: #000000;
+}
+
+a.subject, a.name {
+	font-weight: bold;
+}
+
+table.tags a.subject {
+	font-weight: normal;
+}
+
+a.list:hover {
+	text-decoration: underline;
+	color: #880000;
+}
+
+a.text {
+	text-decoration: none;
+	color: #0000cc;
+}
+
+a.text:visited {
+	text-decoration: none;
+	color: #880000;
+}
+
+a.text:hover {
+	text-decoration: underline;
+	color: #880000;
+}
+
+table {

(Diff truncated)

recolor favicon
diff --git a/favicon.ico b/favicon.ico
index 90b3272..0512e9d 100644
Binary files a/favicon.ico and b/favicon.ico differ


diff --git a/favicon.ico b/favicon.ico
new file mode 100644
index 0000000..90b3272
Binary files /dev/null and b/favicon.ico differ


diff --git a/index.iki b/index.iki
index d14ed6c..3a2b976 100644
--- a/index.iki
+++ b/index.iki
@@ -8,32 +8,6 @@ the Linguistics building at 10 Washington Place, in room 104 (back of the first
One student session will be held every Wednesday from 3-4 on the
fourth floor at 10 Washington Place.

-Here is $some^2 x^{e \pi} + 3y$ math, and $$here_{is} some + more$$ End of math.
-Except I want to add this: $\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^i}$ Okay now I'm finished.
-
-Here is a test:
-
-
-[[!format  python """
-def f(x):
-    if x &alpha; y:
-        print "hello, world\n"
-    else:
-        return False
-
-        idle code
-
-def bar(x, *z):
-
-    print x *and* z
-
-    return [[x]]
-
-"""]]
-
-End of test.
-
-
## Announcements ##

<!--


diff --git a/index.iki b/index.iki
index 07f1d7c..d14ed6c 100644
--- a/index.iki
+++ b/index.iki
@@ -14,22 +14,22 @@ Except I want to add this: $\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^i}$ Okay now I'm fi
Here is a test:

-    [[!format  python """
-    def f(x):
-        if x &alpha; y:
-            print "hello, world\n"
-        else:
-            return False
-
-            idle code
+[[!format  python """
+def f(x):
+    if x &alpha; y:
+        print "hello, world\n"
+    else:
+        return False
+
+        idle code

-    def bar(x, *z):
+def bar(x, *z):

-        print x *and* z
+    print x *and* z

-        return [[x]]
+    return [[x]]

-    """]]
+"""]]

End of test.


diff --git a/index.iki b/index.iki
index a8e58a3..07f1d7c 100644
--- a/index.iki
+++ b/index.iki
@@ -14,7 +14,7 @@ Except I want to add this: $\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^i}$ Okay now I'm fi
Here is a test:

->[[!format  python """
+    [[!format  python """
def f(x):
if x &alpha; y:
print "hello, world\n"


diff --git a/index.iki b/index.iki
index 1575d71..a8e58a3 100644
--- a/index.iki
+++ b/index.iki
@@ -15,12 +15,21 @@ Here is a test:

>[[!format  python """
-def f(x):
-    if x &alpha; y:
-        print "hello, world\n"
-    else:
-        return False
-"""]]
+    def f(x):
+        if x &alpha; y:
+            print "hello, world\n"
+        else:
+            return False
+
+            idle code
+
+    def bar(x, *z):
+
+        print x *and* z
+
+        return [[x]]
+
+    """]]

End of test.


diff --git a/code/same-fringe.rkt b/code/same-fringe.rkt
new file mode 100644
index 0000000..8a8a7ba
--- /dev/null
+++ b/code/same-fringe.rkt
@@ -0,0 +1,193 @@
+#lang racket
+(require racket/control) ; this tells Scheme to let us use shift and reset
+
+(define (visit yield t)
+  (cond [(pair? t) (visit yield (car t)) (visit yield (cdr t))]
+        [else (yield t)]))
+
+
+; delimcc-based implementation of coroutines, following http://okmij.org/ftp/continuations/implementations.html#caml-shift
+  (letrec ([yield (lambda (x) (shift0 k (cons x k)))]
+           [loop (lambda (curk data)
+                   (let ([x (car data)] [k (cdr data)])
+                     (cond
+                       [(eq? k 'finished) (loop curk (curk x))]
+                       [(eq? k 'exit) x]
+                       [else (loop k (curk x))])))])
+    (loop (lambda (x) (reset0 (cons (thread yield x) 'finished))) (reset0 (cons (main yield start) 'exit)))))
+
+; call/cc-based, following Xavier Leroy's ocaml-callcc
+  (let/cc initk (let* ([curk initk]
+                       [yield (lambda (x) (let/cc k (let ([oldk curk]) (set! curk k) (oldk x))))])
+                  (main yield (begin (thread yield (let/cc k2 (set! curk k2) start)))))))
+
+(define (proc coroutine2 max1 max2)
+  (letrec ([proc1 (lambda (yield n) (if (>= n max1) (begin (displayln "1: exit") 100) (begin (display "1: received ") (displayln n) (proc1 yield (yield (+ 1 n))))))]
+           [proc2 (lambda (yield n) (if (>= n max2) (begin (displayln "2: finished") -2) (begin (display "2: received ") (displayln n) (proc2 yield (yield (+ 1 n))))))])
+    (coroutine2 proc1 0 proc2)))
+
+; the following is meant to be a general-purpose handler with the following behavior:
+; 1. call main with start
+; 2. first yield to proc1, which yields back to main,
+; 3. then main yields to proc2, which yields back to main; and so on
+; 4. when either proc finishes, subsequent yields from main which would have gone to that procedure instead always return #f
+; 5. we stop looping only when main finishes
+(define (coroutine3 main start proc1 proc2)
+  (letrec ([yield (lambda (x) (shift0 k (cons x k)))]
+           [false (lambda (x) (reset0 (false (shift0 k (cons #f k)))))]
+           [loop (lambda (inmain curk otherk data)
+                   (let ([x (car data)] [k (cdr data)])
+                     (cond
+                       [(eq? k 'finished) (loop #t otherk false (curk x))]
+                       [(eq? k 'exit) x]
+                       [inmain (loop #f k otherk (curk x))]
+                       [else (loop #t otherk k (curk x))])))])
+    (loop #t (lambda (x) (reset0 (cons (proc1 yield x) 'finished)))
+          (lambda (x) (reset0 (cons (proc2 yield x) 'finished)))
+          (reset0 (cons (main yield start) 'exit)))))
+
+; the same-fringe application doesn't make use of the 'start or 'restart parameters
+; the 'blah values yielded to the leaf-iterators are ignored too
+(define (same-fringe1 tree1 tree2)
+  (letrec ([next1 (lambda (yield x) (visit yield tree1))]
+           [next2 (lambda (yield x) (visit yield tree2))]
+           [main (lambda (yield x)
+                   (let* ([leaf1 (yield 'blah)]
+                          [leaf2 (yield 'blah)])
+                     (cond [(and leaf1 leaf2) (and (equal? leaf1 leaf2) (main yield 'blah))]
+                           [(or leaf1 leaf2) #f]
+                           [else #t])))])
+           (coroutine3 main 'restart next1 next2)))
+
+
+; another delimcc solution, based on Biernacki, Danvy and Shan "On the static and dynamic extents of delimited continuations" 2006, section 4.1.4
+; here, next1 = '(leaf1 . thunk_for_more_leaves); final thunk => '(finished . #f)
+(define (make-enumerator2 tree)
+  (define (yield x) (shift k (cons x k)))
+  (reset (visit yield tree) '(finished . #f)))
+
+(define (same-fringe2 tree1 tree2)
+  (define next1 (make-enumerator2 tree1))
+  (define next2 (make-enumerator2 tree2))
+  (letrec ([loop (lambda (res1 res2)
+                   (let* ([leaf1 (car res1)]
+                          [leaf2 (car res2)]
+                          [next1 (cdr res1)]
+                          [next2 (cdr res2)])
+                     (cond
+                       [(and next1 next2) (and (equal? leaf1 leaf2) (loop (next1) (next2)))]
+                       [(or next1 next2) #f]
+                       [else #t])))])
+    (loop next1 next2)))
+
+
+; call/cc solution, from http://c2.com/cgi/wiki?SameFringeProblem ("Scheme Language, using CoRoutines")
+; here, (next1) => '(1 . #t); (next1) => '(2 . #t); (next1) => '(finished . #f)
+(define (make-enumerator3 t)
+  (letrec ([resk #f]
+           [yieldk #f]
+           [resume (lambda () (let/cc k
+                                (set! yieldk k)
+                                (cond [(eq? resk #f)
+                                       (visit yield t)
+                                       (set! resk 'finished)
+                                       (yieldk (cons 'finished #f))]
+                                      [(eq? resk 'finished)
+                                       #;(error "End of generator")
+                                       (yieldk (cons 'finished #f))
+                                       ]
+                                      [else (resk)])))]
+           [yield (lambda (x) (let/cc k
+                                 (set! resk k)
+                                 (yieldk (cons x #t))))])
+    resume))
+
+(define (same-fringe3 tree1 tree2)
+  (define next1 (make-enumerator3 tree1))
+  (define next2 (make-enumerator3 tree2))
+  (letrec ([loop (lambda (res1 res2)
+                   (let* ([leaf1 (car res1)]
+                          [leaf2 (car res2)]
+                          [isleaf1 (cdr res1)]
+                          [isleaf2 (cdr res2)])
+                     (cond
+                       [(and isleaf1 isleaf2) (and (equal? leaf1 leaf2) (loop (next1) (next2)))]
+                       [(or isleaf1 isleaf2) #f]
+                       [else #t])))])
+    (loop (next1) (next2))))
+
+
+
+(define (test same-fringe)
+  (define tree1 '(((1 . 2) . (3 . 4)) . (5 . 6)))
+  (define tree2 '(1 . (((2 . 3) . (4 . 5)) . 6)))
+  (define tree3 '(1 . (((2 . 3) . (4 . 5)) . 7)))
+  (define tree4 '(((1 . 2) . (4 . 5)) . 7))
+  (define tree5 '(((1 . 2) . (3 . 4)) . 5))
+  (define tree6 '(((10 . 2) . (3 . 4)) . 5))
+  (define tree7 8)
+  (and (same-fringe tree1 tree2)
+       (same-fringe tree7 tree7)
+       (not (or
+             (same-fringe tree1 tree3)
+             (same-fringe tree1 tree4)
+             (same-fringe tree4 tree1)
+             (same-fringe tree5 tree1)
+             (same-fringe tree1 tree5)
+             (same-fringe tree1 tree6)
+             (same-fringe tree6 tree1)
+             (same-fringe tree6 tree7)
+             ))))
+
+#|
+
+In Lua, using CoRoutines:
+ function tree_leaves(tree)
+    if tree.leaf then
+        coroutine.yield(tree.leaf)
+    else
+        tree_leaves(tree.left)
+        tree_leaves(tree.right)
+    end
+ end
+ function same_fringe(tree1, tree2)
+    local iter1 = coroutine.wrap(tree_leaves)
+    local iter2 = coroutine.wrap(tree_leaves)
+    for node in iter1, tree1 do
+        if node ~= iter2(tree2) then
+            return false
+        end
+    end
+    return iter2() == nil
+ end
+
+In OCaml:
+# #require "delimcc";;
+# open Delimcc;;
+# type seq = End | Next of int * seq computation
+  and 'a computation = unit -> 'a;;
+# type 'a tree = Leaf of 'a | Node of 'a tree * 'a tree;;
+# let rec visit p = function Leaf i -> shift p (fun a -> Next (i, a)) | Node (t1,t2) -> let () = visit p t1 in visit p t2;;
+# let prompt mid = let p = new_prompt() in push_prompt p (mid p);;
+val prompt : ('a Delimcc.prompt -> unit -> 'a) -> 'a = <fun>
+# let make_seq t = prompt (fun p () -> let () = visit p t in End);;
+val make_seq : int tree -> seq = <fun>
+# let tree1 = Node (Node (Node(Leaf 1,Leaf 2), Node(Leaf 3,Leaf 4)), Node(Leaf 5,Leaf 6));;
+# let next1 = make_seq tree1;;
+val next1 : seq = Next (1, <fun>)
+# let next2 = match next1 with Next(_,f) -> f ();;
+val next2 : seq = Next (2, <fun>)
+# let next3 = match next2 with Next(_,f) -> f ();;
+val next3 : seq = Next (3, <fun>)
+# let next4 = match next3 with Next(_,f) -> f ();;
+val next4 : seq = Next (4, <fun>)
+# let next5 = match next4 with Next(_,f) -> f ();;
+val next5 : seq = Next (5, <fun>)
+# let next6 = match next5 with Next(_,f) -> f ();;
+val next6 : seq = Next (6, <fun>)
+# let next7 = match next6 with Next(_,f) -> f ();;
+val next7 : seq = End
+
+|#


diff --git a/index.iki b/index.iki
index 2ac2f29..1575d71 100644
--- a/index.iki
+++ b/index.iki
@@ -24,7 +24,6 @@ def f(x):

End of test.

-[[!inline pages="code/lambda.js"]]

## Announcements ##


diff --git a/index.iki b/index.iki
index 5671765..2ac2f29 100644
--- a/index.iki
+++ b/index.iki
@@ -24,7 +24,7 @@ def f(x):

End of test.

-[[!inline code/lambda.js]]
+[[!inline pages="code/lambda.js"]]

## Announcements ##


diff --git a/index.iki b/index.iki
index c907556..5671765 100644
--- a/index.iki
+++ b/index.iki
@@ -24,6 +24,8 @@ def f(x):

End of test.

+[[!inline code/lambda.js]]
+
## Announcements ##

<!--


diff --git a/index.iki b/index.iki
index 5d904de..c907556 100644
--- a/index.iki
+++ b/index.iki
@@ -20,12 +20,6 @@ def f(x):
print "hello, world\n"
else:
return False
-
-        idle code
-
-def bar(y, *z):
-    print 1 *doo* 3
-
"""]]

End of test.


diff --git a/index.iki b/index.iki
index c907556..5d904de 100644
--- a/index.iki
+++ b/index.iki
@@ -20,6 +20,12 @@ def f(x):
print "hello, world\n"
else:
return False
+
+        idle code
+
+def bar(y, *z):
+    print 1 *doo* 3
+
"""]]

End of test.


diff --git a/index.iki b/index.iki
index decd706..c907556 100644
--- a/index.iki
+++ b/index.iki
@@ -14,9 +14,9 @@ Except I want to add this: $\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^i}$ Okay now I'm fi
Here is a test:

-> [[!format  python """
+>[[!format  python """
def f(x):
-    if x:
+    if x &alpha; y:
print "hello, world\n"
else:
return False


Added the L&P version of Ken's article on quotation.
diff --git a/shan-quotation.pdf b/shan-quotation.pdf
new file mode 100644
index 0000000..73a39cc
Binary files /dev/null and b/shan-quotation.pdf differ


diff --git a/index.iki b/index.iki
index 35aab1d..decd706 100644
--- a/index.iki
+++ b/index.iki
@@ -14,8 +14,12 @@ Except I want to add this: $\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^i}$ Okay now I'm fi
Here is a test:

-> [[!format  perl """
-print "hello, world\n";
+> [[!format  python """
+def f(x):
+    if x:
+        print "hello, world\n"
+    else:
+        return False
"""]]

End of test.


diff --git a/index.iki b/index.iki
index 2e7c5d4..35aab1d 100644
--- a/index.iki
+++ b/index.iki
@@ -15,8 +15,8 @@ Here is a test:

> [[!format  perl """
-> print "hello, world\n";
-> """]]
+print "hello, world\n";
+"""]]

End of test.


diff --git a/index.iki b/index.iki
index 84a8117..2e7c5d4 100644
--- a/index.iki
+++ b/index.iki
@@ -14,9 +14,9 @@ Except I want to add this: $\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^i}$ Okay now I'm fi
Here is a test:

-    [[!format  perl """
-    print "hello, world\n";
-    """]]
+> [[!format  perl """
+> print "hello, world\n";
+> """]]

End of test.


diff --git a/index.iki b/index.iki
index 038720d..84a8117 100644
--- a/index.iki
+++ b/index.iki
@@ -14,9 +14,9 @@ Except I want to add this: $\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^i}$ Okay now I'm fi
Here is a test:

-[[!format  perl """
-print "hello, world\n";
-"""]]
+    [[!format  perl """
+    print "hello, world\n";
+    """]]

End of test.


diff --git a/index.iki b/index.iki
index cacebd1..038720d 100644
--- a/index.iki
+++ b/index.iki
@@ -6,9 +6,20 @@ This course is co-taught by [Chris Barker](http://homepages.nyu.edu/~cb125/) and
The seminar meets on Mondays from 4-6, in
the Linguistics building at 10 Washington Place, in room 104 (back of the first floor).
One student session will be held every Wednesday from 3-4 on the
-fourth floor at 10 Washington Place. Here is $some^2 x^{e \pi} + 3y$ math, and $$here_{is} some + more$$ End of math.
+fourth floor at 10 Washington Place.
+
+Here is $some^2 x^{e \pi} + 3y$ math, and $$here_{is} some + more$$ End of math.
Except I want to add this: $\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^i}$ Okay now I'm finished.

+Here is a test:
+
+
+[[!format  perl """
+print "hello, world\n";
+"""]]
+
+End of test.
+
## Announcements ##

<!--


move templates outside document root
diff --git a/templates/page-jsmath.tmpl b/templates/page-jsmath.tmpl
deleted file mode 100644
index bea7083..0000000
--- a/templates/page-jsmath.tmpl
+++ /dev/null
@@ -1,205 +0,0 @@
-<TMPL_IF HTML5><!DOCTYPE html>
-<html>
-<TMPL_ELSE><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-</TMPL_IF>
-<TMPL_IF DYNAMIC>
-<TMPL_IF FORCEBASEURL><base href="<TMPL_VAR FORCEBASEURL>" /><TMPL_ELSE>
-<TMPL_IF BASEURL><base href="<TMPL_VAR BASEURL>" /></TMPL_IF>
-</TMPL_IF>
-</TMPL_IF>
-<TMPL_IF HTML5><meta charset="utf-8" /><TMPL_ELSE><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></TMPL_IF>
-<title><TMPL_VAR TITLE></title>
-<TMPL_IF FAVICON>
-<link rel="icon" href="<TMPL_VAR BASEURL><TMPL_VAR FAVICON>" type="image/x-icon" />
-</TMPL_IF>
-<link rel="stylesheet" href="<TMPL_VAR BASEURL>style.css" type="text/css" />
-<TMPL_IF LOCAL_CSS>
-<link rel="stylesheet" href="<TMPL_VAR BASEURL><TMPL_VAR LOCAL_CSS>" type="text/css" />
-<TMPL_ELSE>
-<link rel="stylesheet" href="<TMPL_VAR BASEURL>local.css" type="text/css" />
-</TMPL_IF>
-<TMPL_IF EDITURL>
-</TMPL_IF>
-<TMPL_IF RELVCS><TMPL_VAR RELVCS></TMPL_IF>
-<TMPL_IF META><TMPL_VAR META></TMPL_IF>
-<body>
-<noscript>
-<div style="color:#CC0000; text-align:center">
-  <b>Warning: <a href="http://www.math.union.edu/locate/jsMath">jsMath</a>
-  If your browser supports JavaScript, be sure it is enabled.</b>
-</div>
-<hr>
-</noscript>
-
-<TMPL_IF HTML5><article class="page"><TMPL_ELSE><div class="page"></TMPL_IF>
-
-<span>
-<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>/
-</TMPL_LOOP>
-</span>
-<span class="title">
-<TMPL_VAR TITLE>
-<TMPL_IF ISTRANSLATION>
-&nbsp;(<TMPL_VAR PERCENTTRANSLATED>%)
-</TMPL_IF>
-</span>
-</span>
-<TMPL_IF SEARCHFORM>
-<TMPL_VAR SEARCHFORM>
-</TMPL_IF>
-
-<TMPL_IF HAVE_ACTIONS>
-<TMPL_IF HTML5><nav class="actions"><TMPL_ELSE><div class="actions"></TMPL_IF>
-<ul>
-<TMPL_IF EDITURL>
-<li><a href="<TMPL_VAR EDITURL>" rel="nofollow">Edit</a></li>
-</TMPL_IF>
-<TMPL_IF RECENTCHANGESURL>
-<li><a href="<TMPL_VAR RECENTCHANGESURL>">RecentChanges</a></li>
-</TMPL_IF>
-<TMPL_IF HISTORYURL>
-<li><a href="<TMPL_VAR HISTORYURL>">History</a></li>
-</TMPL_IF>
-<TMPL_IF GETSOURCEURL>
-<li><a href="<TMPL_VAR GETSOURCEURL>">Source</a></li>
-</TMPL_IF>
-<TMPL_IF PREFSURL>
-<li><a href="<TMPL_VAR PREFSURL>">Preferences</a></li>
-</TMPL_IF>
-<TMPL_IF ACTIONS>
-<TMPL_LOOP ACTIONS>
-<li><TMPL_VAR ACTION></li>
-</TMPL_LOOP>
-</TMPL_IF>
-<TMPL_ELSE>
-</TMPL_IF>
-</TMPL_IF>
-</ul>
-<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
-</TMPL_IF>
-
-<TMPL_IF OTHERLANGUAGES>
-<TMPL_IF HTML5><nav id="otherlanguages"><TMPL_ELSE><div id="otherlanguages"></TMPL_IF>
-<ul>
-<TMPL_LOOP OTHERLANGUAGES>
-<li>
-<a href="<TMPL_VAR URL>"><TMPL_VAR LANGUAGE></a>
-<TMPL_IF MASTER>
-(master)
-<TMPL_ELSE>
-&nbsp;(<TMPL_VAR PERCENT>%)
-</TMPL_IF>
-</li>
-</TMPL_LOOP>
-</ul>
-<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
-</TMPL_IF>
-
-<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
-
-<TMPL_IF SIDEBAR>
-<TMPL_IF HTML5><aside class="sidebar"><TMPL_ELSE><div class="sidebar"></TMPL_IF>
-<TMPL_VAR SIDEBAR>
-<TMPL_IF HTML5></aside><TMPL_ELSE></div></TMPL_IF>
-</TMPL_IF>
-
-<div id="pagebody">
-
-<TMPL_IF HTML5><section id="content"><TMPL_ELSE><div id="content"></TMPL_IF>
-<TMPL_VAR CONTENT>
-<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
-
-<TMPL_UNLESS DYNAMIC>
-</div>
-<TMPL_ELSE>
-</TMPL_IF>
-<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
-</TMPL_IF>
-</TMPL_UNLESS>
-
-</div>
-
-<TMPL_IF HTML5><footer id="footer" class="pagefooter"><TMPL_ELSE><div id="footer" class="pagefooter"></TMPL_IF>
-<TMPL_UNLESS DYNAMIC>
-<TMPL_IF HTML5><nav id="pageinfo"><TMPL_ELSE><div id="pageinfo"></TMPL_IF>
-
-<TMPL_IF TAGS>
-<TMPL_IF HTML5><nav class="tags"><TMPL_ELSE><div class="tags"></TMPL_IF>
-Tags:
-<TMPL_LOOP TAGS>
-</TMPL_LOOP>
-<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
-</TMPL_IF>
-
-<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
-</TMPL_LOOP>
-<span class="popup">...
-<span class="balloon">
-<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
-</TMPL_LOOP>
-</span>
-</span>
-</TMPL_IF>
-<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
-</TMPL_IF>
-
-</div>
-</TMPL_IF>
-
-</div>
-</TMPL_IF>
-
-<div class="pagedate">
-Last edited <TMPL_VAR MTIME>
-<!-- Created <TMPL_VAR CTIME> -->
-</div>

(Diff truncated)

try unicode
diff --git a/templates/page.tmpl b/templates/page.tmpl
index cdcbeec..928b878 120000
--- a/templates/page.tmpl
+++ b/templates/page.tmpl
@@ -1 +1 @@
-page-mathml.tmpl
\ No newline at end of file
+page-orig.tmpl
\ No newline at end of file


try mathml
diff --git a/templates/page.tmpl b/templates/page.tmpl
index ffa825c..cdcbeec 120000
--- a/templates/page.tmpl
+++ b/templates/page.tmpl
@@ -1 +1 @@
-page-mathjax.tmpl
\ No newline at end of file
+page-mathml.tmpl
\ No newline at end of file


try mathjax
diff --git a/templates/page.tmpl b/templates/page.tmpl
index 84453f1..ffa825c 120000
--- a/templates/page.tmpl
+++ b/templates/page.tmpl
@@ -1 +1 @@
-page-jsmath.tmpl
\ No newline at end of file
+page-mathjax.tmpl
\ No newline at end of file


try jsmath
diff --git a/templates/page.tmpl b/templates/page.tmpl
index 223ddb5..84453f1 120000
--- a/templates/page.tmpl
+++ b/templates/page.tmpl
@@ -1 +1 @@
-page-latexmathml.tmpl
\ No newline at end of file
+page-jsmath.tmpl
\ No newline at end of file


try latexmathml
diff --git a/templates/page.tmpl b/templates/page.tmpl
index cdcbeec..223ddb5 120000
--- a/templates/page.tmpl
+++ b/templates/page.tmpl
@@ -1 +1 @@
-page-mathml.tmpl
\ No newline at end of file
+page-latexmathml.tmpl
\ No newline at end of file


diff --git a/index.iki b/index.iki
index b7f7e65..cacebd1 100644
--- a/index.iki
+++ b/index.iki
@@ -7,7 +7,7 @@ The seminar meets on Mondays from 4-6, in
the Linguistics building at 10 Washington Place, in room 104 (back of the first floor).
One student session will be held every Wednesday from 3-4 on the
fourth floor at 10 Washington Place. Here is $some^2 x^{e \pi} + 3y$ math, and $$here_{is} some + more$$ End of math.
-Except I want to add this: $\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^\i}$ Okay now I'm finished.
+Except I want to add this: $\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^i}$ Okay now I'm finished.

## Announcements ##


try mathml
diff --git a/templates/page.tmpl b/templates/page.tmpl
index 928b878..cdcbeec 120000
--- a/templates/page.tmpl
+++ b/templates/page.tmpl
@@ -1 +1 @@
-page-orig.tmpl
\ No newline at end of file
+page-mathml.tmpl
\ No newline at end of file


diff --git a/templates/page-orig.tmpl b/templates/page-orig.tmpl
new file mode 100644
index 0000000..8659018
--- /dev/null
+++ b/templates/page-orig.tmpl
@@ -0,0 +1,196 @@
+<TMPL_IF HTML5><!DOCTYPE html>
+<html>
+<TMPL_ELSE><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+</TMPL_IF>
+<TMPL_IF DYNAMIC>
+<TMPL_IF FORCEBASEURL><base href="<TMPL_VAR FORCEBASEURL>" /><TMPL_ELSE>
+<TMPL_IF BASEURL><base href="<TMPL_VAR BASEURL>" /></TMPL_IF>
+</TMPL_IF>
+</TMPL_IF>
+<TMPL_IF HTML5><meta charset="utf-8" /><TMPL_ELSE><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></TMPL_IF>
+<title><TMPL_VAR TITLE></title>
+<TMPL_IF FAVICON>
+<link rel="icon" href="<TMPL_VAR BASEURL><TMPL_VAR FAVICON>" type="image/x-icon" />
+</TMPL_IF>
+<link rel="stylesheet" href="<TMPL_VAR BASEURL>style.css" type="text/css" />
+<TMPL_IF LOCAL_CSS>
+<link rel="stylesheet" href="<TMPL_VAR BASEURL><TMPL_VAR LOCAL_CSS>" type="text/css" />
+<TMPL_ELSE>
+<link rel="stylesheet" href="<TMPL_VAR BASEURL>local.css" type="text/css" />
+</TMPL_IF>
+<TMPL_IF EDITURL>
+</TMPL_IF>
+<TMPL_IF RELVCS><TMPL_VAR RELVCS></TMPL_IF>
+<TMPL_IF META><TMPL_VAR META></TMPL_IF>
+<body>
+
+<TMPL_IF HTML5><article class="page"><TMPL_ELSE><div class="page"></TMPL_IF>
+
+<span>
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>/
+</TMPL_LOOP>
+</span>
+<span class="title">
+<TMPL_VAR TITLE>
+<TMPL_IF ISTRANSLATION>
+&nbsp;(<TMPL_VAR PERCENTTRANSLATED>%)
+</TMPL_IF>
+</span>
+</span>
+<TMPL_IF SEARCHFORM>
+<TMPL_VAR SEARCHFORM>
+</TMPL_IF>
+
+<TMPL_IF HAVE_ACTIONS>
+<TMPL_IF HTML5><nav class="actions"><TMPL_ELSE><div class="actions"></TMPL_IF>
+<ul>
+<TMPL_IF EDITURL>
+<li><a href="<TMPL_VAR EDITURL>" rel="nofollow">Edit</a></li>
+</TMPL_IF>
+<TMPL_IF RECENTCHANGESURL>
+<li><a href="<TMPL_VAR RECENTCHANGESURL>">RecentChanges</a></li>
+</TMPL_IF>
+<TMPL_IF HISTORYURL>
+<li><a href="<TMPL_VAR HISTORYURL>">History</a></li>
+</TMPL_IF>
+<TMPL_IF GETSOURCEURL>
+<li><a href="<TMPL_VAR GETSOURCEURL>">Source</a></li>
+</TMPL_IF>
+<TMPL_IF PREFSURL>
+<li><a href="<TMPL_VAR PREFSURL>">Preferences</a></li>
+</TMPL_IF>
+<TMPL_IF ACTIONS>
+<TMPL_LOOP ACTIONS>
+<li><TMPL_VAR ACTION></li>
+</TMPL_LOOP>
+</TMPL_IF>
+<TMPL_ELSE>
+</TMPL_IF>
+</TMPL_IF>
+</ul>
+<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+
+<TMPL_IF OTHERLANGUAGES>
+<TMPL_IF HTML5><nav id="otherlanguages"><TMPL_ELSE><div id="otherlanguages"></TMPL_IF>
+<ul>
+<TMPL_LOOP OTHERLANGUAGES>
+<li>
+<a href="<TMPL_VAR URL>"><TMPL_VAR LANGUAGE></a>
+<TMPL_IF MASTER>
+(master)
+<TMPL_ELSE>
+&nbsp;(<TMPL_VAR PERCENT>%)
+</TMPL_IF>
+</li>
+</TMPL_LOOP>
+</ul>
+<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+
+<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
+
+<TMPL_IF SIDEBAR>
+<TMPL_IF HTML5><aside class="sidebar"><TMPL_ELSE><div class="sidebar"></TMPL_IF>
+<TMPL_VAR SIDEBAR>
+<TMPL_IF HTML5></aside><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+
+<div id="pagebody">
+
+<TMPL_IF HTML5><section id="content"><TMPL_ELSE><div id="content"></TMPL_IF>
+<TMPL_VAR CONTENT>
+<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
+
+<TMPL_UNLESS DYNAMIC>
+</div>
+<TMPL_ELSE>
+</TMPL_IF>
+<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+</TMPL_UNLESS>
+
+</div>
+
+<TMPL_IF HTML5><footer id="footer" class="pagefooter"><TMPL_ELSE><div id="footer" class="pagefooter"></TMPL_IF>
+<TMPL_UNLESS DYNAMIC>
+<TMPL_IF HTML5><nav id="pageinfo"><TMPL_ELSE><div id="pageinfo"></TMPL_IF>
+
+<TMPL_IF TAGS>
+<TMPL_IF HTML5><nav class="tags"><TMPL_ELSE><div class="tags"></TMPL_IF>
+Tags:
+<TMPL_LOOP TAGS>
+</TMPL_LOOP>
+<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
+</TMPL_LOOP>
+<span class="popup">...
+<span class="balloon">
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
+</TMPL_LOOP>
+</span>
+</span>
+</TMPL_IF>
+<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+
+</div>
+</TMPL_IF>
+
+</div>
+</TMPL_IF>
+
+<div class="pagedate">
+Last edited <TMPL_VAR MTIME>
+<!-- Created <TMPL_VAR CTIME> -->
+</div>
+
+<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
+<TMPL_IF EXTRAFOOTER><TMPL_VAR EXTRAFOOTER></TMPL_IF>
+</TMPL_UNLESS>
+<!-- from <TMPL_VAR WIKINAME> -->
+<TMPL_IF HTML5></footer><TMPL_ELSE></div></TMPL_IF>
+
+<TMPL_IF HTML5></article><TMPL_ELSE></div></TMPL_IF>
+

(Diff truncated)

diff --git a/index.iki b/index.iki
index 5aef7ef..b7f7e65 100644
--- a/index.iki
+++ b/index.iki
@@ -7,7 +7,7 @@ The seminar meets on Mondays from 4-6, in
the Linguistics building at 10 Washington Place, in room 104 (back of the first floor).
One student session will be held every Wednesday from 3-4 on the
fourth floor at 10 Washington Place. Here is $some^2 x^{e \pi} + 3y$ math, and $$here_{is} some + more$$ End of math.
-Except I want to add this: $$\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^\i}$$ Okay now I'm finished.
+Except I want to add this: $\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^\i}$ Okay now I'm finished.

## Announcements ##


diff --git a/index.iki b/index.iki
index 1abeed1..5aef7ef 100644
--- a/index.iki
+++ b/index.iki
@@ -7,6 +7,7 @@ The seminar meets on Mondays from 4-6, in
the Linguistics building at 10 Washington Place, in room 104 (back of the first floor).
One student session will be held every Wednesday from 3-4 on the
fourth floor at 10 Washington Place. Here is $some^2 x^{e \pi} + 3y$ math, and $$here_{is} some + more$$ End of math.
+Except I want to add this: $$\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^\i}$$ Okay now I'm finished.

## Announcements ##


make links to math javascripts absolute
diff --git a/templates/page-jsmath.tmpl b/templates/page-jsmath.tmpl
index 8d330fa..bea7083 100644
--- a/templates/page-jsmath.tmpl
+++ b/templates/page-jsmath.tmpl
@@ -27,7 +27,7 @@
<TMPL_IF RELVCS><TMPL_VAR RELVCS></TMPL_IF>
<TMPL_IF META><TMPL_VAR META></TMPL_IF>
<body>
<noscript>
diff --git a/templates/page-latexmathml.tmpl b/templates/page-latexmathml.tmpl
index 04944d1..9daa2c6 100644
--- a/templates/page-latexmathml.tmpl
+++ b/templates/page-latexmathml.tmpl
@@ -27,8 +27,8 @@
<TMPL_IF RELVCS><TMPL_VAR RELVCS></TMPL_IF>
<TMPL_IF META><TMPL_VAR META></TMPL_IF>
-<script src="<TMPL_VAR BASEURL>LaTeXMathML.js" type="text/javascript"></script>
-<link href="<TMPL_VAR BASEURL>LaTeXMathML.standardarticle.css" rel="stylesheet" type="text/css" />
+<script src="/LaTeXMathML.js" type="text/javascript"></script>
<body>
<noscript>
diff --git a/templates/page-mathml.tmpl b/templates/page-mathml.tmpl
index 6aed995..cca833d 100644
--- a/templates/page-mathml.tmpl
+++ b/templates/page-mathml.tmpl
@@ -27,7 +27,7 @@
<TMPL_IF RELVCS><TMPL_VAR RELVCS></TMPL_IF>
<TMPL_IF META><TMPL_VAR META></TMPL_IF>
-<script src="<TMPL_VAR BASEURL>mathml.js" type="text/javascript"></script>
+<script src="/mathml.js" type="text/javascript"></script>
<body>


diff --git a/templates/page.tmpl b/templates/page.tmpl
new file mode 120000
index 0000000..cdcbeec
--- /dev/null
+++ b/templates/page.tmpl
@@ -0,0 +1 @@
+page-mathml.tmpl
\ No newline at end of file


diff --git a/index.iki b/index.iki
index 3a2b976..1abeed1 100644
--- a/index.iki
+++ b/index.iki
@@ -6,7 +6,7 @@ This course is co-taught by [Chris Barker](http://homepages.nyu.edu/~cb125/) and
The seminar meets on Mondays from 4-6, in
the Linguistics building at 10 Washington Place, in room 104 (back of the first floor).
One student session will be held every Wednesday from 3-4 on the
-fourth floor at 10 Washington Place.
+fourth floor at 10 Washington Place. Here is $some^2 x^{e \pi} + 3y$ math, and $$here_{is} some + more$$ End of math.

## Announcements ##


move mathml support files outside document root
diff --git a/LaTeXMathML.js b/LaTeXMathML.js
deleted file mode 100644
index 7282569..0000000
--- a/LaTeXMathML.js
+++ /dev/null
@@ -1,2368 +0,0 @@
-/*
-LaTeXMathML.js
-==============
-
-This file, in this form, is due to Douglas Woodall, June 2006.
-It contains JavaScript functions to convert (most simple) LaTeX
-math notation to Presentation MathML.  It was obtained by
-and modifying it so that it carries out ONLY those conversions
-that would be carried out in LaTeX.  A description of the original
-file, with examples, can be found at
-	www1.chapman.edu/~jipsen/mathml/asciimath.html
-	ASCIIMathML: Math on the web for everyone
-
-Here is the header notice from the original file:
-
-ASCIIMathML.js
-==============
-This file contains JavaScript functions to convert ASCII math notation
-to Presentation MathML. The conversion is done while the (X)HTML page
-loads, and should work with Firefox/Mozilla/Netscape 7+ and Internet
-Explorer 6+MathPlayer (http://www.dessci.com/en/products/mathplayer/).
-Just add the next line to your (X)HTML page with this file in the same folder:
-<script type="text/javascript" src="ASCIIMathML.js"></script>
-This is a convenient and inexpensive solution for authoring MathML.
-
-Version 1.4.7 Dec 15, 2005, (c) Peter Jipsen http://www.chapman.edu/~jipsen
-For changes see http://www.chapman.edu/~jipsen/mathml/asciimathchanges.txt
-If you use it on a webpage, please send the URL to jipsen@chapman.edu
-
-This program is free software; you can redistribute it and/or modify
-the Free Software Foundation; either version 2 of the License, or (at
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-for more details.
-
-LaTeXMathML.js (ctd)
-==============
-
-The instructions for use are the same as for the original
-ASCIIMathML.js, except that of course the line you add to your
-file should be
-<script type="text/javascript" src="LaTeXMathML.js"></script>
-Or use absolute path names if the file is not in the same folder
-*/
-
-var checkForMathML = true;   // check if browser can display MathML
-var notifyIfNoMathML = true; // display note if no MathML capability
-var alertIfNoMathML = false;  // show alert box if no MathML capability
-// was "red":
-var mathcolor = "";	     // change it to "" (to inherit) or any other color
-// was "serif":
-var mathfontfamily = "";      // change to "" to inherit (works in IE)
-                              // or another family (e.g. "arial")
-var showasciiformulaonhover = true; // helps students learn ASCIIMath
-/*
-// Commented out by DRW -- not now used -- see DELIMITERS (twice) near the end
-var displaystyle = false;     // puts limits above and below large operators
-var decimalsign = ".";        // change to "," if you like, beware of (1,2)!
-var AMdelimiter1 = "", AMescape1 = "\\\\"; // can use other characters
-var AMdelimiter2 = "$", AMescape2 = "\\\\\\$", AMdelimiter2regexp = "\\"; -var doubleblankmathdelimiter = false; // if true, x+1 is equal to x+1 - // for IE this works only in <!-- --> -//var separatetokens;// has been removed (email me if this is a problem) -*/ -var isIE = document.createElementNS==null; - -if (document.getElementById==null) - alert("This webpage requires a recent browser such as \nMozilla/Netscape 7+ or Internet Explorer 6+MathPlayer") - -// all further global variables start with "AM" - -function AMcreateElementXHTML(t) { - if (isIE) return document.createElement(t); - else return document.createElementNS("http://www.w3.org/1999/xhtml",t); -} - -function AMnoMathMLNote() { - var nd = AMcreateElementXHTML("h3"); - nd.setAttribute("align","center") - nd.appendChild(AMcreateElementXHTML("p")); - nd.appendChild(document.createTextNode("To view the ")); - var an = AMcreateElementXHTML("a"); - an.appendChild(document.createTextNode("LaTeXMathML")); - an.setAttribute("href","http://www.maths.nott.ac.uk/personal/drw/lm.html"); - nd.appendChild(an); - nd.appendChild(document.createTextNode(" notation use Internet Explorer 6+")); - an = AMcreateElementXHTML("a"); - an.appendChild(document.createTextNode("MathPlayer")); - an.setAttribute("href","http://www.dessci.com/en/products/mathplayer/download.htm"); - nd.appendChild(an); - nd.appendChild(document.createTextNode(" or Netscape/Mozilla/Firefox")); - nd.appendChild(AMcreateElementXHTML("p")); - return nd; -} - -function AMisMathMLavailable() { - if (navigator.appName.slice(0,8)=="Netscape") - if (navigator.appVersion.slice(0,1)>="5") return null; - else return AMnoMathMLNote(); - else if (navigator.appName.slice(0,9)=="Microsoft") - try { - var ActiveX = new ActiveXObject("MathPlayer.Factory.1"); - return null; - } catch (e) { - return AMnoMathMLNote(); - } - else return AMnoMathMLNote(); -} - -// character lists for Mozilla/Netscape fonts -var AMcal = ["\uD835\uDC9C", "\uD835\uDC9D", "\uD835\uDC9E", "\uD835\uDC9F", "\uD835\uDCA0", "\uD835\uDCA1", "\uD835\uDCA2", "\uD835\uDCA3", "\uD835\uDCA4", "\uD835\uDCA5", "\uD835\uDCA6", "\uD835\uDCA7", "\uD835\uDCA8", "\uD835\uDCA9", "\uD835\uDCAA", "\uD835\uDCAB", "\uD835\uDCAC", "\uD835\uDCAD", "\uD835\uDCAE", "\uD835\uDCAF", "\uD835\uDCB0", "\uD835\uDCB1", "\uD835\uDCB2", "\uD835\uDCB3", "\uD835\uDCB4", "\uD835\uDCB5"]; -var AMfrk = ["\uD835\uDD04", "\uD835\uDD05", "\uD835\uDD06", "\uD835\uDD07", "\uD835\uDD08", "\uD835\uDD09", "\uD835\uDD0A", "\uD835\uDD0B", "\uD835\uDD0C", "\uD835\uDD0D", "\uD835\uDD0E", "\uD835\uDD0F", "\uD835\uDD10", "\uD835\uDD11", "\uD835\uDD12", "\uD835\uDD13", "\uD835\uDD14", "\uD835\uDD15", "\uD835\uDD16", "\uD835\uDD17", "\uD835\uDD18", "\uD835\uDD19", "\uD835\uDD1A", "\uD835\uDD1B", "\uD835\uDD1C", "\uD835\uDD1D"]; -var AMbbb = ["\uD835\uDD38", "\uD835\uDD39", "\uD835\uDD3A", "\uD835\uDD3B", "\uD835\uDD3C", "\uD835\uDD3D", "\uD835\uDD3E", "\uD835\uDD3F", "\uD835\uDD40", "\uD835\uDD41", "\uD835\uDD42", "\uD835\uDD43", "\uD835\uDD44", "\uD835\uDD45", "\uD835\uDD46", "\uD835\uDD47", "\uD835\uDD48", "\uD835\uDD49", "\uD835\uDD4A", "\uD835\uDD4B", "\uD835\uDD4C", "\uD835\uDD4D", "\uD835\uDD4E", "\uD835\uDD4F", "\uD835\uDD50", "\uD835\uDD51"]; - -var CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4, - RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8, - TEXT = 9, BIG = 10, LONG = 11, STRETCHY = 12, MATRIX = 13; // token types - -var AMsqrt = {input:"\\sqrt", tag:"msqrt", output:"sqrt", ttype:UNARY}, - AMnot = {input:"\\not", tag:"mnot", output:"not", ttype:UNARY}, - AMroot = {input:"\\root", tag:"mroot", output:"root", ttype:BINARY}, - AMfrac = {input:"\\frac", tag:"mfrac", output:"/", ttype:BINARY}, - AMover = {input:"\\stackrel", tag:"mover", output:"stackrel", ttype:BINARY}, - AMatop = {input:"\\atop", tag:"mfrac", output:"", ttype:INFIX}, - AMchoose = {input:"\\choose", tag:"mfrac", output:"", ttype:INFIX}, - AMsub = {input:"_", tag:"msub", output:"_", ttype:INFIX}, - AMsup = {input:"^", tag:"msup", output:"^", ttype:INFIX}, - AMtext = {input:"\\mathrm", tag:"mtext", output:"text", ttype:TEXT}, - AMmbox = {input:"\\mbox", tag:"mtext", output:"mbox", ttype:TEXT}; - -// Commented out by DRW to prevent 1/2 turning into a 2-line fraction -// AMdiv = {input:"/", tag:"mfrac", output:"/", ttype:INFIX}, -// Commented out by DRW so that " prints literally in equations -// AMquote = {input:"\"", tag:"mtext", output:"mbox", ttype:TEXT}; - -// List of negations obtained from http://frodo.elon.edu/tutorial/tutorial.pdf -var AMRelationNegations = { - "\u003C":"\u226E", "\u003E":"\u226F", "\u2264":"\u2270", "\u2265":"\u2271", - "\u003D":"\u2260", "\u2261":"\u2262", "\u227A":"\u2280", "\u227B":"\u2281", - "\u227C":"\u22E0", "\u227D":"\u22E1", "\u223C":"\u2241", "\u2243":"\u2244", - "\u2282":"\u2284", "\u2283":"\u2285", "\u2286":"\u2288", "\u2287":"\u2289", - "\u2248":"\u2249", "\u2245":"\u2247", "\u2291":"\u22E2", "\u2292":"\u22E3", - "\u224D":"\u226D" -} - -var AMsymbols = [ -//Greek letters -{input:"\\alpha", tag:"mi", output:"\u03B1", ttype:CONST}, -{input:"\\beta", tag:"mi", output:"\u03B2", ttype:CONST}, -{input:"\\gamma", tag:"mi", output:"\u03B3", ttype:CONST}, -{input:"\\delta", tag:"mi", output:"\u03B4", ttype:CONST}, -{input:"\\epsilon", tag:"mi", output:"\u03B5", ttype:CONST}, -{input:"\\varepsilon", tag:"mi", output:"\u025B", ttype:CONST}, -{input:"\\zeta", tag:"mi", output:"\u03B6", ttype:CONST}, -{input:"\\eta", tag:"mi", output:"\u03B7", ttype:CONST}, -{input:"\\theta", tag:"mi", output:"\u03B8", ttype:CONST}, -{input:"\\vartheta", tag:"mi", output:"\u03D1", ttype:CONST}, -{input:"\\iota", tag:"mi", output:"\u03B9", ttype:CONST}, -{input:"\\kappa", tag:"mi", output:"\u03BA", ttype:CONST}, -{input:"\\lambda", tag:"mi", output:"\u03BB", ttype:CONST}, -{input:"\\mu", tag:"mi", output:"\u03BC", ttype:CONST}, -{input:"\\nu", tag:"mi", output:"\u03BD", ttype:CONST}, -{input:"\\xi", tag:"mi", output:"\u03BE", ttype:CONST}, -{input:"\\pi", tag:"mi", output:"\u03C0", ttype:CONST}, -{input:"\\varpi", tag:"mi", output:"\u03D6", ttype:CONST}, -{input:"\\rho", tag:"mi", output:"\u03C1", ttype:CONST}, -{input:"\\varrho", tag:"mi", output:"\u03F1", ttype:CONST}, -{input:"\\varsigma", tag:"mi", output:"\u03C2", ttype:CONST}, -{input:"\\sigma", tag:"mi", output:"\u03C3", ttype:CONST}, -{input:"\\tau", tag:"mi", output:"\u03C4", ttype:CONST}, -{input:"\\upsilon", tag:"mi", output:"\u03C5", ttype:CONST}, -{input:"\\phi", tag:"mi", output:"\u03C6", ttype:CONST}, -{input:"\\varphi", tag:"mi", output:"\u03D5", ttype:CONST}, -{input:"\\chi", tag:"mi", output:"\u03C7", ttype:CONST}, -{input:"\\psi", tag:"mi", output:"\u03C8", ttype:CONST}, -{input:"\\omega", tag:"mi", output:"\u03C9", ttype:CONST}, -{input:"\\Gamma", tag:"mo", output:"\u0393", ttype:CONST}, -{input:"\\Delta", tag:"mo", output:"\u0394", ttype:CONST}, -{input:"\\Theta", tag:"mo", output:"\u0398", ttype:CONST}, -{input:"\\Lambda", tag:"mo", output:"\u039B", ttype:CONST}, -{input:"\\Xi", tag:"mo", output:"\u039E", ttype:CONST}, -{input:"\\Pi", tag:"mo", output:"\u03A0", ttype:CONST}, -{input:"\\Sigma", tag:"mo", output:"\u03A3", ttype:CONST}, -{input:"\\Upsilon", tag:"mo", output:"\u03A5", ttype:CONST}, -{input:"\\Phi", tag:"mo", output:"\u03A6", ttype:CONST}, (Diff truncated)  added math templates diff --git a/templates/page-jsmath.tmpl b/templates/page-jsmath.tmpl new file mode 100644 index 0000000..8d330fa --- /dev/null +++ b/templates/page-jsmath.tmpl @@ -0,0 +1,205 @@ +<TMPL_IF HTML5><!DOCTYPE html> +<html> +<TMPL_ELSE><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +</TMPL_IF> +<head> +<TMPL_IF DYNAMIC> +<TMPL_IF FORCEBASEURL><base href="<TMPL_VAR FORCEBASEURL>" /><TMPL_ELSE> +<TMPL_IF BASEURL><base href="<TMPL_VAR BASEURL>" /></TMPL_IF> +</TMPL_IF> +</TMPL_IF> +<TMPL_IF HTML5><meta charset="utf-8" /><TMPL_ELSE><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></TMPL_IF> +<title><TMPL_VAR TITLE></title> +<TMPL_IF FAVICON> +<link rel="icon" href="<TMPL_VAR BASEURL><TMPL_VAR FAVICON>" type="image/x-icon" /> +</TMPL_IF> +<link rel="stylesheet" href="<TMPL_VAR BASEURL>style.css" type="text/css" /> +<TMPL_IF LOCAL_CSS> +<link rel="stylesheet" href="<TMPL_VAR BASEURL><TMPL_VAR LOCAL_CSS>" type="text/css" /> +<TMPL_ELSE> +<link rel="stylesheet" href="<TMPL_VAR BASEURL>local.css" type="text/css" /> +</TMPL_IF> +<TMPL_IF EDITURL> +<link rel="alternate" type="application/x-wiki" title="Edit this page" href="<TMPL_VAR EDITURL>" /> +</TMPL_IF> +<TMPL_IF FEEDLINKS><TMPL_VAR FEEDLINKS></TMPL_IF> +<TMPL_IF RELVCS><TMPL_VAR RELVCS></TMPL_IF> +<TMPL_IF META><TMPL_VAR META></TMPL_IF> +<script src="<TMPL_VAR BASEURL>jsMath/easy/load.js" type="text/javascript"></script> +</head> +<body> +<noscript> +<div style="color:#CC0000; text-align:center"> + <b>Warning: <a href="http://www.math.union.edu/locate/jsMath">jsMath</a> + requires JavaScript to process the mathematics on this page.<br> + If your browser supports JavaScript, be sure it is enabled.</b> +</div> +<hr> +</noscript> + +<TMPL_IF HTML5><article class="page"><TMPL_ELSE><div class="page"></TMPL_IF> + +<TMPL_IF HTML5><section class="pageheader"><TMPL_ELSE><div class="pageheader"></TMPL_IF> +<TMPL_IF HTML5><header class="header"><TMPL_ELSE><div class="header"></TMPL_IF> +<span> +<span class="parentlinks"> +<TMPL_LOOP PARENTLINKS> +<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>/ +</TMPL_LOOP> +</span> +<span class="title"> +<TMPL_VAR TITLE> +<TMPL_IF ISTRANSLATION> +&nbsp;(<TMPL_VAR PERCENTTRANSLATED>%) +</TMPL_IF> +</span> +</span> +<TMPL_IF SEARCHFORM> +<TMPL_VAR SEARCHFORM> +</TMPL_IF> +<TMPL_IF HTML5></header><TMPL_ELSE></div></TMPL_IF> + +<TMPL_IF HAVE_ACTIONS> +<TMPL_IF HTML5><nav class="actions"><TMPL_ELSE><div class="actions"></TMPL_IF> +<ul> +<TMPL_IF EDITURL> +<li><a href="<TMPL_VAR EDITURL>" rel="nofollow">Edit</a></li> +</TMPL_IF> +<TMPL_IF RECENTCHANGESURL> +<li><a href="<TMPL_VAR RECENTCHANGESURL>">RecentChanges</a></li> +</TMPL_IF> +<TMPL_IF HISTORYURL> +<li><a href="<TMPL_VAR HISTORYURL>">History</a></li> +</TMPL_IF> +<TMPL_IF GETSOURCEURL> +<li><a href="<TMPL_VAR GETSOURCEURL>">Source</a></li> +</TMPL_IF> +<TMPL_IF PREFSURL> +<li><a href="<TMPL_VAR PREFSURL>">Preferences</a></li> +</TMPL_IF> +<TMPL_IF ACTIONS> +<TMPL_LOOP ACTIONS> +<li><TMPL_VAR ACTION></li> +</TMPL_LOOP> +</TMPL_IF> +<TMPL_IF COMMENTSLINK> +<li><TMPL_VAR COMMENTSLINK></li> +<TMPL_ELSE> +<TMPL_IF DISCUSSIONLINK> +<li><TMPL_VAR DISCUSSIONLINK></li> +</TMPL_IF> +</TMPL_IF> +</ul> +<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF> +</TMPL_IF> + +<TMPL_IF OTHERLANGUAGES> +<TMPL_IF HTML5><nav id="otherlanguages"><TMPL_ELSE><div id="otherlanguages"></TMPL_IF> +<ul> +<TMPL_LOOP OTHERLANGUAGES> +<li> +<a href="<TMPL_VAR URL>"><TMPL_VAR LANGUAGE></a> +<TMPL_IF MASTER> +(master) +<TMPL_ELSE> +&nbsp;(<TMPL_VAR PERCENT>%) +</TMPL_IF> +</li> +</TMPL_LOOP> +</ul> +<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF> +</TMPL_IF> + +<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF> + +<TMPL_IF SIDEBAR> +<TMPL_IF HTML5><aside class="sidebar"><TMPL_ELSE><div class="sidebar"></TMPL_IF> +<TMPL_VAR SIDEBAR> +<TMPL_IF HTML5></aside><TMPL_ELSE></div></TMPL_IF> +</TMPL_IF> + +<div id="pagebody"> + +<TMPL_IF HTML5><section id="content"><TMPL_ELSE><div id="content"></TMPL_IF> +<TMPL_VAR CONTENT> +<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF> + +<TMPL_UNLESS DYNAMIC> +<TMPL_IF COMMENTS> +<TMPL_IF HTML5><section id="comments"><TMPL_ELSE><div id="comments"></TMPL_IF> +<TMPL_VAR COMMENTS> +<TMPL_IF ADDCOMMENTURL> +<div class="addcomment"> +<a href="<TMPL_VAR ADDCOMMENTURL>">Add a comment</a> +</div> +<TMPL_ELSE> +<div class="addcomment">Comments on this page are closed.</div> +</TMPL_IF> +<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF> +</TMPL_IF> +</TMPL_UNLESS> + +</div> + +<TMPL_IF HTML5><footer id="footer" class="pagefooter"><TMPL_ELSE><div id="footer" class="pagefooter"></TMPL_IF> +<TMPL_UNLESS DYNAMIC> +<TMPL_IF HTML5><nav id="pageinfo"><TMPL_ELSE><div id="pageinfo"></TMPL_IF> + +<TMPL_IF TAGS> +<TMPL_IF HTML5><nav class="tags"><TMPL_ELSE><div class="tags"></TMPL_IF> +Tags: +<TMPL_LOOP TAGS> +<TMPL_VAR LINK> +</TMPL_LOOP> +<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF> +</TMPL_IF> + +<TMPL_IF BACKLINKS> +<TMPL_IF HTML5><nav id="backlinks"><TMPL_ELSE><div id="backlinks"></TMPL_IF> +Links: +<TMPL_LOOP BACKLINKS> +<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a> +</TMPL_LOOP> +<TMPL_IF MORE_BACKLINKS> +<span class="popup">... +<span class="balloon"> +<TMPL_LOOP MORE_BACKLINKS> +<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a> +</TMPL_LOOP> +</span> +</span> +</TMPL_IF> +<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF> +</TMPL_IF> + +<TMPL_IF COPYRIGHT> +<div class="pagecopyright"> +<a name="pagecopyright"></a> +<TMPL_VAR COPYRIGHT> +</div> +</TMPL_IF> + +<TMPL_IF LICENSE> +<div class="pagelicense"> +<a name="pagelicense"></a> +License: <TMPL_VAR LICENSE> +</div> +</TMPL_IF> + +<div class="pagedate"> +Last edited <TMPL_VAR MTIME> +<!-- Created <TMPL_VAR CTIME> --> +</div> (Diff truncated)  re-add mathml.js diff --git a/mathml.js b/mathml.js new file mode 100644 index 0000000..a72c2e5 --- /dev/null +++ b/mathml.js @@ -0,0 +1,70 @@ +/* +March 19, 2004 MathHTML (c) Peter Jipsen http://www.chapman.edu/~jipsen +Released under the GNU General Public License version 2 or later. +See the GNU General Public License (at http://www.gnu.org/copyleft/gpl.html) +for more details. +*/ + +function convertMath(node) {// for Gecko + if (node.nodeType==1) { + var newnode = + document.createElementNS("http://www.w3.org/1998/Math/MathML", + node.nodeName.toLowerCase()); + for(var i=0; i < node.attributes.length; i++) + newnode.setAttribute(node.attributes[i].nodeName, + node.attributes[i].nodeValue); + for (var i=0; i<node.childNodes.length; i++) { + var st = node.childNodes[i].nodeValue; + if (st==null || st.slice(0,1)!=" " && st.slice(0,1)!="\n") + newnode.appendChild(convertMath(node.childNodes[i])); + } + return newnode; + } + else return node; +} + +function convert() { + var mmlnode = document.getElementsByTagName("math"); + var st,str,node,newnode; + for (var i=0; i<mmlnode.length; i++) + if (document.createElementNS!=null) + mmlnode[i].parentNode.replaceChild(convertMath(mmlnode[i]),mmlnode[i]); + else { // convert for IE + str = ""; + node = mmlnode[i]; + while (node.nodeName!="/MATH") { + st = node.nodeName.toLowerCase(); + if (st=="#text") str += node.nodeValue; + else { + str += (st.slice(0,1)=="/" ? "</m:"+st.slice(1) : "<m:"+st); + if (st.slice(0,1)!="/") + for(var j=0; j < node.attributes.length; j++) + if (node.attributes[j].nodeValue!="italic" && + node.attributes[j].nodeValue!="" && + node.attributes[j].nodeValue!="inherit" && + node.attributes[j].nodeValue!=undefined) + str += " "+node.attributes[j].nodeName+"="+ + "\""+node.attributes[j].nodeValue+"\""; + str += ">"; + } + node = node.nextSibling; + node.parentNode.removeChild(node.previousSibling); + } + str += "</m:math>"; + newnode = document.createElement("span"); + node.parentNode.replaceChild(newnode,node); + newnode.innerHTML = str; + } +} + +if (document.createElementNS==null) { + document.write("<object id=\"mathplayer\"\ + classid=\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\"></object>"); + document.write("<?import namespace=\"m\" implementation=\"#mathplayer\"?>"); +} +if(typeof window.addEventListener != 'undefined'){ + window.addEventListener('load', convert, false); +} +if(typeof window.attachEvent != 'undefined') { + window.attachEvent('onload', convert); +}  added LaTeXMathML files diff --git a/LaTeXMathML.js b/LaTeXMathML.js new file mode 100644 index 0000000..7282569 --- /dev/null +++ b/LaTeXMathML.js @@ -0,0 +1,2368 @@ +/* +LaTeXMathML.js +============== + +This file, in this form, is due to Douglas Woodall, June 2006. +It contains JavaScript functions to convert (most simple) LaTeX +math notation to Presentation MathML. It was obtained by +downloading the file ASCIIMathML.js from + http://www1.chapman.edu/~jipsen/mathml/asciimathdownload/ +and modifying it so that it carries out ONLY those conversions +that would be carried out in LaTeX. A description of the original +file, with examples, can be found at + www1.chapman.edu/~jipsen/mathml/asciimath.html + ASCIIMathML: Math on the web for everyone + +Here is the header notice from the original file: + +ASCIIMathML.js +============== +This file contains JavaScript functions to convert ASCII math notation +to Presentation MathML. The conversion is done while the (X)HTML page +loads, and should work with Firefox/Mozilla/Netscape 7+ and Internet +Explorer 6+MathPlayer (http://www.dessci.com/en/products/mathplayer/). +Just add the next line to your (X)HTML page with this file in the same folder: +<script type="text/javascript" src="ASCIIMathML.js"></script> +This is a convenient and inexpensive solution for authoring MathML. + +Version 1.4.7 Dec 15, 2005, (c) Peter Jipsen http://www.chapman.edu/~jipsen +Latest version at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML.js +For changes see http://www.chapman.edu/~jipsen/mathml/asciimathchanges.txt +If you use it on a webpage, please send the URL to jipsen@chapman.edu + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at +your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License (at http://www.gnu.org/copyleft/gpl.html) +for more details. + +LaTeXMathML.js (ctd) +============== + +The instructions for use are the same as for the original +ASCIIMathML.js, except that of course the line you add to your +file should be +<script type="text/javascript" src="LaTeXMathML.js"></script> +Or use absolute path names if the file is not in the same folder +as your (X)HTML page. +*/ + +var checkForMathML = true; // check if browser can display MathML +var notifyIfNoMathML = true; // display note if no MathML capability +var alertIfNoMathML = false; // show alert box if no MathML capability +// was "red": +var mathcolor = ""; // change it to "" (to inherit) or any other color +// was "serif": +var mathfontfamily = ""; // change to "" to inherit (works in IE) + // or another family (e.g. "arial") +var showasciiformulaonhover = true; // helps students learn ASCIIMath +/* +// Commented out by DRW -- not now used -- see DELIMITERS (twice) near the end +var displaystyle = false; // puts limits above and below large operators +var decimalsign = "."; // change to "," if you like, beware of (1,2)! +var AMdelimiter1 = "", AMescape1 = "\\\\"; // can use other characters +var AMdelimiter2 = "", AMescape2 = "\\\\\\$", AMdelimiter2regexp = "\\$";
+var doubleblankmathdelimiter = false; // if true,  x+1  is equal to x+1
+                                      // for IE this works only in <!--   -->
+//var separatetokens;// has been removed (email me if this is a problem)
+*/
+var isIE = document.createElementNS==null;
+
+if (document.getElementById==null)
+  alert("This webpage requires a recent browser such as \nMozilla/Netscape 7+ or Internet Explorer 6+MathPlayer")
+
+
+function AMcreateElementXHTML(t) {
+  if (isIE) return document.createElement(t);
+  else return document.createElementNS("http://www.w3.org/1999/xhtml",t);
+}
+
+function AMnoMathMLNote() {
+  var nd = AMcreateElementXHTML("h3");
+  nd.setAttribute("align","center")
+  nd.appendChild(AMcreateElementXHTML("p"));
+  nd.appendChild(document.createTextNode("To view the "));
+  var an = AMcreateElementXHTML("a");
+  an.appendChild(document.createTextNode("LaTeXMathML"));
+  an.setAttribute("href","http://www.maths.nott.ac.uk/personal/drw/lm.html");
+  nd.appendChild(an);
+  nd.appendChild(document.createTextNode(" notation use Internet Explorer 6+"));
+  an = AMcreateElementXHTML("a");
+  an.appendChild(document.createTextNode("MathPlayer"));
+  nd.appendChild(an);
+  nd.appendChild(document.createTextNode(" or Netscape/Mozilla/Firefox"));
+  nd.appendChild(AMcreateElementXHTML("p"));
+  return nd;
+}
+
+function AMisMathMLavailable() {
+  if (navigator.appName.slice(0,8)=="Netscape")
+    if (navigator.appVersion.slice(0,1)>="5") return null;
+    else return AMnoMathMLNote();
+  else if (navigator.appName.slice(0,9)=="Microsoft")
+    try {
+        var ActiveX = new ActiveXObject("MathPlayer.Factory.1");
+        return null;
+    } catch (e) {
+        return AMnoMathMLNote();
+    }
+  else return AMnoMathMLNote();
+}
+
+// character lists for Mozilla/Netscape fonts
+var AMcal = ["\uD835\uDC9C", "\uD835\uDC9D", "\uD835\uDC9E", "\uD835\uDC9F", "\uD835\uDCA0", "\uD835\uDCA1", "\uD835\uDCA2", "\uD835\uDCA3", "\uD835\uDCA4", "\uD835\uDCA5", "\uD835\uDCA6", "\uD835\uDCA7", "\uD835\uDCA8", "\uD835\uDCA9", "\uD835\uDCAA", "\uD835\uDCAB", "\uD835\uDCAC", "\uD835\uDCAD", "\uD835\uDCAE", "\uD835\uDCAF", "\uD835\uDCB0", "\uD835\uDCB1", "\uD835\uDCB2", "\uD835\uDCB3", "\uD835\uDCB4", "\uD835\uDCB5"];
+var AMfrk = ["\uD835\uDD04", "\uD835\uDD05", "\uD835\uDD06", "\uD835\uDD07", "\uD835\uDD08", "\uD835\uDD09", "\uD835\uDD0A", "\uD835\uDD0B", "\uD835\uDD0C", "\uD835\uDD0D", "\uD835\uDD0E", "\uD835\uDD0F", "\uD835\uDD10", "\uD835\uDD11", "\uD835\uDD12", "\uD835\uDD13", "\uD835\uDD14", "\uD835\uDD15", "\uD835\uDD16", "\uD835\uDD17", "\uD835\uDD18", "\uD835\uDD19", "\uD835\uDD1A", "\uD835\uDD1B", "\uD835\uDD1C", "\uD835\uDD1D"];
+var AMbbb = ["\uD835\uDD38", "\uD835\uDD39", "\uD835\uDD3A", "\uD835\uDD3B", "\uD835\uDD3C", "\uD835\uDD3D", "\uD835\uDD3E", "\uD835\uDD3F", "\uD835\uDD40", "\uD835\uDD41", "\uD835\uDD42", "\uD835\uDD43", "\uD835\uDD44", "\uD835\uDD45", "\uD835\uDD46", "\uD835\uDD47", "\uD835\uDD48", "\uD835\uDD49", "\uD835\uDD4A", "\uD835\uDD4B", "\uD835\uDD4C", "\uD835\uDD4D", "\uD835\uDD4E", "\uD835\uDD4F", "\uD835\uDD50", "\uD835\uDD51"];
+
+var CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4,
+    RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8,
+    TEXT = 9, BIG = 10, LONG = 11, STRETCHY = 12, MATRIX = 13; // token types
+
+var AMsqrt = {input:"\\sqrt",	tag:"msqrt", output:"sqrt",	ttype:UNARY},
+  AMnot = {input:"\\not",	tag:"mnot", output:"not",	ttype:UNARY},
+  AMroot = {input:"\\root",	tag:"mroot", output:"root",	ttype:BINARY},
+  AMfrac = {input:"\\frac",	tag:"mfrac", output:"/",	ttype:BINARY},
+  AMover = {input:"\\stackrel", tag:"mover", output:"stackrel", ttype:BINARY},
+  AMatop = {input:"\\atop",	tag:"mfrac", output:"",		ttype:INFIX},
+  AMchoose = {input:"\\choose", tag:"mfrac", output:"",		ttype:INFIX},
+  AMsub  = {input:"_",		tag:"msub",  output:"_",	ttype:INFIX},
+  AMsup  = {input:"^",		tag:"msup",  output:"^",	ttype:INFIX},
+  AMtext = {input:"\\mathrm",	tag:"mtext", output:"text",	ttype:TEXT},
+  AMmbox = {input:"\\mbox",	tag:"mtext", output:"mbox",	ttype:TEXT};
+
+// Commented out by DRW to prevent 1/2 turning into a 2-line fraction
+// AMdiv   = {input:"/",	 tag:"mfrac", output:"/",    ttype:INFIX},
+// Commented out by DRW so that " prints literally in equations
+// AMquote = {input:"\"",	 tag:"mtext", output:"mbox", ttype:TEXT};
+
+// List of negations obtained from http://frodo.elon.edu/tutorial/tutorial.pdf
+var AMRelationNegations = {
+  "\u003C":"\u226E", "\u003E":"\u226F", "\u2264":"\u2270", "\u2265":"\u2271",
+  "\u003D":"\u2260", "\u2261":"\u2262", "\u227A":"\u2280", "\u227B":"\u2281",
+  "\u227C":"\u22E0", "\u227D":"\u22E1", "\u223C":"\u2241", "\u2243":"\u2244",
+  "\u2282":"\u2284", "\u2283":"\u2285", "\u2286":"\u2288", "\u2287":"\u2289",
+  "\u2248":"\u2249", "\u2245":"\u2247", "\u2291":"\u22E2", "\u2292":"\u22E3",
+  "\u224D":"\u226D"
+}
+
+var AMsymbols = [
+//Greek letters
+{input:"\\alpha",	tag:"mi", output:"\u03B1", ttype:CONST},
+{input:"\\beta",	tag:"mi", output:"\u03B2", ttype:CONST},
+{input:"\\gamma",	tag:"mi", output:"\u03B3", ttype:CONST},
+{input:"\\delta",	tag:"mi", output:"\u03B4", ttype:CONST},
+{input:"\\epsilon",	tag:"mi", output:"\u03B5", ttype:CONST},
+{input:"\\varepsilon",  tag:"mi", output:"\u025B", ttype:CONST},
+{input:"\\zeta",	tag:"mi", output:"\u03B6", ttype:CONST},
+{input:"\\eta",		tag:"mi", output:"\u03B7", ttype:CONST},
+{input:"\\theta",	tag:"mi", output:"\u03B8", ttype:CONST},
+{input:"\\vartheta",	tag:"mi", output:"\u03D1", ttype:CONST},
+{input:"\\iota",	tag:"mi", output:"\u03B9", ttype:CONST},
+{input:"\\kappa",	tag:"mi", output:"\u03BA", ttype:CONST},
+{input:"\\lambda",	tag:"mi", output:"\u03BB", ttype:CONST},
+{input:"\\mu",		tag:"mi", output:"\u03BC", ttype:CONST},
+{input:"\\nu",		tag:"mi", output:"\u03BD", ttype:CONST},
+{input:"\\xi",		tag:"mi", output:"\u03BE", ttype:CONST},
+{input:"\\pi",		tag:"mi", output:"\u03C0", ttype:CONST},
+{input:"\\varpi",	tag:"mi", output:"\u03D6", ttype:CONST},
+{input:"\\rho",		tag:"mi", output:"\u03C1", ttype:CONST},
+{input:"\\varrho",	tag:"mi", output:"\u03F1", ttype:CONST},
+{input:"\\varsigma",	tag:"mi", output:"\u03C2", ttype:CONST},
+{input:"\\sigma",	tag:"mi", output:"\u03C3", ttype:CONST},
+{input:"\\tau",		tag:"mi", output:"\u03C4", ttype:CONST},
+{input:"\\upsilon",	tag:"mi", output:"\u03C5", ttype:CONST},
+{input:"\\phi",		tag:"mi", output:"\u03C6", ttype:CONST},
+{input:"\\varphi",	tag:"mi", output:"\u03D5", ttype:CONST},
+{input:"\\chi",		tag:"mi", output:"\u03C7", ttype:CONST},
+{input:"\\psi",		tag:"mi", output:"\u03C8", ttype:CONST},
+{input:"\\omega",	tag:"mi", output:"\u03C9", ttype:CONST},
+{input:"\\Gamma",	tag:"mo", output:"\u0393", ttype:CONST},
+{input:"\\Delta",	tag:"mo", output:"\u0394", ttype:CONST},
+{input:"\\Theta",	tag:"mo", output:"\u0398", ttype:CONST},
+{input:"\\Lambda",	tag:"mo", output:"\u039B", ttype:CONST},
+{input:"\\Xi",		tag:"mo", output:"\u039E", ttype:CONST},
+{input:"\\Pi",		tag:"mo", output:"\u03A0", ttype:CONST},
+{input:"\\Sigma",	tag:"mo", output:"\u03A3", ttype:CONST},
+{input:"\\Upsilon",	tag:"mo", output:"\u03A5", ttype:CONST},
+{input:"\\Phi",		tag:"mo", output:"\u03A6", ttype:CONST},

(Diff truncated)

diff --git a/jsMath/COPYING.txt b/jsMath/COPYING.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/jsMath/COPYING.txt
@@ -0,0 +1,202 @@
+
+                           Version 2.0, January 2004
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+
+   END OF TERMS AND CONDITIONS
+
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at

(Diff truncated)

cleanup
diff --git a/mathml.js b/mathml.js
deleted file mode 100644
index a72c2e5..0000000
--- a/mathml.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-March 19, 2004 MathHTML (c) Peter Jipsen http://www.chapman.edu/~jipsen
-Released under the GNU General Public License version 2 or later.
-See the GNU General Public License (at http://www.gnu.org/copyleft/gpl.html)
-for more details.
-*/
-
-function convertMath(node) {// for Gecko
-  if (node.nodeType==1) {
-    var newnode =
-      document.createElementNS("http://www.w3.org/1998/Math/MathML",
-        node.nodeName.toLowerCase());
-    for(var i=0; i < node.attributes.length; i++)
-      newnode.setAttribute(node.attributes[i].nodeName,
-        node.attributes[i].nodeValue);
-    for (var i=0; i<node.childNodes.length; i++) {
-      var st = node.childNodes[i].nodeValue;
-      if (st==null || st.slice(0,1)!=" " && st.slice(0,1)!="\n")
-        newnode.appendChild(convertMath(node.childNodes[i]));
-    }
-    return newnode;
-  }
-  else return node;
-}
-
-function convert() {
-  var mmlnode = document.getElementsByTagName("math");
-  var st,str,node,newnode;
-  for (var i=0; i<mmlnode.length; i++)
-    if (document.createElementNS!=null)
-      mmlnode[i].parentNode.replaceChild(convertMath(mmlnode[i]),mmlnode[i]);
-    else { // convert for IE
-      str = "";
-      node = mmlnode[i];
-      while (node.nodeName!="/MATH") {
-        st = node.nodeName.toLowerCase();
-        if (st=="#text") str += node.nodeValue;
-        else {
-          str += (st.slice(0,1)=="/" ? "</m:"+st.slice(1) : "<m:"+st);
-          if (st.slice(0,1)!="/")
-             for(var j=0; j < node.attributes.length; j++)
-               if (node.attributes[j].nodeValue!="italic" &&
-                 node.attributes[j].nodeValue!="" &&
-                 node.attributes[j].nodeValue!="inherit" &&
-                 node.attributes[j].nodeValue!=undefined)
-                 str += " "+node.attributes[j].nodeName+"="+
-                     "\""+node.attributes[j].nodeValue+"\"";
-          str += ">";
-        }
-        node = node.nextSibling;
-        node.parentNode.removeChild(node.previousSibling);
-      }
-      str += "</m:math>";
-      newnode = document.createElement("span");
-      node.parentNode.replaceChild(newnode,node);
-      newnode.innerHTML = str;
-    }
-}
-
-if (document.createElementNS==null) {
-  document.write("<object id=\"mathplayer\"\
-  classid=\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\"></object>");
-  document.write("<?import namespace=\"m\" implementation=\"#mathplayer\"?>");
-}
-}
-if(typeof window.attachEvent != 'undefined') {
-}


diff --git a/sandbox.mdwn b/sandbox.mdwn
index 8eaa89e..4a28975 100644
--- a/sandbox.mdwn
+++ b/sandbox.mdwn
@@ -3,7 +3,7 @@ This is the SandBox, a page anyone can edit to learn how to use the wiki.  Here
Here is [[!img y-combinator.jpg size="200x200" alt="clouds"]]. And rest of paragraph.

Try some math:
-<img src="/cgi-bin/mathtex.cgi?x=\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi}">. Okay, that's it!
+<img src="/cgi-bin/mathtex.cgi?x=\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi^\i}">. Okay, that's it!

----
[[!inline pages="tagged(foo)" show=0 archive=yes]]


diff --git a/sandbox.mdwn b/sandbox.mdwn
index aeea770..8eaa89e 100644
--- a/sandbox.mdwn
+++ b/sandbox.mdwn
@@ -3,7 +3,7 @@ This is the SandBox, a page anyone can edit to learn how to use the wiki.  Here
Here is [[!img y-combinator.jpg size="200x200" alt="clouds"]]. And rest of paragraph.

Try some math:
-<img src="/cgi-bin/mathtex.cgi?x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}">. Okay, that's it!
+<img src="/cgi-bin/mathtex.cgi?x=\frac{-b\pm\sqrt{b^2-4ac}}{2a\pi}">. Okay, that's it!

----
[[!inline pages="tagged(foo)" show=0 archive=yes]]


diff --git a/sandbox.mdwn b/sandbox.mdwn
index bd1e8e8..aeea770 100644
--- a/sandbox.mdwn
+++ b/sandbox.mdwn
@@ -3,7 +3,7 @@ This is the SandBox, a page anyone can edit to learn how to use the wiki.  Here
Here is [[!img y-combinator.jpg size="200x200" alt="clouds"]]. And rest of paragraph.

Try some math:
-<img src="/cgi-bin/mathtex.cgi?x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}">. Okay, that's it.
+<img src="/cgi-bin/mathtex.cgi?x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}">. Okay, that's it!

----
[[!inline pages="tagged(foo)" show=0 archive=yes]]


diff --git a/sandbox.mdwn b/sandbox.mdwn
index a3e7c85..bd1e8e8 100644
--- a/sandbox.mdwn
+++ b/sandbox.mdwn
@@ -3,7 +3,7 @@ This is the SandBox, a page anyone can edit to learn how to use the wiki.  Here
Here is [[!img y-combinator.jpg size="200x200" alt="clouds"]]. And rest of paragraph.

Try some math:
-<img src="/cgi-bin/mimetex.cgi?x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}">. Okay, that's it.
+<img src="/cgi-bin/mathtex.cgi?x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}">. Okay, that's it.

----
[[!inline pages="tagged(foo)" show=0 archive=yes]]


cleanup
diff --git a/index.pdc b/index.pdc
deleted file mode 100644
index 3a2b976..0000000
--- a/index.pdc
+++ /dev/null
@@ -1,298 +0,0 @@
-# Seminar in Semantics / Philosophy of Language #
-
-or: **What Philosophers and Linguists Can Learn From Theoretical Computer Science But Didn't Know To Ask**
-
-This course is co-taught by [Chris Barker](http://homepages.nyu.edu/~cb125/) and [Jim Pryor](http://www.jimpryor.net/). Linguistics calls it "G61.3340-002" and Philosophy calls it "G83.2296-001."
-The seminar meets on Mondays from 4-6, in
-the Linguistics building at 10 Washington Place, in room 104 (back of the first floor).
-One student session will be held every Wednesday from 3-4 on the
-fourth floor at 10 Washington Place.
-
-## Announcements ##
-
-<!--
-*	This is the time of the semester when some people start slipping
-behind with the homework.  Don't.
--->
-
-*	We've added a page on [[Translating between OCaml Scheme and Haskell]]
-
-*	We've added some [commentary](/hints/assignment_6_commentary) on some common issues in your solutions to [[Assignment6]].
-
-
-*	We've posted a [[State Monad Tutorial]].
-
-[[Older Announcements]]
-
-##[[Lambda Evaluator]]##
-
-the homework questions works correctly.
-
-There is also now a [library](/lambda_library) of lambda-calculus
-arithmetical and list operations, some relatively advanced.
-
-
-
-## Lecture Notes and Assignments ##
-
-(13 Sept) Lecture notes for [[Week1]]; [[Assignment1]].
-
->	Topics: [[Applications]], including [[Damn]]; Basics of Lambda Calculus; Comparing Different Languages
-
-(20 Sept) Lecture notes for [[Week2]]; [[Assignment2]].
-
->	Topics: Reduction and Convertibility; Combinators; Evaluation Strategies and Normalization; Decidability; [[Lists and Numbers]]
-
-(27 Sept) Lecture notes for [[Week3]];  [[Assignment3]];
-an evaluator with the definitions used for homework 3
-preloaded is available at [[assignment 3 evaluator]].
-
->	Topics: [[Evaluation Order]]; Recursion with Fixed Point Combinators
-
-(4 Oct) Lecture notes for [[Week4]]; [[Assignment4]].
-
->	Topics: More on Fixed Points; Sets; Aborting List Traversals; [[Implementing Trees]]
-
-
-(18 Oct, 25 Oct) Lecture notes for [[Week5]] and [[Week6]]; [[Assignment5]].
-
->	Topics: Types, Polymorphism, Unit and Bottom
-
-(1 Nov) Lecture notes for [[Week7]]; [[Assignment6]].
-
-
-(8 Nov) Lecture notes for [[Week8]].
-
-
-(15 Nov) Lecture notes for [[Week9]]; [[Assignment7]]. Everyone auditing in the class is encouraged to do this assignment, or at least work through the substantial "hints".
-
->	Topics: Mutable Variables; Passing by Reference; [[State Monad Tutorial]] (added recently)
-
-(22 Nov) Lecture notes for [[Week10]]
-
->	Topics: Calculator Improvements, including mutation
-
-(30 Nov) Lecture notes for [[Week11]]; [[Assignment8]].
-
->	Topics: [[Tree and List Zippers]]; [[Coroutines and Aborts]]; [[From List Zippers to Continuations]]
-
-(6 Dec) Lecture notes for [[Week12]]; [[Assignment9]].
-
-
-(13 Dec) Lecture notes for Week13; [[Assignment10]].
-
->	Topics: [[CPS and Continuation Operators]]; Curry-Howard
-
-
->	Topics: Version 4 lists, Monads in Category Theory
-
-##Scheme and OCaml##
-
-See [below](#installing) for how to get the programming languages running on your computer.
-
-*	Links for help [[learning Scheme]]
-
-*	Links for help [[learning OCaml]]
-
-*	[[Translating between OCaml Scheme and Haskell]]
-
-
-
-There's lots of links here already to tutorials and encyclopedia entries about many of the notions we'll be dealing with.
-
-
-
-## Course Overview ##
-
-The goal of this seminar is to introduce concepts and techniques from
-theoretical computer science and show how they can provide insight
-into established philosophical and linguistic problems.
-
-This is not a seminar about any particular technology or software.
-Rather, it's about a variety of conceptual/logical ideas that have been
-developed in computer science and that linguists and philosophers ought to
-know, or may already be unknowingly trying to reinvent.
-
-Philosphers and linguists tend to reuse the same familiar tools in
-ever more (sometime spectacularly) creative ways.  But when your only
-hammer is classical logic, every problem looks like modus ponens.  In
-contrast, computer scientists have invested considerable ingenuity in
-studying tool design, and have made remarkable progress.
-
-"Why shouldn't I reinvent some idea X for myself? It's intellectually
-rewarding!" Yes it is, but it also takes time you might have better
-spent elsewhere. After all, you can get anywhere you want to go by walking, but you can
-accomplish more with a combination of walking and strategic subway
-rides.
-
-More importantly, the idiosyncrasies of your particular
-implementation may obscure what's fundamental to the idea you're
-working with. Your implementation may be buggy in corner cases you
-didn't think of; it may be incomplete and not trivial to generalize; its
-connection to existing literature and neighboring issues may go
-unnoticed. For all these reasons you're better off understanding the
-state of the art.
-
-The theoretical tools we'll be introducing aren't very familiar to
-everyday programmers, but they are prominent in academic computer science,
-especially in the fields of functional programming and type theory.
-
-Of necessity, this course will lay a lot of logical groundwork. But throughout
-we'll be aiming to mix that groundwork with real cases
-in our home subjects where these tools play central roles. Our aim for the
-course is to enable you to make these tools your own; to have enough
-understanding of them to recognize them in use, use them yourself at least
-in simple ways, and to be able to read more about them when appropriate.
-
-Once we get up and running, the central focii of the course will be
-**continuations**, **types**, and **monads**. One of the on-going themes will
-concern evaluation order and issues about how computations (inferences,
-derivations) unfold in (for instance) time.  The key analytic technique is to
-form a static, order-independent model of a dynamic process. We'll be
-discussing this in much more detail as the course proceeds.
-
-The logical systems we'll be looking at include:
-
-*	the pure/untyped lambda calculus
-*	combinatorial logic
-*	the simply-typed lambda calculus
-*	polymorphic types with System F
-*	some discussion of dependent types
-*	if time permits, "indeterministic" or "preemptively parallel" computation and linear logic
-
-
-<!--
-Other keywords:
-	recursion using the Y-combinator
-	evaluation-order stratgies
-	normalizing properties
-	the Curry-Howard isomorphism(s)
-	monads in category theory and computation
--->
-
-## Who Can Participate? ##
-
-The course will not presume previous experience with programming.  We
-will, however, discuss concepts embodied in specific programming
-languages, and we will encourage experimentation with running,
-modifying, and writing computer programs.
-
-The course will not presume lots of mathematical or logical background, either.
-However, it will demand a certain amount of comfort working with such material; as a result,
-it will not be especially well-suited to be a first graduate-level course
-in formal semantics or philosophy of language. If you have concerns about your
-background, come discuss them with us.
-
-This class will count as satisfying the logic requirement for Philosophy

(Diff truncated)

diff --git a/sandbox.mdwn b/sandbox.mdwn
index d86fec3..a3e7c85 100644
--- a/sandbox.mdwn
+++ b/sandbox.mdwn
@@ -3,7 +3,7 @@ This is the SandBox, a page anyone can edit to learn how to use the wiki.  Here
Here is [[!img y-combinator.jpg size="200x200" alt="clouds"]]. And rest of paragraph.

Try some math:
-<img src="/mimetex.cgi?x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}">. Okay, that's it.
+<img src="/cgi-bin/mimetex.cgi?x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}">. Okay, that's it.

----
[[!inline pages="tagged(foo)" show=0 archive=yes]]


diff --git a/sandbox.mdwn b/sandbox.mdwn
--- a/sandbox.mdwn
+++ b/sandbox.mdwn
@@ -2,6 +2,8 @@ This is the SandBox, a page anyone can edit to learn how to use the wiki.  Here

Here is [[!img y-combinator.jpg size="200x200" alt="clouds"]]. And rest of paragraph.

+Try some math:
+<img src="/mimetex.cgi?x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}">. Okay, that's it.

----
[[!inline pages="tagged(foo)" show=0 archive=yes]]


add some math rendering support files
diff --git a/index.iki b/index.iki
new file mode 100644
index 0000000..3a2b976
--- /dev/null
+++ b/index.iki
@@ -0,0 +1,298 @@
+# Seminar in Semantics / Philosophy of Language #
+
+or: **What Philosophers and Linguists Can Learn From Theoretical Computer Science But Didn't Know To Ask**
+
+This course is co-taught by [Chris Barker](http://homepages.nyu.edu/~cb125/) and [Jim Pryor](http://www.jimpryor.net/). Linguistics calls it "G61.3340-002" and Philosophy calls it "G83.2296-001."
+The seminar meets on Mondays from 4-6, in
+the Linguistics building at 10 Washington Place, in room 104 (back of the first floor).
+One student session will be held every Wednesday from 3-4 on the
+fourth floor at 10 Washington Place.
+
+## Announcements ##
+
+<!--
+*	This is the time of the semester when some people start slipping
+behind with the homework.  Don't.
+-->
+
+*	We've added a page on [[Translating between OCaml Scheme and Haskell]]
+
+*	We've added some [commentary](/hints/assignment_6_commentary) on some common issues in your solutions to [[Assignment6]].
+
+
+*	We've posted a [[State Monad Tutorial]].
+
+[[Older Announcements]]
+
+##[[Lambda Evaluator]]##
+
+the homework questions works correctly.
+
+There is also now a [library](/lambda_library) of lambda-calculus
+arithmetical and list operations, some relatively advanced.
+
+
+
+## Lecture Notes and Assignments ##
+
+(13 Sept) Lecture notes for [[Week1]]; [[Assignment1]].
+
+>	Topics: [[Applications]], including [[Damn]]; Basics of Lambda Calculus; Comparing Different Languages
+
+(20 Sept) Lecture notes for [[Week2]]; [[Assignment2]].
+
+>	Topics: Reduction and Convertibility; Combinators; Evaluation Strategies and Normalization; Decidability; [[Lists and Numbers]]
+
+(27 Sept) Lecture notes for [[Week3]];  [[Assignment3]];
+an evaluator with the definitions used for homework 3
+preloaded is available at [[assignment 3 evaluator]].
+
+>	Topics: [[Evaluation Order]]; Recursion with Fixed Point Combinators
+
+(4 Oct) Lecture notes for [[Week4]]; [[Assignment4]].
+
+>	Topics: More on Fixed Points; Sets; Aborting List Traversals; [[Implementing Trees]]
+
+
+(18 Oct, 25 Oct) Lecture notes for [[Week5]] and [[Week6]]; [[Assignment5]].
+
+>	Topics: Types, Polymorphism, Unit and Bottom
+
+(1 Nov) Lecture notes for [[Week7]]; [[Assignment6]].
+
+
+(8 Nov) Lecture notes for [[Week8]].
+
+
+(15 Nov) Lecture notes for [[Week9]]; [[Assignment7]]. Everyone auditing in the class is encouraged to do this assignment, or at least work through the substantial "hints".
+
+>	Topics: Mutable Variables; Passing by Reference; [[State Monad Tutorial]] (added recently)
+
+(22 Nov) Lecture notes for [[Week10]]
+
+>	Topics: Calculator Improvements, including mutation
+
+(30 Nov) Lecture notes for [[Week11]]; [[Assignment8]].
+
+>	Topics: [[Tree and List Zippers]]; [[Coroutines and Aborts]]; [[From List Zippers to Continuations]]
+
+(6 Dec) Lecture notes for [[Week12]]; [[Assignment9]].
+
+
+(13 Dec) Lecture notes for Week13; [[Assignment10]].
+
+>	Topics: [[CPS and Continuation Operators]]; Curry-Howard
+
+
+>	Topics: Version 4 lists, Monads in Category Theory
+
+##Scheme and OCaml##
+
+See [below](#installing) for how to get the programming languages running on your computer.
+
+*	Links for help [[learning Scheme]]
+
+*	Links for help [[learning OCaml]]
+
+*	[[Translating between OCaml Scheme and Haskell]]
+
+
+
+There's lots of links here already to tutorials and encyclopedia entries about many of the notions we'll be dealing with.
+
+
+
+## Course Overview ##
+
+The goal of this seminar is to introduce concepts and techniques from
+theoretical computer science and show how they can provide insight
+into established philosophical and linguistic problems.
+
+This is not a seminar about any particular technology or software.
+Rather, it's about a variety of conceptual/logical ideas that have been
+developed in computer science and that linguists and philosophers ought to
+know, or may already be unknowingly trying to reinvent.
+
+Philosphers and linguists tend to reuse the same familiar tools in
+ever more (sometime spectacularly) creative ways.  But when your only
+hammer is classical logic, every problem looks like modus ponens.  In
+contrast, computer scientists have invested considerable ingenuity in
+studying tool design, and have made remarkable progress.
+
+"Why shouldn't I reinvent some idea X for myself? It's intellectually
+rewarding!" Yes it is, but it also takes time you might have better
+spent elsewhere. After all, you can get anywhere you want to go by walking, but you can
+accomplish more with a combination of walking and strategic subway
+rides.
+
+More importantly, the idiosyncrasies of your particular
+implementation may obscure what's fundamental to the idea you're
+working with. Your implementation may be buggy in corner cases you
+didn't think of; it may be incomplete and not trivial to generalize; its
+connection to existing literature and neighboring issues may go
+unnoticed. For all these reasons you're better off understanding the
+state of the art.
+
+The theoretical tools we'll be introducing aren't very familiar to
+everyday programmers, but they are prominent in academic computer science,
+especially in the fields of functional programming and type theory.
+
+Of necessity, this course will lay a lot of logical groundwork. But throughout
+we'll be aiming to mix that groundwork with real cases
+in our home subjects where these tools play central roles. Our aim for the
+course is to enable you to make these tools your own; to have enough
+understanding of them to recognize them in use, use them yourself at least
+in simple ways, and to be able to read more about them when appropriate.
+
+Once we get up and running, the central focii of the course will be
+**continuations**, **types**, and **monads**. One of the on-going themes will
+concern evaluation order and issues about how computations (inferences,
+derivations) unfold in (for instance) time.  The key analytic technique is to
+form a static, order-independent model of a dynamic process. We'll be
+discussing this in much more detail as the course proceeds.
+
+The logical systems we'll be looking at include:
+
+*	the pure/untyped lambda calculus
+*	combinatorial logic
+*	the simply-typed lambda calculus
+*	polymorphic types with System F
+*	some discussion of dependent types
+*	if time permits, "indeterministic" or "preemptively parallel" computation and linear logic
+
+
+<!--
+Other keywords:
+	recursion using the Y-combinator
+	evaluation-order stratgies
+	normalizing properties
+	the Curry-Howard isomorphism(s)
+	monads in category theory and computation
+-->
+
+## Who Can Participate? ##
+
+The course will not presume previous experience with programming.  We
+will, however, discuss concepts embodied in specific programming
+languages, and we will encourage experimentation with running,
+modifying, and writing computer programs.
+
+The course will not presume lots of mathematical or logical background, either.
+However, it will demand a certain amount of comfort working with such material; as a result,
+it will not be especially well-suited to be a first graduate-level course
+in formal semantics or philosophy of language. If you have concerns about your
+background, come discuss them with us.
+
+This class will count as satisfying the logic requirement for Philosophy

(Diff truncated)

diff --git a/index.pdc b/index.pdc
index 9303110..3a2b976 100644
--- a/index.pdc
+++ b/index.pdc
@@ -6,7 +6,7 @@ This course is co-taught by [Chris Barker](http://homepages.nyu.edu/~cb125/) and
The seminar meets on Mondays from 4-6, in
the Linguistics building at 10 Washington Place, in room 104 (back of the first floor).
One student session will be held every Wednesday from 3-4 on the
-fourth floor at 10 Washington Place. Here is $some^2 x^{e \pi} + 3y$ math, and $$here_{is} some + more$$. End of math.
+fourth floor at 10 Washington Place.

## Announcements ##


diff --git a/index.pdc b/index.pdc
index 3a2b976..9303110 100644
--- a/index.pdc
+++ b/index.pdc
@@ -6,7 +6,7 @@ This course is co-taught by [Chris Barker](http://homepages.nyu.edu/~cb125/) and
The seminar meets on Mondays from 4-6, in
the Linguistics building at 10 Washington Place, in room 104 (back of the first floor).
One student session will be held every Wednesday from 3-4 on the
-fourth floor at 10 Washington Place.
+fourth floor at 10 Washington Place. Here is $some^2 x^{e \pi} + 3y$ math, and $$here_{is} some + more$$. End of math.

## Announcements ##


removed
diff --git a/test/uno.pdc b/test/uno.pdc
deleted file mode 100644
index f15acde..0000000
--- a/test/uno.pdc
+++ /dev/null
@@ -1,5 +0,0 @@
-Sample.
-
-    Markdown &omega; doesn't convert.
-
-oh well. Why not go to [[two]]?


rename test/one.mdwn to test/uno.pdc
diff --git a/test/one.mdwn b/test/one.mdwn
deleted file mode 100644
index f15acde..0000000
--- a/test/one.mdwn
+++ /dev/null
@@ -1,5 +0,0 @@
-Sample.
-
-    Markdown &omega; doesn't convert.
-
-oh well. Why not go to [[two]]?
diff --git a/test/uno.pdc b/test/uno.pdc
new file mode 100644
index 0000000..f15acde
--- /dev/null
+++ b/test/uno.pdc
@@ -0,0 +1,5 @@
+Sample.
+
+    Markdown &omega; doesn't convert.
+
+oh well. Why not go to [[two]]?


removed
diff --git a/test/two.pdc b/test/two.pdc
deleted file mode 100644
index 7ca29b2..0000000
--- a/test/two.pdc
+++ /dev/null
@@ -1 +0,0 @@
-This is just [[!tag foo bar]] some talk.


diff --git a/sandbox.mdwn b/sandbox.mdwn
--- a/sandbox.mdwn
+++ b/sandbox.mdwn
@@ -4,7 +4,7 @@ Here is [[!img y-combinator.jpg size="200x200" alt="clouds"]]. And rest of parag

----
+[[!inline pages="tagged(foo)" show=0 archive=yes]]

<!--
[[!inline  pages="test/* and !*/Discussion" show="3" rootpage="test"]]


diff --git a/sandbox.mdwn b/sandbox.mdwn
index c866667..4a24211 100644
--- a/sandbox.mdwn
+++ b/sandbox.mdwn
@@ -4,8 +4,11 @@ Here is [[!img y-combinator.jpg size="200x200" alt="clouds"]]. And rest of parag

----

+<!--
[[!inline  pages="test/* and !*/Discussion" show="3" rootpage="test"]]
+-->

----


diff --git a/test/one.mdwn b/test/one.mdwn
index 71b881b..f15acde 100644
--- a/test/one.mdwn
+++ b/test/one.mdwn
@@ -2,4 +2,4 @@ Sample.

Markdown &omega; doesn't convert.

-oh well.
+oh well. Why not go to [[two]]?


diff --git a/test/two.pdc b/test/two.pdc
index 8b13789..7ca29b2 100644
--- a/test/two.pdc
+++ b/test/two.pdc
@@ -1 +1 @@
-
+This is just [[!tag foo bar]] some talk.


diff --git a/sandbox.mdwn b/sandbox.mdwn
index a6c8aca..c866667 100644
--- a/sandbox.mdwn
+++ b/sandbox.mdwn
@@ -2,17 +2,6 @@ This is the SandBox, a page anyone can edit to learn how to use the wiki.  Here

Here is [[!img y-combinator.jpg size="200x200" alt="clouds"]]. And rest of paragraph.

-[[!toggle  id="ipsum" text="show"]]
-
-[[!toggleable  id="ipsum" text="""
-Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
-eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
-ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
-aliquip ex ea commodo consequat.
-
-[[!toggle id="ipsum" text="hide"]]
-"""]]
-

----


diff --git a/test/two.pdc b/test/two.pdc
index 9ae0e51..8b13789 100644
--- a/test/two.pdc
+++ b/test/two.pdc
@@ -1,5 +1 @@
-Sample.

-    Pandoc &omega; doesn't convert.
-
-yay!


diff --git a/sandbox.mdwn b/sandbox.mdwn
index 0183cf4..a6c8aca 100644
--- a/sandbox.mdwn
+++ b/sandbox.mdwn
@@ -2,6 +2,20 @@ This is the SandBox, a page anyone can edit to learn how to use the wiki.  Here

Here is [[!img y-combinator.jpg size="200x200" alt="clouds"]]. And rest of paragraph.

+[[!toggle  id="ipsum" text="show"]]
+
+[[!toggleable  id="ipsum" text="""
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
+eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
+ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
+aliquip ex ea commodo consequat.
+
+[[!toggle id="ipsum" text="hide"]]
+"""]]
+
+
+----
+
[[!inline  pages="test/* and !*/Discussion" show="3" rootpage="test"]]

----

`