L.H.O.O.Q.

From Esolang
Jump to navigation Jump to search
This is still a work in progress. It may be changed in the future.

L.H.O.O.Q. is the conceptual combination of the crude pun of Marcel Duchamp's 1919 readymade artwork wikipedia:L.H.O.O.Q., the joke-language HQ9+ , and complex analytical number theory wikipedia:L-functions (applied to graph humorous moustaches and goatees).

Currently this language is UNDERSPECIFIED, but the joke is probably as clear as it will ever be. The creator User:Salpynx would gladly accept help in figuring out mechanisms to improve the computational power of this language.

The examples used and linked to from this page use the the Riemann Zeta function as a representative stand-in for arbitrary L-Function graphs. Riemann Zeta is effectively the Lorem Ipsum of L.H.O.O.Q.. General suggestions and corrections welcome!

Language goals

  1. replicate a Dadaist readymade
  2. draw more moustaches
  3. to be less comprehensible than Malbolge, on the surface as intelligent as Chicken but as powerful as HQ9+, flirt with mathematical concepts as interesting as Eodermdrome, and perhaps eventually become non-obviously Turing-complete like The Waterfall Model.

It is also a semi-serious attempt to use higher level mathematical objects (functions) as an alphabet for an esolang, rather than the arbitrary characters and numerals used by most langauges. There is a meta layering in L.H.O.O.Q. where character alphabets specify functions, and the resulting functions are used for further operations. This goal is likely de-railed considerably by the many moustaches.

Commands

L add <Lisa> image token to the output buffer and begin an L-Function definition
H add "bonjour" and "monde" text tokens to the token buffer
O decorate a text token in the token buffer with a moustache and goatee
Q add the program's source code to the token buffer
. Increment the accumulator
EOL End L-Function definition, and display contents of output buffer, perform image token decoration (or equivalent non-graphical output).

L.H.O.O.Q. has one output buffer, which is used to collect tokens, and define L-Functions.

There are two kind of tokens, Image tokens, and Text tokens. Image tokens are decorated by L-functions. Text tokens are decorated by the O command.

Additionally, there is the accumulator, which is incremented by the . command.

Decorators

Image tokens are decorated by the graphed output of L-functions.

  • The Z-function along the critical line of an L-function graphs the moustache beneath the nose of the <Lisa> token.
  • The Real / Imaginary plot graphs the goatee on the chin of the <Lisa> token.

Text tokens are decorated by unicode combining diacritics

  • (U+035D) COMBINING DOUBLE BREVE
  • (U+032C) COMBINING CARON BELOW

Example of a decorated 'monde' token: m͝on̬d͝e The decoration represents two halves of a moustache, and a goatee below.

Function specification

Functions are specified in the following way:

For each L definition group:

  • q = <group accumulator value> = modulus of the character
  • n = <count of text tokens + decorators> = index of the character

H tokens, {'bonjour', 'monde'}, count as half each, a text decoration count as one, and empty strings count as zero. This means n is a simple character count of {H, O, Q}.

This selects a Dirichlet character by its Conrey label: χq(n,⋅) (see L.H.O.O.Q.#External resources)

Example: L.H.O.O.Q. q = 5, n = 4. Dirichlet character: χ5(4,⋅), which gives an nice symmetrical Z-function graph, which satisfies this language's requirements for the canonical example moustache.

Example: LH. q = 1, n = 1, gives χ1(1,⋅), which somewhat elegantly is the Riemann Zeta-function, and a rather clean 'Hello World' example in L.H.O.O.Q..

L.H.O.O.Q. can be used to specify any L-function of degree-1 in this way.

Not all combinations of q and n are valid characters. Trivially, it is invalid if the index n exceeds the modulus q. In this case, the pair (q, n) is used to signify a piecewise linear function, which is the absolute value of the function that passes through the point (q, n) and the origin, flipped about the x-axis using a term calculated lift = (<text-decorator count>-<text-token count>)/abs(<text-decorator count>-<text-token count>)

This produces graphs shaped either like , or , which can be used as linear moustaches, or combined (addition, or multiplication) with Z-function graphs to provide lift or droop.

Edge cases:

  1. If the lift term is zero (i.e. there are as many decorators as text tokens), rather than no lift, two linear functions are produced, mirrored on the y-axis to form an X. These provide cat whiskers!
  2. If the pair (q, n) defines a line where x=0, rather than causing an error, this is interpreted as the integer 1. Combinations of this can be used for multiplying other functions.

Integer moustaches are to be represented graphically by the "toothbrush" moustache popularised by Charlie Chaplin and others. For combined integers the suggested layout is as follows: odd valued moustaches are to be joined, even valued one to be split.

  • = 1
  • ▆ ▆ = 2
  • ▆▆▆ = 3
  • ▆▆▆ ▆▆▆ = 6

Combining functions

{needs exapnsion, validation, and testing}

Multiple functions can be combined on a single line, by using repeated L characters.

  • L - addition
  • LL - multiplication
  • LLL.... - exponentiation, exponent = count(L) - 1

Exponentiated functions are either added or multiplied depending on preceding operations.

L{F1}LLL{F2} = F1 + F22

L{F1}LL{F2}LLL{F3} = F1 * F2 * F32

There should be a way to provide an unambiguous conversion from this to postfix notation to handle grouping correctly.

Functions can be multiplied by integers. With addition however, the combination is not clear so the result is a ``list`` (F1, 3, F2, 1, F3), which may prove useful for computation.

Lines beginning with LL are a special case which capture the resulting function form the previous line and make it available for further operations, (justification: there is no value in multiplying the first function by an assumed 0, so the last encountered function is used instead).

Looping constructs

{very provisional}

Each L definition instantiates its own accumulator. Accumulators outside an L block, . at the beginning of a line, could be used as line markers for looping.

A loop is closed by matching lines with a equal accumulator values outside any L block.

A loop is skipped, in analogy with 'branch if zero', if the last encountered functions non-trivial zeros are all on the critical line. This effectively assumes the Riemann hypothesis is true, otherwise conditional branching would not be possible in L.H.O.O.Q.. In practice, the intent is that a plain L-function is combined with piece-wise linear function that shifts all non-trivial zeros off the critical line, and further combinations of other piece-wise linear functions unfold it back to the critical line. This needs investigation and proof that it is a workable mechanism.

Interpreters should generate a warning if any unexpected Siegel zeros are encountered while evaluating loop conditions. This is very important as it could mean the user is entitled to $1M (this is not a joke! -- see Millennium Prize).

Comparison with HQ9+

Just like HQ9+, L.H.O.O.Q. enables the following useful proofs of ability when implemented in another programming language.

  • Character output
  • Graphical output
  • H: Output "Hello World" (or equivalent)
  • Q: Output a Quine
  • L: Perform a more complex task, (calculation and looping) where L is far more interesting and challenging than 9
  • .: Increment an accumulator
  • O: Demonstrate string manipulation (additional proof of ability)

Examples

The canonical program in L.H.O.O.Q. is the eponymous: L.H.O.O.Q. Which is designed to produce output which closely resembles the original L.H.O.O.Q. artwork:

LHOOQ.png
<image of mona lisa with drawn on moustache and goatee>
  L.H.O.O.Q.
 ͝  ̬ ͝    ͝  ̬ ͝
bonjour monde

The accumulator will be set to 5

The 'Hello World' equivalent text is clearly not in the original. This is explained by Marcel Duchamp not being a computer programmer.

Display limitations

Optionally, for limited graphics environments, the output will consist of the lyrics or 99 bottles as generated by the defined L-function.

Representative example of complex 99 bottles:

99.000 imaginary bottles of beer of the wall,
99.000 imaginary bottles of beer.
Take -1.808 down, pass it around,
100.808 bottles of beer on the wall

100.808 imaginary bottles of beer of the wall,
100.808 imaginary bottles of beer.
Take 0.999 down, pass it around,
99.809 bottles of beer on the wall

99.809 imaginary bottles of beer of the wall,
99.809 imaginary bottles of beer.
Take -0.873 down, pass it around,
100.682 bottles of beer on the wall

100.682 imaginary bottles of beer of the wall,
100.682 imaginary bottles of beer.
Take -0.700 down, pass it around,
101.382 bottles of beer on the wall

101.382 imaginary bottles of beer of the wall,
101.382 imaginary bottles of beer.
Take -0.644 down, pass it around,
102.026 bottles of beer on the wall

102.026 imaginary bottles of beer of the wall,
102.026 imaginary bottles of beer.
Take -0.667 down, pass it around,
102.693 bottles of beer on the wall

102.693 imaginary bottles of beer of the wall,
102.693 imaginary bottles of beer.
Take -0.956 down, pass it around,
103.649 bottles of beer on the wall

103.649 imaginary bottles of beer of the wall,
103.649 imaginary bottles of beer.
Take -13.391 down, pass it around,
117.040 bottles of beer on the wall

117.040 imaginary bottles of beer of the wall,
117.040 imaginary bottles of beer.
Take -0.814 down, pass it around,
117.854 bottles of beer on the wall

117.854 imaginary bottles of beer of the wall,
117.854 imaginary bottles of beer.
Take -0.666 down, pass it around,
118.520 bottles of beer on the wall

118.520 imaginary bottles of beer of the wall,
118.520 imaginary bottles of beer.
Take -0.693 down, pass it around,
119.213 bottles of beer on the wall

119.213 imaginary bottles of beer of the wall,
119.213 imaginary bottles of beer.
Take -0.795 down, pass it around,
120.008 bottles of beer on the wall

120.008 imaginary bottles of beer of the wall,
120.008 imaginary bottles of beer.
Take -0.965 down, pass it around,
120.973 bottles of beer on the wall

120.973 imaginary bottles of beer of the wall,
120.973 imaginary bottles of beer.
Take -1.106 down, pass it around,
122.079 bottles of beer on the wall

122.079 imaginary bottles of beer of the wall,
122.079 imaginary bottles of beer.
Take -2.167 down, pass it around,
124.246 bottles of beer on the wall

124.246 imaginary bottles of beer of the wall,
124.246 imaginary bottles of beer.
Take -14.588 down, pass it around,
138.835 bottles of beer on the wall

138.835 imaginary bottles of beer of the wall,
138.835 imaginary bottles of beer.
Take 3845470089057.080 down, pass it around,
No more imaginary bottles of beer!

Which is produced by the following python (tested in 2.7, requires mpmath) code as a simulation of what to expect from a legitimate L.H.O.O.Q. program:

from mpmath import im, j, mp
def im_beer(s_real=0.0001, chi = [1]):
    b = 99j
    while im(b) > 0:
        print("%.3f imaginary bottles of beer of the wall,\n%.3f imaginary bottles of beer." % (im(b), im(b)))
        sub = mp.dirichlet(s_real+b, chi)
        print("Take %.3f down, pass it around," % im(sub))
        if im(sub) < im(b):
            b -= sub
            print("%.3f bottles of beer on the wall\n" % im(b))
        else:
            print("No more imaginary bottles of beer!")
            break

im_beer(0.5**100, [1, -j, j])

Moustache trimming

The current proof-of-concept graphs functions extending as far as possible in either direction on the x axis, which differs again from the original artwork, but is more interesting from the perspective of analysing L-functions. Policies on moustache trimming can be considered an interpreter implementation detail.

Easter Egg

(Help Wanted) It would be ideal if there were some specific trigger that could convert an L token from <Lisa> to <Lena>, and produce an equivalent decoration. Possibly non-deterministic easter-egg?

See also

Magritte

External resources