\start
Date: Wed, 1 Nov 2017 18:05:33 +0000
From: gad9972 <gad9972@googlemail.com>
To: Tim Daly <axiomcas@gmail.com>, axiom-developer@nongnu.org
Subject: Re: [Axiom-developer] Catching up on internals

On 31 Oct 2017 12:29 p.m., "Tim Daly" <axiomcas@gmail.com> wrote:

Martin,

\begin{verbatim}What possible advantage would it be to have the interpreter in Spad?

Assuming you want to move away from Lisp you would also have to
code the compiler in Spad.


Tim,

Well, at least it would be a first step in moving away from lisp. I would
really like more mainstream base language that supports parallel code and
more powerful libraries for graphics and so on. I think parallel code is
very important, I think mathematics has a lot of inherent parallelism
(vectors for example).

The main issue is that I find it extremely difficult to work out what a
given piece of Lisp/boot code does. If I look at a given function there is
no clues about the structure of its parameters or what  variables are being
used or what they are used for. I think it's because Lisp/boot uses a
single type (feels like dynamic typing) and global variables it is very
hard to understand code. I suspect your answer to this might be
documentation and I agree that documentation is very important but I don't
think it's a fix for spaghetti code.

I understand that Lisp is an epiphany language (i.e. you hate it until
you "get it" and then you love it)


I can see that Lisp is quite mathematical (lambda calculus) and I can see
that it allows the original programmer to be very creative, but when trying
to understand other peoples code, creative is not what I need. I want a
language with meaningful types and minimal global variables.

Sorry, I didn't mean this to be a discussion about the pros and cons of
various languages. I am sure we won't change each others mind about this. I
just wanted to explain why I'm keen to find a way to convert boot to SPAD
as discussed on my web page.

Martin B

\start
Date: Wed, 1 Nov 2017 16:03:22 -0400
From: Tim Daly <axiomcas@gmail.com>
To: gad9972 <gad9972@googlemail.com>
Subject: Re: [Axiom-developer] Catching up on internals

The issue of the current lisp code is related to several factors. Scratchpad
was implemented in maclisp, ported to lispvm, and then ported to common
lisp (I did large portions of the CL port). So the code is a macro-mangled
version of several lisps. In addition, there was another language (called
Meta) that was part of the build process making life more complex. Boot
added to that complexity by making it unreasonable to write good lisp
code that takes advantage of Common lisp. Nobody writes CL code
using lists of lists of lists and cadadr accesses.

Common lisp code can be very readable. It is easy to write in a functional
style and structure the data in a more rational fashion. I've been working
in that direction.

You're right that nobody is going to change their minds about this issue,
of course. It's one of the reasons for a fork. But if you're going to put
forth
the effort to rewrite the compiler in Spad it might be worthwhile to create
a specification of what it does now before trying to write Spad code.
There are a lot of subtle hacks (e.g. add chain searches) that would be
useful to explain.

Another thought is that Aldor was an attempt to re-write the world into
a higher level language. I spent 4 years of PhD research trying to move
Axiom's algebra library into Aldor. Aldor was supposed to be the
replacement compiler for Scratchpad. Unfortunately it suffers from
"the second system effect", losing sight of the primary goal. You could
consider moving the algebra to Aldor but I don't recommend it.

Tim



On Wed, Nov 1, 2017 at 2:05 PM, gad9972 <gad9972@googlemail.com> wrote:

> On 31 Oct 2017 12:29 p.m., "Tim Daly" <axiomcas@gmail.com> wrote:
>
> Martin,
>
> What possible advantage would it be to have the interpreter in Spad?
>
> Assuming you want to move away from Lisp you would also have to
> code the compiler in Spad.
>
>
> Tim,
>
> Well, at least it would be a first step in moving away from lisp. I would
> really like more mainstream base language that supports parallel code and
> more powerful libraries for graphics and so on. I think parallel code is
> very important, I think mathematics has a lot of inherent parallelism
> (vectors for example).
>
> The main issue is that I find it extremely difficult to work out what a
> given piece of Lisp/boot code does. If I look at a given function there is
> no clues about the structure of its parameters or what  variables are being
> used or what they are used for. I think it's because Lisp/boot uses a
> single type (feels like dynamic typing) and global variables it is very
> hard to understand code. I suspect your answer to this might be
> documentation and I agree that documentation is very important but I don't
> think it's a fix for spaghetti code.
>
> I understand that Lisp is an epiphany language (i.e. you hate it until
> you "get it" and then you love it)
>
>
> I can see that Lisp is quite mathematical (lambda calculus) and I can see
> that it allows the original programmer to be very creative, but when trying
> to understand other peoples code, creative is not what I need. I want a
> language with meaningful types and minimal global variables.
>
> Sorry, I didn't mean this to be a discussion about the pros and cons of
> various languages. I am sure we won't change each others mind about this. I
> just wanted to explain why I'm keen to find a way to convert boot to SPAD
> as discussed on my web page.
>
> Martin B
>

\start
Date: Thu, 2 Nov 2017 17:10:56 -0400
From: Tim Daly <axiomcas@gmail.com>
To: gad9972 <gad9972@googlemail.com>, Tim Daly <daly@axiom-developer.org>
Subject: Re: [Axiom-developer] Catching up on internals

Another thought... While people don't seem to like lisp as a platform
it does have major advantages. I usually find myself using the lisp
debugging facilities (trace, break, and REPL evaluation) to find
out what failed and where.

If you go from Spad to executable code you lose all of that.


On Wed, Nov 1, 2017 at 4:03 PM, Tim Daly <axiomcas@gmail.com> wrote:

> The issue of the current lisp code is related to several factors.
> Scratchpad
> was implemented in maclisp, ported to lispvm, and then ported to common
> lisp (I did large portions of the CL port). So the code is a macro-mangled
> version of several lisps. In addition, there was another language (called
> Meta) that was part of the build process making life more complex. Boot
> added to that complexity by making it unreasonable to write good lisp
> code that takes advantage of Common lisp. Nobody writes CL code
> using lists of lists of lists and cadadr accesses.
>
> Common lisp code can be very readable. It is easy to write in a functional
> style and structure the data in a more rational fashion. I've been working
> in that direction.
>
> You're right that nobody is going to change their minds about this issue,
> of course. It's one of the reasons for a fork. But if you're going to put
> forth
> the effort to rewrite the compiler in Spad it might be worthwhile to create
> a specification of what it does now before trying to write Spad code.
> There are a lot of subtle hacks (e.g. add chain searches) that would be
> useful to explain.
>
> Another thought is that Aldor was an attempt to re-write the world into
> a higher level language. I spent 4 years of PhD research trying to move
> Axiom's algebra library into Aldor. Aldor was supposed to be the
> replacement compiler for Scratchpad. Unfortunately it suffers from
> "the second system effect", losing sight of the primary goal. You could
> consider moving the algebra to Aldor but I don't recommend it.
>
> Tim
>
>
>
> On Wed, Nov 1, 2017 at 2:05 PM, gad9972 <gad9972@googlemail.com> wrote:
>
>> On 31 Oct 2017 12:29 p.m., "Tim Daly" <axiomcas@gmail.com> wrote:
>>
>> Martin,
>>
>> What possible advantage would it be to have the interpreter in Spad?
>>
>> Assuming you want to move away from Lisp you would also have to
>> code the compiler in Spad.
>>
>>
>> Tim,
>>
>> Well, at least it would be a first step in moving away from lisp. I would
>> really like more mainstream base language that supports parallel code and
>> more powerful libraries for graphics and so on. I think parallel code is
>> very important, I think mathematics has a lot of inherent parallelism
>> (vectors for example).
>>
>> The main issue is that I find it extremely difficult to work out what a
>> given piece of Lisp/boot code does. If I look at a given function there is
>> no clues about the structure of its parameters or what  variables are being
>> used or what they are used for. I think it's because Lisp/boot uses a
>> single type (feels like dynamic typing) and global variables it is very
>> hard to understand code. I suspect your answer to this might be
>> documentation and I agree that documentation is very important but I don't
>> think it's a fix for spaghetti code.
>>
>> I understand that Lisp is an epiphany language (i.e. you hate it until
>> you "get it" and then you love it)
>>
>>
>> I can see that Lisp is quite mathematical (lambda calculus) and I can see
>> that it allows the original programmer to be very creative, but when trying
>> to understand other peoples code, creative is not what I need. I want a
>> language with meaningful types and minimal global variables.
>>
>> Sorry, I didn't mean this to be a discussion about the pros and cons of
>> various languages. I am sure we won't change each others mind about this. I
>> just wanted to explain why I'm keen to find a way to convert boot to SPAD
>> as discussed on my web page.
>>
>> Martin B
>>
>
>

\start
Date: Fri, 3 Nov 2017 18:27:58 +0000
From: Martin Baker <ax87438@martinb.com>
To: Tim Daly <axiomcas@gmail.com>, axiom-developer@nongnu.org,
Subject: Re: [Axiom-developer] Catching up on internals

On 02/11/17 21:10, Tim Daly wrote:
> Another thought... While people don't seem to like lisp as a platform
> it does have major advantages. I usually find myself using the lisp
> debugging facilities (trace, break, and REPL evaluation) to find
> out what failed and where.
> 
> If you go from Spad to executable code you lose all of that.

Tim,

This is one of the problems, in my view, in that Lisp shows through 
underneath SPAD. That is debugging, error messages, outputs, etc. are 
often formatted as Lisp or require Lisp knowledge. I think this is 
particularly important for potential new users. SPAD has a steep enough 
learning curve on its own without needing to learn Lisp. Could it be 
things like this that prevent new user take up and explain the limited 
amount of discussion here?

What I would like would be a clean language for people interested in 
mathematics without all the baggage of having to learn lots of 
(non-mainstream) computer stuff that's not really about the mathematics.

Martin B

\start
Date: Fri, 3 Nov 2017 20:42:01 -0400
From: Tim Daly <axiomcas@gmail.com>
To: Martin Baker <ax87438@martinb.com>
Subject: Re: [Axiom-developer] Catching up on internals

That seems reasonable, except for the fact that any non-algebra error that
does
show up has to exhibit itself somehow. Worst case is a core dump. Spad does
not define robust error handling primitives. Local try-catch is reasonable
but
it is not clear how to handle things like restarts, tracebacks, etc. when
the
non-algebra error occurs. How would you model handling errors in Spad?

I do think that there might be an interesting research question of how to
handle classes of errors in computational mathematics. I had proposed
using Provisos to handle side-conditions on formulas. Hoon Hong and
Chris Brown have done a lot of work on QEPCAD for handling these.
Manuel Bronstein and I had long discussions about a SUCHTHAT domain
for encapsulating Provisos but little code resulted as the QEPCAD work
was still in the future at the time.

As for writing Axiom in Spad, you find that compiling Axiom to efficient but
generic code relies heavily on trampolines and symbol-plist lookups
to do dynamics dispatch. I can't imagine how to work that into a strong type
system so a compiler written in Spad might be a challenge.

Grab a copy of Axiom and try to move some of the code to Spad. I'd
recommend starting with eliminating any $Lisp calls in the algebra. That
will move the algebra away from the underlying Lisp. It will also bring a
lot of issues into focus. A non-lisp-based Spad cannot have $Lisp calls
so each would have to be replaced with a Spad implementation.

On the other hand, my current effort involves proving Axiom correct. That
should (in theory) eliminate whole classes of errors. This is at the expense
of proving new code correct which tends to get a negative reaction from
developers. The upside is that "underneath Spad errors" should not occur.

Proven code certainly moves away from "lots of (non-mainstream) stuff
that's not really about the mathematics". On the other hand, it does make
the mathematics hill-climb steeper. Unless you're up to speed on Heyting
and Intuitionistic Logic, writing proven code is going to ruin your
weekends,
based on my current weekend experience :-)

Axiom is fundamentally a research platform in the area of computational
mathematics. I expect the user base to remain rather small, especially as
it gets closer to a rigorous mathematical base.

Tim


On Fri, Nov 3, 2017 at 2:27 PM, Martin Baker <ax87438@martinb.com> wrote:

> On 02/11/17 21:10, Tim Daly wrote:
>
>> Another thought... While people don't seem to like lisp as a platform
>> it does have major advantages. I usually find myself using the lisp
>> debugging facilities (trace, break, and REPL evaluation) to find
>> out what failed and where.
>>
>> If you go from Spad to executable code you lose all of that.
>>
>
> Tim,
>
> This is one of the problems, in my view, in that Lisp shows through
> underneath SPAD. That is debugging, error messages, outputs, etc. are often
> formatted as Lisp or require Lisp knowledge. I think this is particularly
> important for potential new users. SPAD has a steep enough learning curve
> on its own without needing to learn Lisp. Could it be things like this that
> prevent new user take up and explain the limited amount of discussion here?
>
> What I would like would be a clean language for people interested in
> mathematics without all the baggage of having to learn lots of
> (non-mainstream) computer stuff that's not really about the mathematics.
>
> Martin B
>

\start
Date: Sat, 4 Nov 2017 08:38:34 +0000
From: Martin Baker <ax87438@martinb.com>
To: Tim Daly <axiomcas@gmail.com>, axiom-dev <axiom-developer@nongnu.org>
Subject: Re: [Axiom-developer] Catching up on internals

On 04/11/17 00:42, Tim Daly wrote:
> On the other hand, my current effort involves proving Axiom correct. That
> should (in theory) eliminate whole classes of errors. This is at the expense
> of proving new code correct which tends to get a negative reaction from
> developers.

Tim,

I know little about proving code correct (though it looks like an 
interesting topic) so I'm certainly not doubting anything you say. Its 
just that (in my ignorance) I would have thought it would have been 
easier to prove high level code correct than low level code and 
therefore, for this reason,  better to move boot code to SPAD than Lisp?

By 'high level code' I mean code with meaningful static types and 
semantics closer to mathematical structures.

Martin B

\start
Date: Sat, 4 Nov 2017 12:18:13 -0400
From: Tim Daly <axiomcas@gmail.com>
To: Martin Baker <ax87438@martinb.com>
Subject: Re: [Axiom-developer] Catching up on internals

You're correct. My primary focus is on Spad code.

In a logic setting there are things called Typeclasses which are roughly
equivalent to Axiom Categories. Typeclasses have 3 parts:

   signatures    -- just like Axiom
   carriers        -- Axiom's Domain representation
   propositions -- formal properties

The fact that Axiom puts carriers in the domain allows us to have multiple
instances with the same signature set (e.g. Sparse vs Dense polynomials)

The fact that Axiom lacks propsitions causes us to invent a method of
declaring properties (e.g. commutative("*") ). This was fine for the 1970s
but mathematics has gotten much more precise and mechanical about
reasoning with such properties (e.g Coq, Agda, Isabelle, etc)

Mathematics has improved but Computer Algebra is still stuck in the
ad-hoc, informal rewrite semantics. It is time to use these research
results to improve Computer Algebra. Axiom has an excellent structure
based on Group theory which makes this feasible.

The Curry-Howard isomorphism is that propositions are types. That means
that propositions are part of the type declarations that should be in Axiom.
So instead of declaring 'commutative' we add the proposition stating the
commutative property to the appropriate Category.

Given a domain, e.g. NNI, we should be able to collect all of the
propositions
it inherits from the Category chain and use them to prove properties of the
algorithms in the NNI domain, such as GCD(x,y) = GCD(y,x). Domain
specific properties can be added at the Domain level.

So step 1 is to decorate the categories with propositions. Which means that
step 0 is to be able to encode and distribute propostions. Which means that
step -1 is to figure out how to parse, represent, and manipulate
propostions.
step -2 is to see what has been done before in this area.
step -3 is to create a survey article... which is what I've been working on
and hope to publish before the end of this semester.

Prior efforts seems to be mostly about CA and Proof systems running
in parallel and communicating in order to provide user-level proofs.
I'm trying to unify the two areas of mathematics into a single,
consistent system where system level proofs provide trusted results.

That said, the work still needs to be grounded with lisp-level proofs
since Axiom relies heavily on lisp-level primitives like List types.

I've proven one of the lisp functions so far (using ACL2). I'm adding
type signatures to the lisp code and rewriting functions to be strongly
typed (and more in line with a functional programming style).

At the moment, during build Axiom calls ACL2 for the lisp proofs and
Coq for the Spad proofs (the first of which is still under construction).

Carnegie Mellon University has been exceptionally generous in giving
me access to logic courses (quite a few in the CS department these days).
I get to ask questions of professors who have pioneered logic research.

Tim

On Sat, Nov 4, 2017 at 4:38 AM, Martin Baker <ax87438@martinb.com> wrote:

> On 04/11/17 00:42, Tim Daly wrote:
>
>> On the other hand, my current effort involves proving Axiom correct. That
>> should (in theory) eliminate whole classes of errors. This is at the
>> expense
>> of proving new code correct which tends to get a negative reaction from
>> developers.
>>
>
> Tim,
>
> I know little about proving code correct (though it looks like an
> interesting topic) so I'm certainly not doubting anything you say. Its just
> that (in my ignorance) I would have thought it would have been easier to
> prove high level code correct than low level code and therefore, for this
> reason,  better to move boot code to SPAD than Lisp?
>
> By 'high level code' I mean code with meaningful static types and
> semantics closer to mathematical structures.
>
> Martin B

\start
Date: Sat, 4 Nov 2017 18:02:28 +0000
From: Martin Baker <ax87438@martinb.com>
To: Tim Daly <axiomcas@gmail.com>, axiom-dev <axiom-developer@nongnu.org>
Subject: Re: [Axiom-developer] Catching up on internals

On 04/11/17 16:18, Tim Daly wrote:
> You're correct. My primary focus is on Spad code.
> ....

Tim,

Thanks for the explanation, interesting stuff, I'll be keen to read any 
progress reports if you get time to write them.

Thanks, Martin B

\start
Date: Tue, 7 Nov 2017 15:34:12 +0000
From: Martin Baker <ax87438@martinb.com>
To: Tim Daly <axiomcas@gmail.com>, axiom-dev <axiom-developer@nongnu.org>
Subject: Re: [Axiom-developer] Catching up on internals

On 04/11/17 00:42, Tim Daly wrote:
> How would you model handling errors in Spad?
> 
> I do think that there might be an interesting research question of how to
> handle classes of errors in computational mathematics. I had proposed
> using Provisos to handle side-conditions on formulas. Hoon Hong and
> Chris Brown have done a lot of work on QEPCAD for handling these.
> Manuel Bronstein and I had long discussions about a SUCHTHAT domain
> for encapsulating Provisos but little code resulted as the QEPCAD work
> was still in the future at the time.

Tim,

Since you asked this question I've been thinking about it (although I 
don't claim any expert knowledge).

It seems to me that there are at least 2 types of errors:
1) An error where the programmer just does something wrong.
2) An error where a partial function is called with an invalid value.

If the program is proved correct then I assume type 1 can't happen so we 
are mainly concerned with type 2 errors.

I have been looking at a programming language called 'Idris'. This 
language classifies each function as being either 'total' or 'partial', 
if it is partial then perhaps we can say something about which inputs 
are invalid.

Of course the compiler can't always determine that a function is total 
(because of the halting problem). However, for most simple functions 
(without recursion, dependent types, etc.) it is possible (at least it 
is in 'Idris') and perhaps the other functions could be classified manually.

Of course any function could be made 'total' by returning Maybe % or 
Union(%,"Fail") but that just pushes the problem upto the next level. 
The advantage of the above ideas is that the error might be explained to 
the user in much more appropriate detail, for example:
"function x called with value y which caused division by 0"
Also it could avoid lots of error handling boilerplate code.

Martin B

\start
Date: Tue, 7 Nov 2017 14:15:18 -0700
From: powerline <powerline332@gmx.us>
To: axiom-math@nongnu.org, axiom-developer@nongnu.org
Subject: [Axiom-developer] both mailing lists please

Hi, I was hoping to join the "math" users and "developer" mailing
lists... I am a newbie in using Axiom but am familiar somewhat with Lisp
and other CAS.

Thanks!

\start
Date: Wed, 8 Nov 2017 08:13:00 -0500
From: Tim Daly <axiomcas@gmail.com>
To: Martin Baker <ax87438@martinb.com>
Subject: Re: [Axiom-developer] Catching up on internals

Partial function checking happens in ML-fathered languages also. It
complains
when I fail to fill out a pattern match with all the cases, for example.

Proving partial functions implies a set of provisos (checks on the input).
These checks could be inserted as an 'assert' on the calling arguments
automatically. In addition, or as an alternative in a closed system, you
could prove that every caller respects the preconditions and will not ever
make a call with an invalid argument.

This is problematic in cases where the user chooses the input rather
than calls between internal functions. In that case, adding 'assert'
statements would provide a place to insert your user-level error message.

Tim


On Tue, Nov 7, 2017 at 10:34 AM, Martin Baker <ax87438@martinb.com> wrote:

> On 04/11/17 00:42, Tim Daly wrote:
>
>> How would you model handling errors in Spad?
>>
>> I do think that there might be an interesting research question of how to
>> handle classes of errors in computational mathematics. I had proposed
>> using Provisos to handle side-conditions on formulas. Hoon Hong and
>> Chris Brown have done a lot of work on QEPCAD for handling these.
>> Manuel Bronstein and I had long discussions about a SUCHTHAT domain
>> for encapsulating Provisos but little code resulted as the QEPCAD work
>> was still in the future at the time.
>>
>
> Tim,
>
> Since you asked this question I've been thinking about it (although I
> don't claim any expert knowledge).
>
> It seems to me that there are at least 2 types of errors:
> 1) An error where the programmer just does something wrong.
> 2) An error where a partial function is called with an invalid value.
>
> If the program is proved correct then I assume type 1 can't happen so we
> are mainly concerned with type 2 errors.
>
> I have been looking at a programming language called 'Idris'. This
> language classifies each function as being either 'total' or 'partial', if
> it is partial then perhaps we can say something about which inputs are
> invalid.
>
> Of course the compiler can't always determine that a function is total
> (because of the halting problem). However, for most simple functions
> (without recursion, dependent types, etc.) it is possible (at least it is
> in 'Idris') and perhaps the other functions could be classified manually.
>
> Of course any function could be made 'total' by returning Maybe % or
> Union(%,"Fail") but that just pushes the problem upto the next level. The
> advantage of the above ideas is that the error might be explained to the
> user in much more appropriate detail, for example:
> "function x called with value y which caused division by 0"
> Also it could avoid lots of error handling boilerplate code.
>
> Martin B

\start
Date: Thu, 16 Nov 2017 08:06:37 -0500
From: Tim Daly <axiomcas@gmail.com>
To: axiom-dev <axiom-developer@nongnu.org>, Tim Daly <axiomcas@gmail.com>, 
	Tim Daly <daly@axiom-developer.org>, rxg@cs.ubc.ca
Subject: [Axiom-developer] Literate programs

Ron,

As I mentioned, code dies when the authors stop touching it. This is
especially so with interns and students. Github is a graveyard of code
for exactly that reason. Even important Phd code gets thrown away once
the thesis is done. Literate programming is an attempt to overcome this.
This is my pain-less way of doing it.Inflict it on your students.

In general, I write code in an Emacs buffer and run a shell in another
buffer.
I run a pdf browser in another window. As I work (usually every 10 lines or
so of input) I run a little make command that latex's my file and compiles
my code so I catch mistakes early. This method of programming strongly
encourages writing explanations in latex as you code.


Knuth defined a file format Foo. The file contained both code and
explanation.
     weave Foo >foo.tex     generates a tex file for processing
     tangle Foo >foo.code   generates a code file for compiling



The idea of weaving in order to generate tex seems pointless.
In my scheme there is no longer a need for Knuth's weave program
because the file is already latex code. The only required code is a
simple tangle program.

I've defined 2 latex macros (see tangle.lisp for details)

   \begin{chunk}{name} ... \end{chunk}   delimits a named code block

   \getchunk{name}                              requests a code block Foo
expansion

As per Knuth, you extract code from your latex file using tangle.
The tangle program walks the Foo.tex file. Every chunk is put into a hash
table under the given name (multiple name uses are concatenated into one
hash block).

The tangle program, when it finds a "getchunk" will output the named
hash block.

So to create a literate program you write standard latex and surround your
code blocks with \begin{chunk}{name} ... \end{chunk}

To extract that code block you write

    tangle Foo.tex name >name.code

The default name is "*". You can name any (or all) blocks "*" and then

   tangle Foo.tex >the.code

I tend to write a lot of named blocks and then have a single final block
named "*" that consists of

\begin{chunk}{*}
\getchunk{block1}
...
\getchunk{blockn}
\end{chunk}

The tangle program, when asked for "*" will then inline all the named code
blocks on output.

I've attached both lisp and C versions of the tangle command. To use C:
   gcc -o mytangle tanglec.c
   ./mytangle test.tex                -- output the default block "*"
   ./mytangle test.tex foo           -- output the block named "foo"
   pdflatex test.tex                    -- latex the file (pdf browser will
update)

Oh, by the way, you might already have a binary named 'tangle' on your
system. This is NOT the tangle you're looking for. Use the attached code.

(Aside: it would be a trivial but clever change to use latex to write the
code file immediately during the latex step using \write. Then you don't
need tangle at all. It all works by 'magic'...)

Tim

--089e082454e464459f055e194a73
Content-Type: application/octet-stream; name="tangle.lisp"
Content-Disposition: attachment; filename="tangle.lisp"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_ja2fpnvw0

OyAgMCBBVVRIT1IgYW5kIExJQ0VOU0UKOyAgMSBBQlNUUkFDVAo7ICAyIFRIRSBMQVRFWCBTVVBQ
T1JUIENPREUKOyAgMyBHTE9CQUxTCjsgIDQgVEhFIFRBTkdMRSBDT01NQU5ECjsgIDUgVEhFIFRB
TkdMRSBGVU5DVElPTgo7ICA2IEdDTC1SRUFELUZJTEUgKGFrYSByZWFkLXNlcXVlbmNlKQo7ICA3
IEdDTC1IQVNIQ0hVTktTCjsgIDggR0NMLUVYUEFORAo7ICA5IElTQ0hVTkstTEFURVgKOyAxMCBJ
U0NIVU5LLU5PV0VCCjsgMTEgQUxMQ0hVTktTCgoKOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Cjs7OyAwIEFVVEhP
UiBhbmQgTElDRU5TRQoKOzs7IFRpbW90aHkgRGFseSAoZGFseUBheGlvbS1kZXZlbG9wZXIub3Jn
KSAKOzs7IExpY2Vuc2U6IFB1YmxpYyBEb21haW4KCjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Owo7OzsgMSBBQlNU
UkFDVAoKOzs7IFRoaXMgcHJvZ3JhbSB3aWxsIGV4dHJhY3QgdGhlIHNvdXJjZSBjb2RlIGZyb20g
YSBsaXRlcmF0ZSBmaWxlCgo7OzsgQSBsaXRlcmF0ZSBsaXNwIGZpbGUgY29udGFpbnMgYSBtaXh0
dXJlIG9mIGxhdGV4IGFuZCBsaXNwIHNvdXJjZXMgY29kZS4KOzs7IFRoZSBmaWxlIGlzIGludGVu
ZGVkIHRvIGJlIGluIG9uZSBvZiB0d28gZm9ybWF0cywgZWl0aGVyIGluIGxhdGV4Cjs7OyBmb3Jt
YXQgb3IsIGZvciBsZWdhY3kgcmVhc29ucywgaW4gbm93ZWIgZm9ybWF0LgoKOzs7IExhdGV4IGZv
cm1hdCBmaWxlcyBkZWZpbmVzIGEgbmV3ZW52aXJvbm1lbnQgc28gdGhhdCBjb2RlIGNodW5rcwo7
OzsgY2FuIGJlIGRlbGltaXRlZCBieSBcYmVnaW57Y2h1bmt9e25hbWV9IC4uLi4gXGVuZHtjaHVu
a30gYmxvY2tzCjs7OyBUaGlzIGlzIHN1cHBvcnRlZCBieSB0aGUgZm9sbG93aW5nIGxhdGV4IGNv
ZGUuCgo7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsKOzs7IDIgVEhFIExBVEVYIFNVUFBPUlQgQ09ERQoKOzs7IFRo
ZSB2ZXJiYXRpbSBwYWNrYWdlIHF1b3RlcyBldmVyeXRoaW5nIHdpdGhpbiBpdHMgZ3Jhc3AgYW5k
IGlzIHVzZWQgdG8KOzs7IGhpZGUgYW5kIHF1b3RlIHRoZSBzb3VyY2UgY29kZSBkdXJpbmcgbGF0
ZXggZm9ybWF0dGluZy4gVGhlIHZlcmJhdGltCjs7OyBlbnZpcm9ubWVudCBpcyBidWlsdCBpbiBi
dXQgdGhlIHBhY2thZ2UgZm9ybSBsZXRzIHVzIHVzZSBpdCBpbiBvdXIKOzs7IGNodW5rIGVudmly
b25tZW50IGFuZCBpdCBsZXRzIHVzIGNoYW5nZSB0aGUgZm9udC4KOzs7Cjs7OyBcdXNlcGFja2Fn
ZXt2ZXJiYXRpbX0KOzs7IAo7OzsgTWFrZSB0aGUgdmVyYmF0aW0gZm9udCBzbWFsbGVyCjs7OyBO
b3RlIHRoYXQgd2UgaGF2ZSB0byB0ZW1wb3JhcmlseSBjaGFuZ2UgdGhlICdAJyB0byBiZSBqdXN0
IGEgY2hhcmFjdGVyCjs7OyBiZWNhdXNlIHRoZSBcdmVyYmF0aW1AZm9udCBuYW1lIHVzZXMgaXQg
YXMgYSBjaGFyYWN0ZXIKOzs7Cjs7OyBcY2hhcmRlZlxhdGNvZGU9XGNhdGNvZGVgXEAKOzs7IFxj
YXRjb2RlYFxAPTExCjs7OyBccmVuZXdjb21tYW5ke1x2ZXJiYXRpbUBmb250fXtcdHRmYW1pbHlc
c21hbGx9Cjs7OyBcY2F0Y29kZWBcQD1cYXRjb2RlCgo7OzsgVGhpcyBkZWNsYXJlcyBhIG5ldyBl
bnZpcm9ubWVudCBuYW1lZCBgYGNodW5rJycgd2hpY2ggaGFzIG9uZQo7OzsgYXJndW1lbnQgdGhh
dCBpcyB0aGUgbmFtZSBvZiB0aGUgY2h1bmsuIEFsbCBjb2RlIG5lZWRzIHRvIGxpdmUKOzs7IGJl
dHdlZW4gdGhlIFxiZWdpbntjaHVua317bmFtZX0gYW5kIHRoZSBcZW5ke2NodW5rfQo7OzsgVGhl
IGBgbmFtZScnIGlzIHVzZWQgdG8gZGVmaW5lIHRoZSBjaHVuay4KOzs7IFJldXNlIG9mIHRoZSBz
YW1lIGNodW5rIG5hbWUgbGF0ZXIgY29uY2F0ZW5hdGVzIHRoZSBjaHVua3MKCjs7OyBGb3IgdGhv
c2Ugb2YgeW91IHdobyBjYW4ndCByZWFkIGxhdGV4IHRoaXMgc2F5czoKOzs7IE1ha2UgYSBuZXcg
ZW52aXJvbm1lbnQgbmFtZWQgY2h1bmsgd2l0aCBvbmUgYXJndW1lbnQKOzs7IFRoZSBmaXJzdCBi
bG9jayBpcyB0aGUgY29kZSBmb3IgdGhlIFxiZWdpbntjaHVua317bmFtZX0KOzs7IFRoZSBzZWNv
bmQgYmxvY2sgaXMgdGhlIGNvZGUgZm9yIHRoZSBcZW5ke2NodW5rfQo7OzsgVGhlICUgaXMgdGhl
IGxhdGV4IGNvbW1lbnQgY2hhcmFjdGVyCgo7OzsgV2UgaGF2ZSB0d28gYWx0ZXJuYXRlIG1hcmtl
cnMsIGEgbGlnaHR3ZWlnaHQgb25lIHVzaW5nIGRhc2hlcwo7OzsgYW5kIGEgaGVhdnl3ZWlnaHQg
b25lIHVzaW5nIHRoZSBcYmVnaW4gYW5kIFxlbmQgc3ludGF4Cjs7OyBZb3UgY2FuIGNob29zZSBl
aXRoZXIgb25lIGJ5IGNoYW5naW5nIHRoZSBjb21tZW50IGNoYXIgaW4gY29sdW1uIDEKIAo7Ozsg
XG5ld2Vudmlyb25tZW50e2NodW5rfVsxXXslICAgd2UgbmVlZCB0aGUgY2h1bmtuYW1lIGFzIGFu
IGFyZ3VtZW50Cjs7OyB7XCB9XG5ld2xpbmVcbm9pbmRlbnQlICAgICAgICAgICAgICAgICAgICBt
YWtlIHN1cmUgd2UgYXJlIGluIGNvbHVtbiAxCjs7OyAle1xzbWFsbCAkXGJhY2tzbGFzaHt9JGJl
Z2luXHtjaHVua1x9XHt7XGJmICMxfVx9fSUgYWx0ZXJuYXRlIGJlZ2luIG1hcmsKOzs7IFxoYm94
e1xoc2tpcCAyLjBjbX17XGJmIC0tLSAjMSAtLS19JSAgICAgIG1hcmsgdGhlIGJlZ2lubmluZwo7
OzsgXHZlcmJhdGltfSUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F5IGV4YWN0bHkg
d2hhdCB3ZSBzZWUKOzs7IHtcZW5kdmVyYmF0aW0lICAgICAgICAgICAgICAgICAgICAgICAgICAg
IHByb2Nlc3MgXGVuZHtjaHVua30KOzs7IFxwYXJ7fSUgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgIHdlIGFkZCBhIG5ld2xpbmUKOzs7IFxub2luZGVudHt9JSAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgIHN0YXJ0IGluIGNvbHVtbiAxCjs7OyBcaGJveHtcaHNraXAgMi4wY219
e1xiZiAtLS0tLS0tLS0tfSUgICAgICBtYXJrIHRoZSBlbmQKOzs7ICUkXGJhY2tzbGFzaHt9JGVu
ZFx7Y2h1bmtcfSUgICAgICAgICAgICAgIGFsdGVybmF0ZSBlbmQgbWFyayAoY29tbWVudGVkKQo7
OzsgXHBhciUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIGEgbmV3bGlu
ZQo7OzsgXG5vcm1hbHNpemVcbm9pbmRlbnR9JSAgICAgICAgICAgICAgICAgICAgYW5kIHJldHVy
biB0byB0aGUgZG9jdW1lbnQKCjs7OyBUaGlzIGRlY2xhcmVzIHRoZSBwbGFjZSB3aGVyZSB3ZSB3
YW50IHRvIGV4cGFuZCBhIGNodW5rCjs7OyBUZWNobmljYWxseSB3ZSBkb24ndCBuZWVkIHRoaXMg
YmVjYXVzZSBhIGdldGNodW5rIG11c3QgYWx3YXlzCjs7OyBiZSBwcm9wZXJseSBuZXN0ZWQgd2l0
aGluIGEgY2h1bmsgYW5kIHdpbGwgYmUgdmVyYmF0aW0uCgo7OzsgXHByb3ZpZGVjb21tYW5ke1xn
ZXRjaHVua31bMV17JQo7OzsgXG5vaW5kZW50JQo7Ozsge1xzbWFsbCAkXGJhY2tzbGFzaHt9JGJl
Z2luXHtjaHVua1x9XHt7XGJmICMxfVx9fX0lIG1hcmsgdGhlIHJlZmVyZW5jZQoKOzs7Ozs7Ozs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
Ozs7Ozs7Cjs7OyAzIEdMT0JBTFMKCjs7OyBUaGUgKmNodW5raGFzaCogdmFyaWFibGUgd2lsbCBo
b2xkIHRoZSBoYXNoIHRhYmxlIG9mIGNodW5rcy4KOzs7Cjs7OyBFdmVyeSB0aW1lIHdlIGZpbmQg
YSBcYmVnaW57Y2h1bmt9e25hbWV9IC4uLiBcZW5ke2NodW5rfSB3ZSBsb29rCjs7OyBpbiB0aGlz
IGhhc2ggdGFibGUuIElmIHRoZSBgYG5hbWUnJyBpcyBub3QgZm91bmQgd2UgYWRkIGl0Lgo7Ozsg
SWYgdGhlIG5hbWUgaXMgZm91bmQsIHdlIGNvbmNhdGVudGF0ZSBpdCB0byB0aGUgZXhpc3Rpbmcg
Y2h1bmsuCgooZGVmdmFyICpjaHVua2hhc2gqIG5pbCAidGhpcyBoYXNoIHRhYmxlIGNvbnRhaW5z
IHRoZSBjaHVua3MgZm91bmQiKQoKOzs7IFRoaXMgc2hvd3MgY3JpdGljYWwgaW5mb3JtYXRpb24g
Zm9yIGRlYnVnZ2luZyBwdXJwb3NlcwooZGVmdmFyICpjaHVua25vaXNlKiBuaWwgInR1cm4gdGhp
cyBvbiB0byBkZWJ1ZyBpbnRlcm5hbHMiKQoKCjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Owo7OzsgNCBUSEUgVEFO
R0xFIENPTU1BTkQKCjs7Owo7OzsgVGhlIHRhbmdsZSBjb21tYW5kIGRvZXMgYWxsIG9mIHRoZSB3
b3JrIG9mIGV4dHJhY3RpbmcgY29kZS4KOzs7IEZvciBsZWdhY3kgcmVhc29ucyB3ZSBzdXBwb3J0
IDIgc3ludGF4IGZvcm1zLCBsYXRleCBhbmQgbm93ZWIKOzs7Cjs7OyBJbiBsYXRleCBmb3JtIHRo
ZSBjb2RlIGJsb2NrcyBhcmUgZGVsaW1pdGVkIGJ5Cjs7OyAgICAgXGJlZ2lue2NodW5rfXtuYW1l
fQo7OzsgICAgIC4uLiAoY29kZSBmb3IgbmFtZSkuLi4KOzs7ICAgICBcZW5ke2NodW5rfQo7OzsK
Ozs7IGFuZCByZWZlcmVuY2VkIGJ5IFxnZXRjaHVua3tuYW1lfSB3aGljaCBnZXRzIHJlcGxhY2Vk
IGJ5IHRoZSBjb2RlCgo7OzsgSW4gbm93ZWIgZm9ybSB0aGUgY29kZSBibG9ja3MgYXJlIGRlbGlt
aXRlZCBieQo7OzsgICAgIDw8bmFtZT4+PQo7OzsgICAgIC4uLiAoY29kZSBmb3IgbmFtZSkuLi4K
Ozs7ICAgICBACjs7Owo7OzsgYW5kIHJlZmVyZW5jZWQgYnkgPDxuYW1lPj4gd2hpY2ggZ2V0cyBy
ZXBsYWNlZCBieSB0aGUgY29kZQoKOzs7IFRoZXJlIGFyZSBzZXZlcmFsIHdheXMgdG8gaW52b2tl
IHRoZSB0YW5nbGUgZnVuY3Rpb24uIAo7OzsKOzs7IFRoZSBmaXJzdCBhcmd1bWVudCBpcyBhbHdh
eXMgdGhlIGZpbGUgZnJvbSB3aGljaCB0byBleHRyYWN0IGNvZGUKOzs7Cjs7OyBUaGUgc2Vjb25k
IGFyZ3VtZW50IGlzIHRoZSBuYW1lIG9mIHRoZSBjaHVuayB0byBleHRyYWN0Cjs7OyAgICBJZiB0
aGUgbmFtZSBzdGFydHMgd2l0aCA8IHRoZW4gd2UgYXNzdW1lIG5vd2ViIGZvcm1hdCBhcyBpbjoK
Ozs7ICAgICAgICAodGFuZ2xlICJjbHdlYi5wYW1waGxldCIgIjw8bmFtZT4+IikgIDw9PSBub3dl
YiBzeW50YXgKOzs7ICAgIE90aGVyd2lzZSB3ZSBhc3N1bWUgbGF0ZXggZm9ybWF0IGFzIGluOgo7
OzsgICAgICAgICh0YW5nbGUgImNsd2ViLnBhbXBobGV0ICJuYW1lIikgICAgICAgPD09IGxhdGV4
IHN5bnRheCAoZGVmYXVsdCkKOzs7Cjs7OyBUaGUgc3RhbmRhcmQgbm93ZWIgY2h1bmsgbmFtZSBp
cyBgYConJyBidXQgYW55IG5hbWUgY2FuIGJlIHVzZWQuCjs7Owo7OzsgVGhlIHRoaXJkIGFydW1l
bnQgaXMgdGhlIG5hbWUgb2YgYW4gb3V0cHV0IGZpbGU6Cjs7OyAgKHRhbmdsZSAiY2x3ZWIucGFt
cGhsZXQiICJjbHdlYi5jaHVuayIgImNsd2ViLnNwYWRmaWxlIikKCgoKOzs7Ozs7Ozs7Ozs7Ozs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
Cjs7OyA1IFRIRSBUQU5HTEUgRlVOQ1RJT04KCjs7OyBUaGlzIHJvdXRpbmUgbG9va3MgYXQgdGhl
IGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgY2h1bmsgbmFtZS4KOzs7IElmIGl0IGlzIGEgJDwkIGNo
YXJhY3RlciB0aGVuIHdlIGFzc3VtZSBub3dlYiBzeW50YXggb3RoZXJ3aXNlCjs7OyB3ZSBhc3N1
bWUgbGF0ZXggc3ludGF4Lgo7OzsKOzs7IFdlIGluaXRpYWxpemUgdGhlIGNodW5rIGhhc2h0YWJs
ZQo7OzsgdGhlbiByZWFkIHRoZSBmaWxlIGFuZCBzdG9yZSBlYWNoIGNodW5rCjs7OyB0aGVuIHdl
IHJlY3Vyc2l2ZWx5IGV4cGFuZCB0aGUgYGB0b3BjaHVuaycnIHRvIHRoZSBvdXRwdXQgc3RyZWFt
CgooZGVmdW4gdGFuZ2xlIChmaWxlbmFtZSB0b3BjaHVuayAmb3B0aW9uYWwgZmlsZSkKICJFeHRy
YWN0IHRoZSBzb3VyY2UgY29kZSBmcm9tIGEgcGFtcGhsZXQgZmlsZSIKIChsZXQgKChub3dlYj8g
KGNoYXI9IChzY2hhciB0b3BjaHVuayAwKSAjXDwpKSkKICAoc2V0cSAqY2h1bmtoYXNoKiAobWFr
ZS1oYXNoLXRhYmxlIDp0ZXN0ICMnZXF1YWwpKQogICh3aGVuICpjaHVua25vaXNlKiAoZm9ybWF0
IHQgIlBBU1MgMX4lIikpCiAgKGdjbC1oYXNoY2h1bmtzIChnY2wtcmVhZC1maWxlIGZpbGVuYW1l
KSBub3dlYj8pCiAgKHdoZW4gKmNodW5rbm9pc2UqIChmb3JtYXQgdCAiUEFTUyAyfiUiKSkKICAo
aWYgKGFuZCBmaWxlIChzdHJpbmdwIGZpbGUpKQogICAod2l0aC1vcGVuLWZpbGUgKG91dCBmaWxl
IDpkaXJlY3Rpb24gOm91dHB1dCkKICAgICAoZ2NsLWV4cGFuZCB0b3BjaHVuayBub3dlYj8gb3V0
KSkKICAgKGdjbC1leHBhbmQgdG9wY2h1bmsgbm93ZWI/IHQpKSkKICAodmFsdWVzKSkKCgoKOzs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
Ozs7Ozs7Ozs7Ozs7Cjs7OyA2IEdDTC1SRUFELUZJTEUgKGFrYSByZWFkLXNlcXVlbmNlKQoKOzs7
IFRoaXMgd291bGQgYmUgcmVhZC1zZXF1ZW5jZSBpbiBhbnNpIGNvbW1vbiBsaXNwLiBIZXJlIHdl
IHJlYWQKOzs7IGEgbGluZSwgcHVzaCBpdCBvbnRvIGEgc3RhY2sgYW5kIHRoZW4gcmV2ZXJzZSB0
aGUgc3RhY2suIFRoZQo7OzsgbmV0IGVmZmVjdCBpcyBhIGxpc3Qgb2Ygc3RyaW5ncywgb25lIHBl
ciBsaW5lIG9mIHRoZSBmaWxlLgoKKGRlZnVuIGdjbC1yZWFkLWZpbGUgKHN0cmVhbW5hbWUpCiAi
SW1wbGVtZW50IHJlYWQtc2VxdWVuY2UgaW4gR0NMIgogKGxldCAocmVzdWx0KQogICh3aXRoLW9w
ZW4tZmlsZSAoc3RyZWFtIChvcGVuIHN0cmVhbW5hbWUpKQogICAoZG8gKGxpbmUgZW9mKQogICAg
ICAoKGVxIGxpbmUgJ2RvbmUpIChucmV2ZXJzZSByZXN1bHQpKQogICAgKG11bHRpcGxlLXZhbHVl
LXNldHEgKGxpbmUgZW9mKSAocmVhZC1saW5lIHN0cmVhbSBuaWwgJ2RvbmUpKSAKICAgICh1bmxl
c3MgKGVxIGxpbmUgJ2RvbmUpIChwdXNoIGxpbmUgcmVzdWx0KSkpKSkpCgoKCjs7Ozs7Ozs7Ozs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
Ozs7Owo7OzsgNyBHQ0wtSEFTSENIVU5LUwoKOzs7IGdjbC1oYXNoY2h1bmtzIGdhdGhlcnMgdGhl
IGNodW5rcyBhbmQgcHV0cyB0aGVtIGluIHRoZSBoYXNoIHRhYmxlCjs7Owo7OzsgaWYgd2UgZmlu
ZCB0aGUgY2h1bmsgc3ludGF4IGFuZCBpdCBpcyBhCjs7OyAgIGRlZmluZSA9PT4gcGFyc2UgdGhl
IGNodW5rbmFtZSBhbmQgc3RhcnQgZ2F0aGVyaW5nIGxpbmVzIG9udG8gYSBzdGFjawo7OzsgICBl
bmQgICAgPT0+IHB1c2ggdGhlIGNvbXBsZXRlZCBsaXN0IG9mIGxpbmVzIGludG8gYSBzdGFjayBv
ZiBjaHVua3MKOzs7ICAgICAgICAgICAgICBhbHJlYWR5IGluIHRoZSBoYXNoIHRhYmxlCjs7OyAg
IG90aGVyd2lzZSA9PT4gaWYgd2UgYXJlIGdhdGhlcmluZywgcHVzaCB0aGUgbGluZSBvbnRvIHRo
ZSBzdGFjawoKOzs7IGEgaGFzaCB0YWJsZSBlbnRyeSBpcyBhIGxpc3Qgb2YgbGlzdHMgc3VjaCBh
cwo7OzsgKCgiNiIgIjUiKSAoIjQiICIzIikgKCIyIiAiMSIpKQo7OzsgZWFjaCBvZiB0aGUgc3Vi
bGlzdHMgaXMgYSBzZXQgb2YgbGluZXMgaW4gcmV2ZXJzZSAoc3RhY2spIG9yZGVyCjs7OyBlYWNo
IHN1Ymxpc3QgaXMgYSBzaW5nbGUgY2h1bmsgb2YgbGluZXMuIAo7OzsgdGhlcmUgaXMgYSBuZXcg
c3VibGlzdCBmb3IgZWFjaCByZXVzZSBvZiB0aGUgc2FtZSBjaHVua25hbWUKCjs7OyBJZiB0aGUg
bm93ZWIgYXJndW1lbnQgaXMgbm9uLW5pbCB3ZSBhc3N1bWUgdGhhdCB3ZSBhcmUgcGFyc2luZwo7
OzsgdXNpbmcgdGhlIG5vd2ViIHN5bnRheC4gQSBuaWwgYXJndW1lbnQgaW1wbGllcyBsYXRleCBz
eW50YXguCgooZGVmdW4gZ2NsLWhhc2hjaHVua3MgKGxpbmVzIG5vd2ViKQogIkdhdGhlciBhbGwg
b2YgdGhlIGNodW5rcyBhbmQgcHV0IHRoZW0gaW50byBhIGhhc2ggdGFibGUiCiAobGV0ICh0eXBl
IG5hbWUgY2h1bmtuYW1lIG9sZGNodW5rcyBjaHVuayBnYXRoZXIpCiAgKGRvbGlzdCAobGluZSBs
aW5lcykKICAgKGlmIG5vd2ViCiAgICAobXVsdGlwbGUtdmFsdWUtc2V0cSAodHlwZSBuYW1lKSAo
aXNjaHVuay1ub3dlYiBsaW5lKSkKICAgIChtdWx0aXBsZS12YWx1ZS1zZXRxICh0eXBlIG5hbWUp
IChpc2NodW5rLWxhdGV4IGxpbmUpKSkKICAgKGNvbmQKICAgICgoZXEgdHlwZSAnZGVmaW5lKQog
ICAgICAod2hlbiAqY2h1bmtub2lzZSogKGZvcm1hdCB0ICJERUZJTkUgbmFtZT1+YX4lIiBuYW1l
KSkKICAgICAgKHNldHEgY2h1bmtuYW1lIG5hbWUpCiAgICAgIChzZXRxIGdhdGhlciB0KSkKICAg
ICgoZXEgdHlwZSAnZW5kKQogICAgICAod2hlbiAqY2h1bmtub2lzZSogCiAgICAgICAoZm9ybWF0
IHQgIkVORCBuYW1lPSB+YSBjaHVuaz1+c34lIiBjaHVua25hbWUgKHJldmVyc2UgY2h1bmspKSkK
ICAgICAgKHNldHEgb2xkY2h1bmtzIChnZXRoYXNoIGNodW5rbmFtZSAqY2h1bmtoYXNoKikpCiAg
ICAgIChzZXRmIChnZXRoYXNoIGNodW5rbmFtZSAqY2h1bmtoYXNoKikgKHB1c2ggY2h1bmsgb2xk
Y2h1bmtzKSkKICAgICAgKHNldHEgZ2F0aGVyIG5pbCkKICAgICAgKHNldHEgY2h1bmsgbmlsKSkK
ICAgIChnYXRoZXIgOzsgY29sbGVjdCBsaW5lcyBpbnRvIHRoZSBjaHVuayB3aGlsZSBnYXRoZXIg
aXMgdHJ1ZQogICAgICAocHVzaCBsaW5lIGNodW5rKSkpKSkpCgoKOzs7Ozs7Ozs7Ozs7Ozs7Ozs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Cjs7
OyA4IEdDTC1FWFBBTkQKCjs7OyBnY2wtZXhwYW5kIHdpbGwgcmVjdXJzaXZlbHkgZXhwYW5kIGNo
dW5rcyBpbiB0aGUgaGFzaCB0YWJsZQo7OzsgCjs7OyBsYXRleCBjaHVuayBuYW1lcyBhcmUganVz
dCB0aGUgY2h1bmtuYW1lIGl0c2VsZiBlLmcuIGNodW5rbmFtZQo7Ozsgbm93ZWIgY2h1bmsgbmFt
ZXMgaW5jbHVkZSB0aGUgZGVsaW1pdGVycywgZS5nOiA8PGNodW5rbmFtZT4+Cgo7OzsgYSBoYXNo
IHRhYmxlIGVudHJ5IGlzIGEgbGlzdCBvZiBsaXN0cyBzdWNoIGFzCjs7OyAoKCI2IiAiNSIpICgi
NCIgIjMiKSAoIjIiICIxIikpCjs7OyBzbyB0byBwcm9jZXNzIHRoZSBjaHVuayB3ZSByZXZlcnNl
IHRoZSBtYWluIGxpc3QgYW5kCjs7OyBmb3IgZWFjaCBzdWJsaXN0IHdlIHJldmVyc2UgdGhlIHN1
Ymxpc3QgYW5kIHByb2Nlc3MgdGhlIGxpbmVzCgo7OzsgaWYgYSBjaHVuayBuYW1lIHJlZmVyZW5j
ZSBpcyBlbmNvdW50ZXJlZCBpbiBhIGxpbmUgd2UgY2FsbCBleHBhbmQKOzs7IHJlY3Vyc2l2ZWx5
IHRvIGV4cGFuZCB0aGUgaW5uZXIgY2h1bmtuYW1lLgoKKGRlZnVuIGdjbC1leHBhbmQgKGNodW5r
IG5vd2ViPyBmaWxlKQogIlJlY3Vyc2l2ZWx5IGV4cGFuZCBhIGNodW5rIGludG8gdGhlIG91dHB1
dCBzdHJlYW0iCiAobGV0ICgoY2h1bmtsaXN0IChnZXRoYXNoIGNodW5rICpjaHVua2hhc2gqKSkg
dHlwZSBuYW1lKQogIChkb2xpc3QgKGNodW5rIChyZXZlcnNlIGNodW5rbGlzdCkpCiAgIChkb2xp
c3QgKGxpbmUgKHJldmVyc2UgY2h1bmspKQogICAgKGlmIG5vd2ViPwogICAgIChtdWx0aXBsZS12
YWx1ZS1zZXRxICh0eXBlIG5hbWUpIChpc2NodW5rLW5vd2ViIGxpbmUpKQogICAgIChtdWx0aXBs
ZS12YWx1ZS1zZXRxICh0eXBlIG5hbWUpIChpc2NodW5rLWxhdGV4IGxpbmUpKSkKICAgIChpZiAo
ZXEgdHlwZSAncmVmZXIpIAogICAgICAocHJvZ24KICAgICAgICh3aGVuICpjaHVua25vaXNlKiAo
Zm9ybWF0IHQgIlJFRkVSIG5hbWU9fmF+JSIgbmFtZSkpCiAgICAgICAoZ2NsLWV4cGFuZCBuYW1l
IG5vd2ViPyBmaWxlKSkKICAgICAgKGZvcm1hdCBmaWxlICJ+YX4lIiBsaW5lKSkpKSkpCgoKCjs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
Ozs7Ozs7Ozs7Ozs7Owo7OzsgOSBJU0NIVU5LLUxBVEVYCgo7OzsgVGhlcmUgaXMgYSBidWlsdC1p
biBhc3N1bXB0aW9uIChpbiB0aGUgaXNjaHVuay0qIGZ1bmN0aW9ucykKOzs7IHRoYXQgdGhlIGNo
dW5rcyBvY2N1ciBvbiBzZXBhcmF0ZSBsaW5lcyBhbmQgdGhhdCB0aGUgaW5kZW50YXRpb24KOzs7
IG9mIHRoZSBjaHVuayByZWZlcmVuY2UgaGFzIG5vIG1lYW5pbmcuCjs7Owo7OzsgaXNjaHVuay1s
YXRleCAgcmVjb2duaXplcyBjaHVuayBuYW1lcyBpbiBsYXRleCBjb252ZW50aW9uCjs7Owo7Ozsg
VGhlcmUgYXJlIDMgY2FzZXMgdG8gcmVjb2duaXplOgo7OzsgIFxiZWdpbntjaHVua317dGhlY2h1
bmtuYW1lfSAgPT0+ICdkZWZpbmUgdGhlY2h1bmtuYW1lCjs7OyAgXGVuZHtjaHVua30gICAgICAg
ICAgICAgICAgICA9PT4gJ2VuZCBuaWwKOzs7ICBcZ2V0Y2h1bmt7dGhlY2h1bmtuYW1lfSAgICAg
ID09PiAncmVmZXIgdGhlY2h1bmtuYW1lCgooZGVmdW4gaXNjaHVuay1sYXRleCAobGluZSkKICJG
aW5kIGNodW5rcyBkZWxpbWl0ZWQgYnkgbGF0ZXggc3ludGF4IgogKGxldCAoKG1hcmsgKHNlYXJj
aCAiY2h1bmsiIGxpbmUpKSAgICAgIDsgaXMgdGhpcyBhIGxpbmUgd2UgY2FyZSBhYm91dD8KICAg
ICAgIChwb2ludCAwKQogICAgICAgbmFtZSAKICAgICAgIChiZWdpbnN0cmluZyAiXFxiZWdpbntj
aHVua317IikgICA7IHRoaXMgaXMgdGhlIGRlZmluZSBtYXJrZXIgc3RyaW5nCiAgICAgICBiZWdp
bmxlbmd0aAogICAgICAgKGVuZHN0cmluZyAiXGVuZHtjaHVua30iKSAgICAgICAgIDsgdGhpcyBp
cyB0aGUgZW5kIG1hcmtlciBzdHJpbmcKICAgICAgIChyZWZlcnN0cmluZyAiXGdldGNodW5reyIp
ICAgICAgICA7IHRoaXMgaXMgdGhlIHJlZmVyIHN0cmluZwogICAgICAgcmVmZXJsZW5ndGgpCiAg
KHNldHEgYmVnaW5sZW5ndGggKGxlbmd0aCBiZWdpbnN0cmluZykpCiAgKHNldHEgcmVmZXJsZW5n
dGggKGxlbmd0aCByZWZlcnN0cmluZykpCiAgKHdoZW4gbWFyawogICAoY29uZAogICAgKChzZXRx
IG1hcmsgKHNlYXJjaCBiZWdpbnN0cmluZyBsaW5lKSkgOyByZWNvZ25pemUgZGVmaW5lCiAgICAg
IChzZXRxIHBvaW50IChwb3NpdGlvbiAjXH0gbGluZSA6c3RhcnQgKCsgbWFyayBiZWdpbmxlbmd0
aCkpKQogICAgICAoY29uZAogICAgICAgKChudWxsIHBvaW50KSAodmFsdWVzIG5pbCBuaWwpKQog
ICAgICAgKCg9IHBvaW50IDApICAodmFsdWVzIG5pbCBuaWwpKQogICAgICAgKHQKICAgICAgICAg
KHNldHEgbmFtZSAoc3Vic2VxIGxpbmUgKCsgbWFyayBiZWdpbmxlbmd0aCkgcG9pbnQpKSAKICAg
ICAgICAgOyhwcmludCAobGlzdCAnaXNjaHVuay1sYXRleCAnZGVmaW5lIG5hbWUpKQogICAgICAg
ICAodmFsdWVzICdkZWZpbmUgbmFtZSkpKSkKICAgICgoc2V0cSBtYXJrIChzZWFyY2ggZW5kc3Ry
aW5nIGxpbmUpKSAgICAgOyByZWNvZ25pemUgZW5kCiAgICAgICA7KHByaW50IChsaXN0ICdpc2No
dW5rLWxhdGV4ICdlbmQpKQogICAgICAgKHZhbHVlcyAnZW5kIG5pbCkpCiAgICAoKHNldHEgbWFy
ayAoc2VhcmNoIHJlZmVyc3RyaW5nIGxpbmUpKSAgICAgICAgIDsgcmVjb2duaXplIHJlZmVyZW5j
ZQogICAgICAoc2V0cSBwb2ludCAocG9zaXRpb24gI1x9IGxpbmUgOnN0YXJ0ICgrIG1hcmsgcmVm
ZXJsZW5ndGgpKSkKICAgICAgKGNvbmQKICAgICAgICgobnVsbCBwb2ludCkgKHZhbHVlcyBuaWwg
bmlsKSkKICAgICAgICgoPSBwb2ludCAwKSAgKHZhbHVlcyBuaWwgbmlsKSkKICAgICAgICh0CiAg
ICAgICAgIChzZXRxIG5hbWUgKHN1YnNlcSBsaW5lICgrIG1hcmsgcmVmZXJsZW5ndGgpIHBvaW50
KSkgCiAgICAgICAgIDsocHJpbnQgKGxpc3QgJ2lzY2h1bmstbGF0ZXggJ3JlZmVyIG5hbWUpKQog
ICAgICAgICAodmFsdWVzICdyZWZlciBuYW1lKSkpKQogICAgKHQgKHZhbHVlcyBuaWwgbmlsKSkp
KSkpCiAgCgoKOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Cjs7OyAxMCBJU0NIVU5LLU5PV0VCCgo7OzsgaXNjaHVu
ay1ub3dlYiByZWNvZ25pemVzIGNodW5rIG5hbWVzIHVzaW5nIHRoZSBub3dlYiBjb252ZW50aW9u
Cjs7Owo7OzsgVGhlcmUgYXJlIDMgY2FzZXMgdG8gcmVjb2duaXplOgo7OzsgIDw8dGhlY2h1bmtu
YW1lPj49ICA9PT4gJ2RlZmluZSB0aGVjaHVua25hbWUKOzs7ICBAICAgICAgICAgICAgICAgICAg
PT0+ICdlbmQgbmlsCjs7OyAgPDx0aGVjaHVua25hbWU+PiAgID09PiAncmVmZXIgdGhlY2h1bmtu
YW1lCgooZGVmdW4gaXNjaHVuay1ub3dlYiAobGluZSkKICJGaW5kIGNodW5rcyBkZWxpbWl0ZWQg
Ynkgbm93ZWIgc3ludGF4IgogKGxldCAoKGxlbiAobGVuZ3RoIGxpbmUpKSAobWFyayAocG9zaXRp
b24gI1w+IGxpbmUpKSAocG9pbnQgMCkpCiAgKGNvbmQKICAgKChhbmQgbWFyayAgICAgICAgICAg
ICAgICAgICAgOyByZWNvZ25pemUgZGVmaW5lCiAgICAgICAgICg+IGxlbiAoKyBtYXJrIDIpKQog
ICAgICAgICAoY2hhcj0gI1w8IChzY2hhciBsaW5lIDApKQogICAgICAgICAoY2hhcj0gI1w8IChz
Y2hhciBsaW5lIDEpKQogICAgICAgICAoY2hhcj0gI1w+IChzY2hhciBsaW5lICgrIG1hcmsgMSkp
KQogICAgICAgICAoY2hhcj0gI1w9IChzY2hhciBsaW5lICgrIG1hcmsgMikpKSkKICAgICA7KHBy
aW50IChsaXN0ICdkZWZpbmUgKHN1YnNlcSBsaW5lIDAgKCsgbWFyayAyKSkpKQogICAgICh2YWx1
ZXMgJ2RlZmluZSAoc3Vic2VxIGxpbmUgMCAoKyBtYXJrIDIpKSkpCiAgICgoYW5kIG1hcmsgICAg
ICAgICAgICAgICAgICAgIDsgcmVjb2duaXplIHJlZmVyZW5jZQogICAgICAgICAoPiBsZW4gKCsg
bWFyayAxKSkKICAgICAgICAgKGNoYXI9ICNcPiAoc2NoYXIgbGluZSAoKyBtYXJrIDEpKSkpCiAg
ICAgKHNldHEgcG9pbnQgKHBvc2l0aW9uICNcPCBsaW5lKSkKICAgICAoaWYKICAgICAgKGFuZCBw
b2ludAogICAgICAgICAgICg8IHBvaW50ICgtIG1hcmsgMikpCiAgICAgICAgICAgKGNoYXI9ICNc
PCAoc2NoYXIgbGluZSAoKyBwb2ludCAxKSkpKQogICAgICAgICh2YWx1ZXMgJ3JlZmVyIChzdWJz
ZXEgbGluZSBwb2ludCAoKyBtYXJrIDIpKSkKICAgICAgICAodmFsdWVzICdub2lzZSBuaWwpKSkK
ICAgICgoYW5kICg+IGxlbiAwKSAgICAgICAgICAgICAgICA7IGVuZCBjaHVuawogICAgICAgICAg
KGNoYXI9ICNcQCAoc2NoYXIgbGluZSAwKSkpCiAgICAgICh2YWx1ZXMgJ2VuZCBuaWwpKQogICAg
KHQgKHZhbHVlcyBuaWwgbmlsKSkpKSkKICAKCjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Owo7OzsgMTEgYWxsY2h1
bmtzCjs7OyAKOzs7IGFsbGNodW5rcyB3aWxsIG1ha2UgYSBzaW5nbGUgcGFzcyBvdmVyIGEgYm9v
ayBleHRyYWN0aW5nIGFueSBjaHVuawo7OzsgdGhhdCBmaXRzIHRoZSBQQVRURVJOIGZyb20gdGhl
IEZST01GSUxFIHRvIHRoZSBUT0RJUi4gVGhlIGNodW5rCjs7OyBmb3JtYXQgaXMgZWl0aGVyIG5v
d2ViIChpZiB0cnVlKSBvciBsYXRleCAoaWYgZmFsc2UpLgo7OzsKOzs7IGFsbGNodW5rcyB0YWtl
cyA0IGFyZ3VtZW50cywKOzs7IHRoZSBQQVRURVJOIChhIHN0cmluZyBsaWtlICIuaGVscD4+Igo7
OzsgdGhlIEZST01GSUxFIChhIHN0cmluZyBsaWtlICIvYXhpb20vYm9va3MvYm9va3ZvbDUucGFt
cGhsZXQiKQo7OzsgdGhlIFRPRElSIChhIHN0cmluZyBsaWtlICIvYXhpb20vbW50L3VidW50dS9k
b2Mvc3BhZGhlbHAiKQo7OzsgYW5kIGEgYm9vbGVhbiBOT1dFQj8gKHRydWUgaXMgbm93ZWIgZm9y
bWF0IGNodW5rcywgZmFsc2UgaXMgbGF0ZXggc3R5bGUpCjs7Owo7OzsgYSBjaHVuayBuYW1lIGlz
IGV4cGVjdGVkIHRvIGJlIG9mIHRoZSBmb3JtOgo7OzsgPDxGUk9NRklMRS5QQVRURVJOPj49Cjs7
OyB3aGljaCBtZWFucyB0aGF0IGEgY2h1bmsgbWF0Y2hpbmcgdGhlIHBhdHRlcm4gKGUuZy4gIi5p
bnB1dD4+IikgCjs7OyB3aWxsIGJlIGV4dHJhY3RlZCB0byB0aGUgZmlsZSBUT0RJUi9GUk9NRklM
RS5QQVRURVJOCjs7OyAKOzs7IFRoaXMgaXMgdXNlZCBmb3IgPDxmb28uaGVscD4+IGFuZCA8PGZv
by5pbnB1dD4+IGZpbGUgZXh0cmFjdGlvbi4KOzs7IGFsbGNodW5rcyBpcyB1c2VkIHRvIGV4dHJh
Y3QgaGVscCBmaWxlcyBhbmQgaW5wdXQgZmlsZXMgaW4gYSBzaW5nbGUKOzs7IHBhc3Mgb3ZlciB0
aGUgYm9va3MuIFNpbmNlIHRoZXJlIGFyZSBodW5kcmVkcyBvZiBpbnB1dCBmaWxlcyBhbmQKOzs7
IGhlbHAgZmlsZXMgdGhpcyBpcyBhIHNpZ25pZmljYW50IHNwZWVkdXAuCgooZGVmdW4gYWxsY2h1
bmtzIChwYXR0ZXJuIGZyb21maWxlIHRvZGlyIG5vd2ViPykKICAoc2V0cSAqY2h1bmtoYXNoKiAo
bWFrZS1oYXNoLXRhYmxlIDp0ZXN0ICMnZXF1YWwpKQogICh3aGVuICpjaHVua25vaXNlKiAoZm9y
bWF0IHQgIlBBU1MgMX4lIikpCiAgKGdjbC1oYXNoY2h1bmtzIChnY2wtcmVhZC1maWxlIGZyb21m
aWxlKSBub3dlYj8pCiAgKHdoZW4gKmNodW5rbm9pc2UqIChmb3JtYXQgdCAiUEFTUyAyfiUiKSkK
ICAobWFwaGFzaCAjJyhsYW1iZGEgKGtleSB2YWx1ZSkKICAgICAgICAgICAgICAoaWYgKHNlYXJj
aCBwYXR0ZXJuIGtleSkKICAgICAgICAgICAgICAgKGxldCAoKGZpbGVuYW1lIGtleSkgaGVscGZp
bGUpCiAgICAgICAgICAgICAgICAod2hlbiBub3dlYj8gKHNldHEgZmlsZW5hbWUgKHN1YnNlcSBr
ZXkgMiAoLSAobGVuZ3RoIGtleSkgMikpKSkKICAgICAgICAgICAgICAgIChzZXRxIGhlbHBmaWxl
IChjb25jYXRlbmF0ZSAnc3RyaW5nIHRvZGlyICIvIiBmaWxlbmFtZSkpCiAgICAgICAgICAgICAg
ICAod2l0aC1vcGVuLWZpbGUgKG91dCBoZWxwZmlsZSA6ZGlyZWN0aW9uIDpvdXRwdXQpCiAgICAg
ICAgICAgICAgICAgKGZvcm1hdCB0ICJleHRyYWN0aW5nIH5hfiUiIGhlbHBmaWxlKQogICAgICAg
ICAgICAgICAgIChnY2wtZXhwYW5kIGtleSBub3dlYj8gb3V0KSkpKSkKICAgICAgICpjaHVua2hh
c2gqKSkKCgoKCgo=
--089e082454e464459f055e194a73
Content-Type: text/x-csrc; charset="US-ASCII"; name="tanglec.c"
Content-Disposition: attachment; filename="tanglec.c"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_ja2fpzbw1

I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHVuaXN0ZC5o
PgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8c3lz
L21tYW4uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CgovLyBzZXQgdGhpcyB0byAzIGZvciBmdXJ0aGVy
IGluZm9ybWF0aW9uCiNkZWZpbmUgREVCVUcgMAoKLyogZm9yd2FyZCByZWZlcmVuY2UgZm9yIHRo
ZSBDIGNvbXBpbGVyICovCmludCBnZXRjaHVuayhjaGFyICpjaHVua25hbWUpOwoKLyogYSBtZW1v
cnkgbWFwcGVkIGJ1ZmZlciBjb3B5IG9mIHRoZSBmaWxlICovCmNoYXIgKmJ1ZmZlcjsKaW50IGJ1
ZnNpemU7CgovKiByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgbmV4dCBsaW5lICovCmludCBuZXh0
bGluZShpbnQgaSkgewogIGludCBqOwogIGlmIChpID49IGJ1ZnNpemUpIHJldHVybigtMSk7CiAg
Zm9yIChqPTA7ICgoaStqIDwgYnVmc2l6ZSkgJiYgKGJ1ZmZlcltpK2pdICE9ICdcbicpKTsgaisr
KTsKICByZXR1cm4oaik7Cn0KCi8qIG91dHB1dCB0aGUgbGluZSB3ZSBuZWVkICovCmludCBwcmlu
dGxpbmUoaW50IGksIGludCBsZW5ndGgpIHsKICBpbnQgajsKICBmb3IgKGo9MDsgajxsZW5ndGg7
IGorKykgeyBwdXRjaGFyKGJ1ZmZlcltpK2pdKTsgfQogIHByaW50ZigiXG4iKTsKICByZXR1cm4o
MCk7Cn0KCi8qIGhhbmRsZSBiZWdpbntjaHVua317Y2h1bmtuYW1lfSAgICAgICAgKi8KLyogaXMg
dGhpcyBjaHVuayBuYW1lIHdlIGFyZSBsb29raW5nIGZvcj8gJiYKICAgZG9lcyB0aGUgbGluZSBz
dGFydCB3aXRoIFxiZWdpbntjaHVua30/ICYmCiAgIGlzIHRoZSBuZXh0IGNoYXJhY3RlciBhIFx7
ICYmCiAgIGlzIHRoZSBsYXN0IGNoYXJhY3RlciBhZnRlciB0aGUgY2h1bmtuYW1lIGEgXH0KKi8K
aW50IGZvdW5kY2h1bmsoaW50IGksIGNoYXIgKmNodW5rbmFtZSkgewogIGlmICgoc3RybmNtcCgm
YnVmZmVyW2krMTRdLGNodW5rbmFtZSxzdHJsZW4oY2h1bmtuYW1lKSkgPT0gMCkgJiYKICAgICAg
KHN0cm5jbXAoJmJ1ZmZlcltpXSwiXFxiZWdpbntjaHVua30iLDEzKSA9PSAwKSAmJgogICAgICAo
YnVmZmVyW2krMTNdID09ICd7JykgJiYKICAgICAgKGJ1ZmZlcltpKzE0K3N0cmxlbihjaHVua25h
bWUpXSA9PSAnfScpKSB7CiAgICBpZiAoREVCVUc9PTMpIHsgcHJpbnRmKCJmb3VuZGNodW5rKCVz
KVxuIixjaHVua25hbWUpOyB9CiAgICByZXR1cm4oMSk7IAogIH0KICByZXR1cm4oMCk7Cn0KCi8q
IGhhbmRsZSBlbmR7Y2h1bmt9ICAgKi8KLyogaXMgaXQgcmVhbGx5IGFuIGVuZD8gKi8KaW50IGZv
dW5kRW5kKGludCBpLCBjaGFyKiBjaHVua25hbWUpIHsKICBpZiAoKGJ1ZmZlcltpXSA9PSAnXFwn
KSAmJiAKICAgICAgKHN0cm5jbXAoJmJ1ZmZlcltpKzFdLCJlbmR7Y2h1bmt9IiwxMCkgPT0gMCkp
IHsKICAgIGlmIChERUJVRz09MykgeyBwcmludGYoImZvdW5kRW5kKCVzKVxuIixjaHVua25hbWUp
OyB9CiAgICByZXR1cm4oMSk7IAogIH0KICByZXR1cm4oMCk7Cn0KCi8qIGhhbmRsZSBnZXRjaHVu
a3tjaHVua25hbWV9ICovCi8qIGlzIHRoaXMgbGluZSBhIGdldGNodW5rPyAgICAqLwppbnQgZm91
bmRHZXRjaHVuayhpbnQgaSwgaW50IGxpbmVsZW4pIHsKICBpbnQgbGVuOwogIGlmIChzdHJuY21w
KCZidWZmZXJbaV0sIlxcZ2V0Y2h1bmt7IiwxMCkgPT0gMCkgewogICAgZm9yKGxlbj0wOyAoKGxl
biA8IGxpbmVsZW4pICYmIChidWZmZXJbaStsZW5dICE9ICd9JykpOyBsZW4rKyk7CiAgICByZXR1
cm4obGVuLTEwKTsKICB9CiAgcmV0dXJuKDApOwp9CgovKiBTb21lYm9keSBkaWQgYSBnZXRjaHVu
ayBhbmQgd2UgbmVlZCBhIGNvcHkgb2YgdGhlIG5hbWUgKi8KLyogbWFsbG9jIHN0cmluZyBzdG9y
YWdlIGZvciBhIGNvcHkgb2YgdGhlIGdldGNodW5rIG5hbWUgICovCmNoYXIgKmdldENodW5rbmFt
ZShpbnQgaywgaW50IGdldGxlbikgewogIGNoYXIgKnJlc3VsdCA9IChjaGFyICopbWFsbG9jKGdl
dGxlbisxKTsKICBzdHJuY3B5KHJlc3VsdCwmYnVmZmVyW2srMTBdLGdldGxlbik7CiAgcmVzdWx0
W2dldGxlbl09J1wwJzsKICByZXR1cm4ocmVzdWx0KTsKfQogIAovKiBwcmludCBsaW5lcyBpbiB0
aGlzIGNodW5rLCBwb3NzaWJseSByZWN1cnNpbmcgaW50byBnZXRjaHVuayAqLwppbnQgcHJpbnRj
aHVuayhpbnQgaSwgaW50IGNodW5rbGluZWxlbiwgY2hhciAqY2h1bmtuYW1lKSB7CiAgaW50IGs7
CiAgaW50IGxpbmVsZW47CiAgY2hhciAqZ2V0bmFtZTsKICBpbnQgZ2V0bGVuID0gMDsKICBpZiAo
REVCVUc9PTMpIHsgcHJpbnRmKCI9PT0gICBcXHN0YXJ0eyVzfSAgID09PVxuIixjaHVua25hbWUp
OyB9CiAgZm9yIChrPWkrY2h1bmtsaW5lbGVuKzE7ICgobGluZWxlbj1uZXh0bGluZShrKSkgIT0g
LTEpOyApIHsKICAgIGlmICgoZ2V0bGVuPWZvdW5kR2V0Y2h1bmsoayxsaW5lbGVuKSkgPiAwKSB7
CiAgICAgICBnZXRuYW1lID0gZ2V0Q2h1bmtuYW1lKGssZ2V0bGVuKTsKICAgICAgIGdldGNodW5r
KGdldG5hbWUpOwogICAgICAgZnJlZShnZXRuYW1lKTsKICAgICAgIGs9aytnZXRsZW4rMTJsOwog
ICAgfSBlbHNlIHsKICAgICAgaWYgKChsaW5lbGVuID49IDExKSAmJiAoZm91bmRFbmQoayxjaHVu
a25hbWUpID09IDEpKSB7CiAgICAgIGlmIChERUJVRz09MykgeyBwcmludGYoIj09PSAgIFxcZW5k
eyVzfSAgID09PVxuIixjaHVua25hbWUpOyB9CiAgICAgIHJldHVybihrKzEyKTsKICAgIH0gZWxz
ZSB7CiAgICAgIGlmIChERUJVRz09MikgeyAKICAgICAgICBwcmludGYoIj09PT09PT09IHByaW50
Y2h1bmsgZWxzZSAlZCAlZFxuIixrLGxpbmVsZW4pOyAKICAgICAgfQogICAgICBwcmludGxpbmUo
ayxsaW5lbGVuKTsKICAgICAgaz1rK2xpbmVsZW4rMTsKICAgIH0KICB9fQogIGlmIChERUJVRz09
MikgewogICAgIHByaW50ZigiPT09PT09PT09PT09PT09PT1cXG91dHslc30gJWRcbiIsY2h1bmtu
YW1lLGspOyAKICB9CiAgcmV0dXJuKGspOwp9CgovKiBmaW5kIHRoZSBuYW1lZCBjaHVuayBhbmQg
Y2FsbCBwcmludGNodW5rIG9uIGl0ICovCmludCBnZXRjaHVuayhjaGFyICpjaHVua25hbWUpIHsK
ICBpbnQgaTsKICBpbnQgbGluZWxlbjsKICBpbnQgY2h1bmtsZW4gPSBzdHJsZW4oY2h1bmtuYW1l
KTsKICBpZiAoREVCVUc9PTMpIHsgcHJpbnRmKCJnZXRjaHVuayglcylcbiIsY2h1bmtuYW1lKTsg
fQogIGZvciAoaT0wOyAoKGxpbmVsZW49bmV4dGxpbmUoaSkpICE9IC0xKTsgKSB7CiAgICBpZiAo
REVCVUc9PTIpIHsgCiAgICAgIHByaW50ZigiLS0tLSIpOyBwcmludGxpbmUoaSxsaW5lbGVuKTsg
cHJpbnRmKCItLS0tXG4iKTsgCiAgICB9CiAgICBpZiAoKGxpbmVsZW4gPj0gY2h1bmtsZW4rMTUp
ICYmIChmb3VuZGNodW5rKGksY2h1bmtuYW1lKSA9PSAxKSkgewogICAgICBpZiAoREVCVUc9PTIp
IHsKICAgICAgICAgZnByaW50ZihzdGRlcnIsIj09PT09PT09PT09PT09PT09XFxnZXRjaHVuaygl
cylcbiIsY2h1bmtuYW1lKTsgCiAgICAgIH0KICAgICAgaT1wcmludGNodW5rKGksbGluZWxlbixj
aHVua25hbWUpOwogICAgfSBlbHNlIHsKICAgICAgaT1pK2xpbmVsZW4rMTsKICAgIH0KICB9CiAg
aWYgKERFQlVHPT0yKSB7IAogICAgZnByaW50ZihzdGRlcnIsIj09PT09PT09PT09PT09PT09Z2V0
Y2h1bmsgcmV0dXJuZWQ9JWRcbiIsaSk7IAogIH0KICByZXR1cm4oaSk7Cn0KCi8qIG1lbW9yeSBt
YXAgdGhlIGlucHV0IGZpbGUgaW50byB0aGUgZ2xvYmFsIGJ1ZmZlciBhbmQgZ2V0IHRoZSBjaHVu
ayAqLwppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqYXJndltdKSB7CiAgaW50IGZkOwogIHN0cnVj
dCBzdGF0IGZpbGVzdGF0OwogIGlmICgoYXJnYyA9PSAxKSB8fCAoYXJnYyA+IDMpKSB7IAogICAg
cGVycm9yKCJVc2FnZTogdGFuZ2xlIGZpbGVuYW1lIGNodW5rbmFtZSIpOwogICAgZXhpdCgtMSk7
CiAgfQogIGZkID0gb3Blbihhcmd2WzFdLE9fUkRPTkxZKTsKICBpZiAoZmQgPT0gLTEpIHsKICAg
IHBlcnJvcigiRXJyb3Igb3BlbmluZyBmaWxlIGZvciByZWFkaW5nIik7CiAgICBleGl0KC0yKTsK
ICB9CiAgaWYgKGZzdGF0KGZkLCZmaWxlc3RhdCkgPCAwKSB7CiAgICBwZXJyb3IoIkVycm9yIGdl
dHRpbmcgaW5wdXQgZmlsZSBzaXplIik7CiAgICBleGl0KC0zKTsKICB9CiAgYnVmc2l6ZSA9IChp
bnQpZmlsZXN0YXQuc3Rfc2l6ZTsKICBidWZmZXIgPSBtbWFwKDAsZmlsZXN0YXQuc3Rfc2l6ZSxQ
Uk9UX1JFQUQsTUFQX1NIQVJFRCxmZCwwKTsKICBpZiAoYnVmZmVyID09IE1BUF9GQUlMRUQpIHsK
ICAgIGNsb3NlKGZkKTsKICAgIHBlcnJvcigiRXJyb3IgcmVhZGluZyB0aGUgZmlsZSIpOwogICAg
ZXhpdCgtNCk7CiAgfQogIGlmIChhcmdjID09IDIpIHsKICAgIGdldGNodW5rKCIqIik7CiAgfSBl
bHNlIHsKICAgIGdldGNodW5rKGFyZ3ZbMl0pOwogIH0KICBjbG9zZShmZCk7CiAgcmV0dXJuKDAp
Owp9Cgo=
--089e082454e464459f055e194a73
Content-Type: application/x-tex; name="test.tex"
Content-Disposition: attachment; filename="test.tex"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_ja2hawh22

XGRvY3VtZW50Y2xhc3N7YXJ0aWNsZX0KClx1c2VwYWNrYWdle3ZlcmJhdGltfQoKXG5ld2Vudmly
b25tZW50e2NodW5rfVsxXXslICAgd2UgbmVlZCB0aGUgY2h1bmtuYW1lIGFzIGFuIGFyZ3VtZW50
CntcIH1cbmV3bGluZVxub2luZGVudCUgICAgICAgICAgICAgICAgICAgIG1ha2Ugc3VyZSB3ZSBh
cmUgaW4gY29sdW1uIDEKJXtcc21hbGwgJFxiYWNrc2xhc2h7fSRiZWdpblx7Y2h1bmtcfVx7e1xi
ZiAjMX1cfX0lIGFsdGVybmF0ZSBiZWdpbiBtYXJrClxoYm94e1xoc2tpcCAyLjBjbX17XGJmIC0t
LSAjMSAtLS19JSAgICAgIG1hcmsgdGhlIGJlZ2lubmluZwpcdmVyYmF0aW19JSAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICBzYXkgZXhhY3RseSB3aGF0IHdlIHNlZQp7XGVuZHZlcmJhdGlt
JSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzIFxlbmR7Y2h1bmt9ClxwYXJ7fSUg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlIGFkZCBhIG5ld2xpbmUKXG5vaW5k
ZW50e30lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQgaW4gY29sdW1uIDEKXGhi
b3h7XGhza2lwIDIuMGNtfXtcYmYgLS0tLS0tLS0tLX0lICAgICAgbWFyayB0aGUgZW5kCiUkXGJh
Y2tzbGFzaHt9JGVuZFx7Y2h1bmtcfSUgICAgICAgICAgICAgIGFsdGVybmF0ZSBlbmQgbWFyayAo
Y29tbWVudGVkKQpccGFyJSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQg
YSBuZXdsaW5lClxub3JtYWxzaXplXG5vaW5kZW50fSUgICAgICAgICAgICAgICAgICAgIGFuZCBy
ZXR1cm4gdG8gdGhlIGRvY3VtZW50CgpccHJvdmlkZWNvbW1hbmR7XGdldGNodW5rfVsxXXslClxu
b2luZGVudCUKe1xzbWFsbCAkXGJhY2tzbGFzaHt9JGJlZ2luXHtjaHVua1x9XHt7XGJmICMxfVx9
fX0lIG1hcmsgdGhlIHJlZmVyZW5jZQoKXGJlZ2lue2RvY3VtZW50fQpUaGlzIGlzIGEgdGVzdCBm
aWxlIGZvciBhIGxpdGVyYXRlIHByb2dyYW0KClxiZWdpbntjaHVua317Zm9vfQpUaGlzIGlzIHRo
ZSBjb2RlIGZvciBGb28KXGVuZHtjaHVua30KClxiZWdpbntjaHVua317Kn0KICBUaGlzIGlzIGEg
dGVzdCBmb3IgaW5saW5pbmcgZGVmYXVsdCBjb2RlClxnZXRjaHVua3tmb299ClxlbmR7Y2h1bmt9
CkxldHMgaG9wZSBpdCB3b3Jrcy4KClxlbmR7ZG9jdW1lbnR9Cg==
--089e082454e464459f055e194a73--

\start
Date: Sat, 25 Nov 2017 12:43:47 -0500
From: Eugene Surowtz <surow@verizon.net>
To: Martin Baker <ax87438@martinb.com>
Subject: Re: [Axiom-developer] Catching up on internals

OK somehow it never arrived here.

Gene

On 11/21/2017 12:07 PM, Martin Baker wrote:
> Gene,
>=20
> Yes, Tim posted the following reply, I think saying ML-related language=
s also have=20
> some knowledge of partial functions.
>=20
> I think I am coming around to the view that the easiest way to to prove=
 axiom correct=20
> and get better type system, parallel code, etc. would be to put the Axi=
om library on=20
> top of a more modern language such as Idris but I think Tim has made it=
 very clear he=20
> is not interested in going in that direction.
>=20
> Martin
>=20
> -------- Forwarded Message --------
>=20
> Subject:=C2=A0=C2=A0=C2=A0=C2=A0 Re: [Axiom-developer] Catching up on i=
nternals
> Date:=C2=A0=C2=A0=C2=A0=C2=A0 Wed, 8 Nov 2017 08:13:00 -0500
> From:=C2=A0=C2=A0=C2=A0=C2=A0 Tim Daly <axiomcas@gmail.com>
> To:=C2=A0=C2=A0=C2=A0=C2=A0 Martin Baker <ax87438@martinb.com>
> CC:=C2=A0=C2=A0=C2=A0=C2=A0 axiom-dev <axiom-developer@nongnu.org>, Tim=
 Daly <daly@axiom-developer.org>
>=20
>=20
>=20
> Partial function checking happens in ML-fathered languages also. It com=
plains
> when I fail to fill out a pattern match with all the cases, for example=
.
>=20
> Proving partial functions implies a set of provisos (checks on the inpu=
t).
> These checks could be inserted as an 'assert' on the calling arguments
> automatically. In addition, or as an alternative in a closed system, yo=
u
> could prove that every caller respects the preconditions and will not e=
ver
> make a call with an invalid argument.
>=20
> This is problematic in cases where the user chooses the input rather
> than calls between internal functions. In that case, adding 'assert'
> statements would provide a place to insert your user-level error messag=
e.
>=20
> Tim
>=20
> On 21/11/17 15:37, Eugene Surowtz wrote:
>> Martin:
>>
>> Did you get any response from Tim on these notes?
>>
>> Gene
>>
>> On 11/7/2017 10:34 AM, Martin Baker wrote:
>>> On 04/11/17 00:42, Tim Daly wrote:
>>>> How would you model handling errors in Spad?
>>>>
>>>> I do think that there might be an interesting research question of h=
ow to
>>>> handle classes of errors in computational mathematics. I had propose=
d
>>>> using Provisos to handle side-conditions on formulas. Hoon Hong and
>>>> Chris Brown have done a lot of work on QEPCAD for handling these.
>>>> Manuel Bronstein and I had long discussions about a SUCHTHAT domain
>>>> for encapsulating Provisos but little code resulted as the QEPCAD wo=
rk
>>>> was still in the future at the time.
>>>
>>> Tim,
>>>
>>> Since you asked this question I've been thinking about it (although I=
 don't claim=20
>>> any expert knowledge).
>>>
>>> It seems to me that there are at least 2 types of errors:
>>> 1) An error where the programmer just does something wrong.
>>> 2) An error where a partial function is called with an invalid value.
>>>
>>> If the program is proved correct then I assume type 1 can't happen so=
 we are=20
>>> mainly concerned with type 2 errors.
>>>
>>> I have been looking at a programming language called 'Idris'. This la=
nguage=20
>>> classifies each function as being either 'total' or 'partial', if it =
is partial=20
>>> then perhaps we can say something about which inputs are invalid.
>>>
>>> Of course the compiler can't always determine that a function is tota=
l (because of=20
>>> the halting problem). However, for most simple functions (without rec=
ursion,=20
>>> dependent types, etc.) it is possible (at least it is in 'Idris') and=
 perhaps the=20
>>> other functions could be classified manually.
>>>
>>> Of course any function could be made 'total' by returning Maybe % or=20
>>> Union(%,"Fail") but that just pushes the problem upto the next level.=
 The=20
>>> advantage of the above ideas is that the error might be explained to =
the user in=20
>>> much more appropriate detail, for example:
>>> "function x called with value y which caused division by 0"
>>> Also it could avoid lots of error handling boilerplate code.
>>>
>>> Martin B
\documentclass{book}
%\newcommand{\VolumeName}{Volume 2: Axiom Users Guide}
%\input{bookheader.tex}
\pagenumbering{arabic}
\mainmatter
\setcounter{chapter}{0} % Chapter 1

\usepackage{makeidx}
\makeindex
\begin{document}



\end{verbatim}
\eject
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\cleardoublepage
%\phantomsection
\addcontentsline{toc}{chapter}{Bibliography}
\bibliographystyle{axiom}
\bibliography{axiom}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\cleardoublepage
%\phantomsection
\addcontentsline{toc}{chapter}{Index}
\printindex
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
