From C++ to HERCs Prolog: Can you do this in another language?
This is one of my favourite examples! You will see how parameters are passed.
Let's say, we have two functions in C or C++ or Java or in some other similar language.
One of them multiplies by 3. The other divides by three.
Here we will translate these two functions into HERCs Prolog code.
The result will be quite intriguing.
double multiplyBy3 (double argument)
{
double result;
result = argument * 3.0;
return result;
}
AND
double divideBy3 (double argument)
{
double result;
result = argument / 3.0;
return result;
}
First, let's focus on the first function.
In general Prolog instructions don't return values.
We need to do something about it here.
First, we will change the signature. A new output parameter will be introduced and return type will be changed to void.
Also, we will remove the declaration of result and the whole return statement all-together.
Here is what we have:
void multiplyBy3 (double argument, double * result)
{
* result = argument * 3.0;
}
// Note: star (*) also means 'pointer', which is used to implement output parameters in C/C++.
Now we will do the first step to make it looking like prolog.
First, we will remove the void keyword. Similarly, we will remove the double keywords.
They are not necessary either.
Then we will change M-Expressions into S-Expressions.
This will be done for both function signature and body.
{(multiplyBy3 argument, * result)
* result = argument * 3.0;
}
The next step is purely syntactic.
We have to change all the brackets into square brackets.
Also, we can remove all the comas and semicolons.
[[multiplyBy3 argument * result]
* result = argument * 3.0
]
We are now ready to do something about parameters.
First of all, we don't know the value of argument. Therefore it is going to be a variable.
All unknown variables in HERCs Prolog begin with the star (*).
This is not a pointer! Don't get confused!
The same with result, as we don't know its value it is going to be a variable as well.
[[multiplyBy3 *argument *result]
* result = argument * 3.0
]
Now it is time to do something about the actual calculation inside the body of this code.
We need a multiplication instruction. HERCs Prolog has got two.
We will chooose the times instruction.
It takes 3 parameters. It multiplies the first two and the third parameter becomes the result.
Here is what we end-up-with:
[[multiplyBy3 *argument *result]
[times *argument 3.0 *result]
]
GREAT! We just translated the mutliplyBy3 function
Now we can deal with the divideBy3. Let's quickly by-pass the obvious steps.
This is how it looks after all the modifications, EXCEPT changing the body:
[[divideBy3 *argument *result]
* result = argument / 3.0
]
Obviously we need the division instruction.
Interestingly, we can also use the times instruction.
Pay special attention as it is quite interesting.
The times instruction can also do divisions.
Simply, if one of the first two operands is unknown AND our result is already some number, then times calculates the unknown operand.
Below is the code:
[[divideBy3 *argument *result]
[times *result 3.0 *argument]
]
The meaning of the above is roughly: what *result multiplied by 3.0 gives the *argument?.
Please, read it again as it is quite important.
Now, the time for surprise! Please, compare the two different codes for multiplyBy3 and divideBy3.
[[multiplyBy3 *argument *result]
[times *argument 3.0 *result]
]
[[divideBy3 *argument *result]
[times *result 3.0 *argument]
]
Exactly! We just wrote two almost identical codes! The only differences? Name (multiplyBy3 versus divideBy3) and the order of parameters.
Does it mean we can use multiplyBy3 to do divisions by 3.0?
Yes.
Try typing-in the following querries, one for multiplication, the other for division:
[res [multiplyBy3 4.0 *result] [show *result]]
[res [multiplyBy3 *result 12.0] [show *result]]
You can do exactly the same with divideBy3:
[res [divideBy3 12.0 *result] [show *result]]
[res [divideBy3 *result 4.0] [show *result]]