How to implement C code with pointers in Prolog? - c

I am new to prolog. I have learned that ,though it is a declarative language, prolog can be used as a general purpose programming language, just like C. So, whatever problems you can solve in C, you can solve in prolog as well, even though its run-time may not be as good. Since there are no pointers in prolog (as far as i know), I am wondering if i can write an equivalent program in prolog for the following code written in C :-
#include <stdio.h>
int main()
{
int a = 5;
int *p;
p = &a;
printf("The address of a is %d.", p);
return 0;
}

You're trying to drive in a nail using a screwdriver, to use a popular analogy. Prolog is not C and solving problems in Prolog is fundamentally different from solving them in C.
Printing the value of a variable is easy to do, for example:
main :-
X = 5,
io:format("X = ~w~n", [X]).
but you can't get the address of X like you can in C. And why would you want to? The address could be different next time since Prolog has automatic garbage collection.
If you want to learn Prolog, forget about trying to write Prolog programs which look like C programs, and try to solve actual problems instead. You could try out the Project Euler series of problems, for example.

Apart from the comments and the existing answer, here is more:
Ask yourself: what is the use of the C program that you have shown? What problem does it solve? I can't answer this question, and I suspect you can't answer it either. In isolation, this program has no useful application whatsoever! So despite C being a general purpose programming language, you can write programs without any purpose, general or domain-specific.
The same, of course, is true of Prolog.
To pointers in particular: they are a very thin abstraction over absolute memory addresses. You can use (and abuse) pointers in many ways, and, if your algorithms are correct for the problem you are currently solving, the compiler can generate very efficient machine code. The same, however, is true of Prolog. The paradigms, however, will be very different.
In summary, you have managed to write a question so devoid of meaning that you provoked me to answer it without any code.
P.S. Or you have just trolled us with moderate success.

Well, since you tagged swi-prolog your question, I can show the code I used to exchange Qt GUI objects (just pointers, you know...) with the Prolog engine.
/** get back an object passed by pointer to Prolog */
template<typename Obj> Obj* pq_cast(T ptr) {
return static_cast<Obj*>(static_cast<void*>(ptr));
}
to be used, for instance in swipl-win, where _read_f is really a C callback:
/** fill the buffer */
ssize_t Swipl_IO::_read_f(void *handle, char *buf, size_t bufsize) {
auto e = pq_cast<Swipl_IO>(handle);
return e->_read_(buf, bufsize);
swipl-win has found its way as the new console in SWI-Prolog.

Related

Which number, 0 or 1, should I define the variabliable of loops for arrays from?

I'm a beginner in data structures. I learnt that SqLists are starting from 1, when the arrays inside SqLists are from 0.
The question is if I create a loop, which of the following representation is better? Will the other one be weird?
//i=0 according to arrays
for(int i=0;i<L->length;++i)
L->data[i]=givenArray[i];
//i=1 according to SqList
for(int i=1;i<=L->length;++i)
L->data[i-1]=givenArray[i-1];
There is nothing wrong with either ways.
With that aside, the first way of writing is more clear and often used when writing programs (in any language).
If you are programming alone, it doesn't really matter, just pick your style and stick to it.
But, if you want to adhere to global programming conventions, and make your code more readable and accessible to other people, stick for the first style.

alternative to sandboxing C for a programming contest with very limited constraints

I'm trying to organize a programming contest for signal processing; originally it was going to be in Python, but the question came up if I could expand allowable entries to C.
The type of programming needed for the entries is really pretty limited:
no stdin/stdout needed
contestants can declare 1 struct containing state variables
entries can declare functions
I will create my own trusted C code for a test harness that calls into the contestants' entries
So I am wondering:
is it possible to declare a particular C file as "safe" by parsing, if there are severe restrictions on the type of calculations allowed? The one thing I can't seem to figure out is how to easily prevent casting pointers or pointer arithmetic.
Entries would be of this form (more or less):
#include "contest.h"
// includes stdint.h and math.h and some other things
// no "#" signs after this line allowed
typedef struct MyState {
int16_t somevar;
int16_t anothervar;
...
} MyState_t;
void dosomething(MyState *pstate)
{
...
}
void dosomethingelse(MyState *pstate)
{
...
}
void calculate_timestep(MyState *pstate, ContestResults *presults)
{
...
}
I've read some of the sandboxing questions (this and this) and it looks a bit difficult to find a way to sandbox one part of C code but allow other trusted parts of C code. So I'm hoping that parsing may be able to help "bless" C code that meets certain constraints.
Any advice? I don't really care if it gets stuck in an infinite loop (I can kill it if the time takes too long) but I do want to prevent OS access or unwanted memory access.
There's no point in allowing C if you also want to disallow things that are part of C, such as pointers, casting, and pointer arithmetic. Many valid C programs then become impossible to write, which would seem counter-intuitive if you're saying "you can use C".
It's hard to detect statically that a program won't do
*(uint32_t *) 0 = 0xdeadf00d;
which might cause a segmentation fault on your host operating system. I'm sure it's possible, or that very good attempts have been made. This Wikipedia article has a list of C and C++ static checking tools that you can investigate.

beginner Cuda program

This is with ref to the code http://wind.d.umn.edu/acmclub/sites/default/files/summation.cu provided at http://wind.d.umn.edu/acmclub/?q=node/12
Im a beginner programmer but still I could follow the code and explanation except for few things.
1.] What is the meaning of "new" in this line taken from summation.cu
sum_h = new unsigned long();
2.]Also I really couldnt understand this code. What purpuse does strtoul serve ? I'd be thankful if you could point to some beginners resource on "new" & "strtoul"
n = strtoul(argv[1], NULL, 0);
3.] Is the code "summation.cu" written completely in C++. So inorder to code CUDA programs do I need to learn C++ instead of C? Or do I need to learn both C & C++ ?
To make it short:
new allocates memory (e.g. for the sum) (see details)
strtoul converts a string to a long (see details)
I think you should start with a good C++ book (e.g. C++ Primer) and learn some C later (e.g. from this book). After that I would start with
CUDA.
Keep your chin up.
As Saviour Self pointed out in the comments - new means dynamic memory allocation on the heap at runtime. More information here.
I think this is pretty much similar to the C-function atoi that converts a number stored as a char into a integer. In you case this should convert the number (stored as char) in argv[1] into a unsigned long int. Check it here.
The language used in CUDA is called "C for CUDA" and as long as I've been reading and learning you can code in C but there are many features of C++ that are also supported. You can start taking a look at CUDA DOCUMENTATION.
Hope this helps.

what the author of nedtries means by "in-place"?

I. Just implemented a kind of bitwise trie (based on nedtries), but my code does lot
Of memory allocation (for each node).
Contrary to my implemetation, nedtries are claimed to be fast , among othet things,
Because of their small number of memory allocation (if any).
The author claim his implementation to be "in-place", but what does it really means in this context ?
And how does nedtries achieve such a small number of dynamic memory allocation ?
Ps: I know that the sources are available, but the code is pretty hard to follow and I cannot figure how it works
I'm the author, so this is for the benefit of the many according to Google who are similarly having difficulties in using nedtries. I would like to thank the people here on stackflow for not making unpleasant comments about me personally which some other discussions about nedtries do.
I am afraid I don't understand the difficulties with knowing how to use it. Usage is exceptionally easy - simply copy the example in the Readme.html file:
typedef struct foo_s foo_t;
struct foo_s {
NEDTRIE_ENTRY(foo_t) link;
size_t key;
};
typedef struct foo_tree_s foo_tree_t;
NEDTRIE_HEAD(foo_tree_s, foo_t);
static foo_tree_t footree;
static size_t fookeyfunct(const foo_t *RESTRICT r)
{
return r->key;
}
NEDTRIE_GENERATE(static, foo_tree_s, foo_s, link, fookeyfunct, NEDTRIE_NOBBLEZEROS(foo_tree_s));
int main(void)
{
foo_t a, b, c, *r;
NEDTRIE_INIT(&footree);
a.key=2;
NEDTRIE_INSERT(foo_tree_s, &footree, &a);
b.key=6;
NEDTRIE_INSERT(foo_tree_s, &footree, &b);
r=NEDTRIE_FIND(foo_tree_s, &footree, &b);
assert(r==&b);
c.key=5;
r=NEDTRIE_NFIND(foo_tree_s, &footree, &c);
assert(r==&b); /* NFIND finds next largest. Invert the key function to invert this */
NEDTRIE_REMOVE(foo_tree_s, &footree, &a);
NEDTRIE_FOREACH(r, foo_tree_s, &footree)
{
printf("%p, %u\n", r, r->key);
}
NEDTRIE_PREV(foo_tree_s, &footree, &a);
return 0;
}
You declare your item type - here it's struct foo_s. You need the NEDTRIE_ENTRY() inside it otherwise it can contain whatever you like. You also need a key generating function. Other than that, it's pretty boilerplate.
I wouldn't have chosen this system of macro based initialisation myself! But it's for compatibility with the BSD rbtree.h so nedtries is very easy to swap in to anything using BSD rbtree.h.
Regarding my usage of "in place"
algorithms, well I guess my lack of
computer science training shows
here. What I would call "in place"
is when you only use the memory
passed into a piece of code, so if
you hand 64 bytes to an in place
algorithm it will only touch that 64
bytes i.e. it won't make use of
extra metadata, or allocate some
extra memory, or indeed write to
global state. A good example is an
"in place" sort implementation where
only the collection being sorted
(and I suppose the thread stack)
gets touched.
Hence no, nedtries doesn't need a
memory allocator. It stores all the
data it needs in the NEDTRIE_ENTRY
and NEDTRIE_HEAD macro expansions.
In other words, when you allocate
your struct foo_s, you do all the
memory allocation for nedtries.
Regarding understanding the "macro
goodness", it's far easier to
understand the logic if you compile
it as C++ and then debug it :). The
C++ build uses templates and the
debugger will cleanly show you state
at any given time. In fact, all
debugging from my end happens in a
C++ build and I meticulously
transcribe the C++ changes into
macroised C.
Lastly, before a new release, I
search Google for people having
problems with my software to see if
I can fix things and I am typically
amazed what someone people say about
me and my free software. Firstly,
why didn't those people having
difficulties ask me directly for
help? If I know that there is
something wrong with the docs, then
I can fix them - equally, asking on
stackoverflow doesn't let me know
immediately that there is a docs
problem bur rather relies on me to
find it next release. So all I would
say is that if anyone finds a
problem with my docs, please do
email me and say so, even if there
is a discussion say like here on
stackflow.
Niall
I took a look at the nedtrie.h source code.
It seems that the reason it is "in-place" is that you have to add the trie bookkeeping data to the items that you want to store.
You use the NEDTRIE_ENTRY macro to add parent/child/next/prev links to your data structure, and you can then pass that data structure to the various trie routines, which will extract and use those added members.
So it is "in-place" in the sense that you augment your existing data structures and the trie code piggybacks on that.
At least that's what it looks like. There's lots of macro goodness in that code so I could have gotten myself confused (:
In-place means you operate on the original (input) data, so the input data becomes the output data. Not-in-place means that you have separate input and output data, and the input data is not modified. In-place operations have a number of advantages - smaller cache/memory footprint, lower memory bandwidth, hence typically better performance, etc, but they have the disadvantage that they are destructive, i.e. you lose the original input data (which may or may not matter, depending on the use case).
In-place means to operate on the input data and (possibly) update it. The implication is that there no copying and/moving of the input data. This may result in loosing the input data original values which you will need to consider if it is relevant for your particular case.

Trying to understand the MD5 algorithm

I am trying to do something in C with the MD5 (and latter trying to do something with the SHA1 algorithm). My main problem is that I never really did anything complex in C, just simple stuff (nothing like pointers to pointers or structs).
I got the md5 algorithm here.
I included the files md5.c and md5.h in my C project (using codeblocks) but the only problem is that I don't really understand how to use it. I have read and re-read the code and I don't understand how I use those functions to turn 'example' into a MD5 hash.
I haven't done C programming in a while (mostly php) so I am a bit lost here.
Basically what I am asking is for some examples of usage. They are provided via the md5main.c file but I don't understand them.
Am I aiming high here? Should I stop all this and start reading the C book again or can anyone give me some pointers and see if I can figure this out.
Thanks.
While I agree with Bill, you should go back to the C book if you want to really understand what you're doing. But, in an effort to help, I've modified and commented some of the code from md5main.c...
const char* testData = "12345"; // this is the data you want to hash
md5_state_t state; // this is a state object used by the MD5 lib to do "stuff"
// just treat it as a black box
md5_byte_t digest[16]; // this is where the MD5 hash will go
// initialize the state structure
md5_init(&state);
// add data to the hasher
md5_append(&state, (const md5_byte_t *)testData, strlen(testData));
// now compute the hash
md5_finish(&state, digest);
// digest will now contain a MD5 hash of the testData input
Hope this helps!
You should stop all this and start reading the C book again.
My experience is that when I am trying to learn a new programming language, it's not practical to try implementing a complex project at the same time. You should do simple exercises in C until you are comfortable with the language, and then tackle something like implementing MD5 or integrating an existing implementation.
By the way, reading code is a skill different from writing code. There are differences between these two skills, but both require that you understand the language well.
I think you picked about the worst thing to look at (by no fault of your own). Encryption and hash type algorithms are going to make the strangest use of the language possible to do the type of math they need to do quickly. They are almost guaranteed to be obfuscated and difficult to understand. Plus, you will need to get bogged down in math in order to really understand them.
If you just want a hashing algorithm, get a well-known implementation and use it as a black box. Don't try and implement it yourself, you will almost certainly introduce some cryptographic weakness into the implementation.
Edit: To be fully responsive if you want great books (or resources) on encryption, look to Bruce Schneier. Applied Cryptography is a classic.

Resources