Close

Time For Some News

A project log for Does Anyone Really Know What Time It is?

If you havent noticed, the clock in the Windows Taskbar has gone missing. Will it ever return?

glgormanglgorman 09/28/2025 at 18:220 Comments

Alright, I will explain this later.  In the meantime, images seem to be broken again.  So I will have to try to explain what I am thinking about.  I saw an article online about how someone asked GPT to demonstrate how to construct a rectangle with an area equal to twice the area of another rectangle, while presumably preserving the aspect ratio. Thus, both rectangles have the same aspect ratio.  So maybe it is time to do some more work on my Euclid.cpp source files, on the one hand, while giving some thought as to how to create some kind of proof-generating AI, on the other.

So, to construct such a rectangle, one would need to increase the height and width of the given rectangle by multiplying those dimensions by a factor of the square root of two.  Using compass and straight edge methods alone, this could be done, that is, if provided with an already constructed rectangle, by simply constructing two squares, one with sides equal to the width of the given rectangle, and the other with sides equal to the height of the given rectangle.  Then one can make use of the fact that the length of an internal diagonal of any square is just the length of one of the sides of a square multiplied by the square root of two.

The construction should be performed in such a fashion as to allow for the creation of the second rectangle by making use of a minimum number of steps, i.e., making the most direct application of the compass and straight edge in generating and making use of the required dimensions.  Thus, a rotated and enlarged construction of the given rectangle that overlays the given rectangle should be preferred, for reasons of rigor, that is, over a construction that transfers the dimensions to another sheet.

Now, insofar as how one might turn this into code, so that the problem at hand, somehow, "solves itself", i.e., so that a suitable LLM-based AI might turn what I just said into code. which, herein is already available so as to be able to actually perform the construction, is another matter.

Of course, one of the things that I want to try is to modify a calculator library that makes calls to some of its functions by using a table of function pointers, so that instead of mapping opcodes onto function calls, I want to, instead that is, map words like "bisect", "perpendicular", and so on, onto the appropriate Euclidian operations.  So here is the starting point, for how this sort of thing is typically done.

typedef enum { add=0, sub=1, mult=2, divi=3, }; opcode1;
typedef double (*ftable[])(const double&, const double&);

class calculator
{
protected:
    double reg[16];
    static double (*ftab[4])(const double&, const double&);
    static double fadd(const double &, const double &);
    static double fsub(const double &, const double &);
    static double fmult(const double &, const double &);
    static double fdiv(const double &, const double &);

public:
    static double exec(opcode1, const double &arg1, const double &arag2);
    static int main();
};

Then, in our source file, we fill in the values for our table of function pointers, as well as defining some of the functions themselves.

ftable calculator::ftab =
{
    &calculator::fadd,
    &calculator::fsub,
    &calculator::fmult,
    &calculator::fdiv,
};

double calculator::fadd(const double &arg1, const double &arg2)
{
    double result;
    result = arg1+arg2;
    return result;
}

double calculator::fsub(const double &arg1, const double &arg2)
{
    double result;
    result = arg1-arg2;
    return result;
}

double calculator::fmult(const double &arg1, const double &arg2)
{
     double result;
    result = arg1*arg2;
    return result;
} 

double calculator::fdiv(const double &arg1, const double &arg2)
{
    double result;
    result = arg1/arg2;
    return result;
}

double calculator::exec(opcode1 op, const double &arg1, const double &arg2)
{ 
    double result;
    result = (ftab[op])(arg1,arg2);
    return result;
}

Here, it is easy to see how the function calculator::exec handles the task of looking up the address of the function that we want to call, according to the ordinal value of the opcode associated with the desired function, and then it actually makes the function call for us and returns the appropriate value.  And thus, this makes it possible to call a function like calculator::fmult by knowing that it is associated with the ordinal value of an enum, i.e., the value of "mult".

.....
double val1, val2;
val1 = exec(mult,2,PI);
val2 = exec(mult,exec(add,3,4),exec(add,4,6));
.....

Likewise, in an implementation of Eliza that I am working on,  there is already a method for looking up the number of responses associated with a particular keyword.  So while it might be more elegant to map keywords onto function pointers directly, as this will be less error prone, it is also easy to see how keywords could be used to look up ordinal values in a table of function pointers, and that those function pointers could then be used by a simple interpreter.

key_info keywords[] = 
{
    key_info("THANK",2),
    key_info("CAN YOU",3),
    key_info("CAN I",2),
    key_info("YOU ARE",4),
    key_info("YOU'RE",-1),
    key_info("I DON'T",4),
    key_info("I FEEL",3),

// etc........ 
}

And thus, just in case you have ever wanted to write your own BASIC interpreter, this is one way of doing it!  Thus we might want to have a table of function pointers that maps a word like "midpoint" to a function that we already have.

fpoint fpoint::midpoint (const fpoint &p1, const fpoint &p2)
{
    fpoint result;
    result.x = 0.5*(p1.x+p2.x);
    result.y = 0.5*(p1.y+p2.y);
    return result;
}

 Of course, it will be necessary to have a method for specifying just how to deal with a potentially wide variety of function types, such as functions that take two doubles and return a double, or functions that take two points and return a double, or else functions that take two points and return a point, like the midpoint function, described here.

So, let's consider just how the actual construction might work if we write out a detailed set of instructions in plain English.

  1.  First, construct an arbitrary rectangle with some specified height and width.
  2.  Plot a line that extends the height of the rectangle so that the line is as tall as the rectangle is wide.
  3.  Now draw the diagonal of the suggested square, with or without actually drawing the entire square, i.e., we only need the diagonal of the suggested square, but not the square itself.
  4. Extend the base of the rectangle by an amount equal to the height of the rectangle, and go ahead and fully construct a square adjacent to the original rectangle.
  5. Now plot a line perpendicular to the diagonal of the larger square, which also forms one of the diagonals of the adjacent square.
  6. Extend lines perpendicular from the newly created points, i.e., relative to the associated diagonals, until a point of intersection is found.
  7. Thus, a rectangle with an area twice that of the original rectangle has been constructed.
  8. You may now rotate and shift copies of the newly constructed object as desired, using already established techniques.

Taking notice of word count, and not including the snippets of source code, it would appear that this log entry now contains 999 words, including this sentence, and that bits that follow.  Whether or not a picture is worth 1000 words or not is, of course, another subject altogether.  Especially when we begin to contemplate the issues associated with trying to create a more general proof-generating engine.  And so it goes.

Discussions