Search code examples
prologcode-translation

Is it somehow a "reflection" in Prolog?


So basically I am trying to use some Prolog code to simulate pointer like behavior.

I asked a related question here, and after around one month, I finally have time to start.

Here is a simple example in C:

int a = 1;
int* p = &a;
int b = *p;   

And I want to translate this code into Prolog like this (or other better strategies?):

A is 1, 
assert(ref(p, a)),    <-  this can be dynamic fact gene
ref(p, TEMP),   <-  now I want to use a!!
to_lowercase(TEMP, TEMP1),  <- I don't know how to implement to_low
B is TEMP1.     <- reflection? 

So in the above code, I am confused with

  1. In my understanding, after ref(p, TEMP), then TEMP will equal to "a", and it is just a string, then how can I reuse it as a variable name, sounds like a reflection...?

  2. How to implement the to_lowercase function?

Am I clear?


Solution

  • If you are really that determined to simulate a computer from within Prolog, you should take into account the answers to your previous questions before moving on. Either way, this answer makes a lot of assumptions about what your ultimate goal is. I am guessing that you are trying to simulate a machine, and write a simulator that takes source code written in a C-style language and executes it.

    So let's say you have a very simple processor with flat memory space (some small embedded microcontrollers are like this). Your whole memory then would be just one chunk of 16-bit addresses, let's say 1000 of them:

    functor(Memory, memory, 1000).
    

    Taking your C code above, a compiler might come up with:

    • Pick an address Addr1 for a, which is an int, and write the value 1 at that address
    • Pick an address Addr2 for p, which is an int *, and write the value of the address of a at that address
    • Pick an address Addr3 for b, which is an int, and write to it the value which is at the memory to which the value in p is pointing to.

    This could translate to machine code for the machine you are simulating (assuming the actual addresses have been already picked appropriately by the compiler):

    arg(Addr1, Memory, 1),     % int a = 1;
    arg(Addr2, Memory, Addr1), % int *p = &a;
    arg(Addr2, Memory, Tmp1),  %% put the value at p in Tmp1; this is an address
    arg(Tmp1, Memory, Tmp2),   %% read the value at the address Tmp1 into Tmp2
    arg(Addr3, Memory, Tmp2).  % int b = *p;
    

    So of course all addresses should be within your memory space. Some of the calls to arg/3 above are reads and some are writes; it should be clear which is which. Note that in this particular conjunction all three arguments to the term memory/1000 are still free variables. To modify the values at an address that has been already set you would need to copy it accordingly, freeing the address you need to reuse.

    Please read carefully all the answers to your questions before pressing on.