Advertisement

AI and Self Modifying Code

Started by March 28, 2006 07:20 PM
15 comments, last by GameDev.net 18 years, 7 months ago
I just had a thought one night... I have heard alot about the mis-uses of the goto command because of it's tendency to lead to spagetti code... I was thinking spagetti code would be alright for AI if it was implemented correctly (and I don't mean a programmer figuring out the sequence of jumps)... But what if a program had the ability to program itself with the sequencing of jumps so that you enter the code in certain places and exit in other places and depending on the outcome of the exit, the program could change the sequence of jumps in order to give the intended result... Sorta like a neural net I don't know how easily it is to do self-modifying code from within Windows indeed if it is possible at all... It also came to mind that it might best be done on a dual core processor.
[google] "self-modifying code"

-me
Advertisement
You should check out CoreWars :)

There is a windows Interpretter called WinCore
-www.freewebs.com/tm1rbrt -> check out my gameboy emulator ( worklog updated regularly )

Self modifying code is usually efficient only when the code change is made once by some decision making process that selects the appropriate options (what to run and what code to bypass) which may be a complicated set of calculations/logic. The decision is based on some logic evaluating the situational state and matching up which precanned code block solutions are best. The generated code would then be re-executed numerous times using that decision with the minimum amount of code execution (otherwise you might as well use conventional methods imbedding all the IF-THEN-ELSE logic).

Nothing says you couldnt do jump table offsets (using ASM) based on the content of an options data array (in variablespace where its readwriteable). It would be marginally more costly execution-wise than direct GOTO jumps. One of the problem with true self modifying code is that its not useable for instancing. Having each thread/fiber instance control its own custom code option block would get around that limitation (and might eliminate alot of the VirtualProtect() calls and other overhead.)

This of course is for code that cannot be done simply by using callbacks -- like numerous (twisty??) small/finegrained code chunks (where many callbacks to small chunks of code would have excessive overhead for context parameters...) and combinatorics precludes having many coarse grained callback functions that cover the range of combinations (like substituting sort functions).

An example I can think of for AI would be building filter logic to be used by some behavioral code -- a sensory filter that is applied to ALOT of situational data and which doesnt change very often -- it would be built up from an object's abilities/unique attributes. The patterns would not be simple matching, but more complex AND/OR/NOT clauses and Value Range tests (and custom function calls) for multiple attribute factors -- something that would run horribly slow if it had to be 'interpreted' and generalized.


Which brings up the use of self-modifying code in script languages. Having a script build another script to do a customized operation (and preferably a bytecode style script system to speed operations) would not require OS level write permissions (as it is already program data). Such code building code is usually quite ugly and large and generalized (and slow), but can pay off in performance as the custom code is executed millions/billions of times over its lifetime (consider how incredibly slow it would be if a generalized script doing the same thing had to be run instead).


A program can't change itself. This is because it is running and depends on itself to run the program. When a file is saved it completly wipes the file and then saves over it so the program would glitch. So what you need is another copy of the program and a source. Then a file that rights the new programs.

The program will send a command to the source saying that it needs to change itself and the source will activate the writing program to write over your copy then the copy will send a string saying it is updated and working and it will turn on the second copy and auto enter all values in the first so whatever it's other function is won't be restarted. Then the first will be deactivated and rewriten. Then this will send a string to the source telling it that it is ready to take control back over the program.
Check my forus at http://s14.invisionfree.com/tsoftor http://tjsoftware.tk
C# can generate its own code procedurally, compile it, and run it all without restarting the main app.

And there's nothing stopping you from generating native code on the fly in any other language with direct access to memory, but you'd have to do a lot more work yourself.
Advertisement
Quote: Original post by tjweb92
A program can't change itself. This is because it is running and depends on itself to run the program. When a file is saved it completly wipes the file and then saves over it so the program would glitch. So what you need is another copy of the program and a source. Then a file that rights the new programs.

The program will send a command to the source saying that it needs to change itself and the source will activate the writing program to write over your copy then the copy will send a string saying it is updated and working and it will turn on the second copy and auto enter all values in the first so whatever it's other function is won't be restarted. Then the first will be deactivated and rewriten. Then this will send a string to the source telling it that it is ready to take control back over the program.
You're completely wrong. Machine code can be changed in memory, and it's not impossible (though not easy) to save it back to the file. The reason saving the changes is difficult is twofold, with neither part being the reason you stated. First, windows loads executables by mapping the file to memory, which causes it to be locked as long as it remains open. Luckily, ntdll.dll exports a function that allows you to unmap the executable, but it must be used with caution because simply calling the funciton in a standard executable would cause the code to be unloaded as well, so special measures must be taken in the code to prevent that from happening. The second problem is that executables are not stored on disk in the same layout they are stored in memory, so there would need to be a transformation function to adjust addresses, padding, etc.

In C or C++, making a self-modifying executable would be extremely difficult and would require non-standard extensions to the languages. In machine code/assembly, it's possible but not easy, and in higher level languages such as Common Lisp, the only hard part is saving the changes (and that might not be too hard depending on the implementation).
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Code which changes its behaviour over time, is NOT the same as self-modifying code, which literally modifies itself. An AI algorithm could gradually change its behaviour without needing to modify itself.

Self modifying code was used historically to save a bit of space occasionally in assembly language, and as an obfuscation method.

There is no case for self modifying code any more.

Almost as bad, is code-writing-code - of which you could argue, one example is a compiler. But some applications do create code from other code, this code generation is considered a more reasonable technique.

So it might be feasible even, to have an application which outputs source code for a new (modified) version of itself, feeds it into the compiler then chains that. However, it would be very weird :)

Mark
Quote: Original post by markr
[...]So it might be feasible even, to have an application which outputs source code for a new (modified) version of itself, feeds it into the compiler then chains that. However, it would be very weird :)[...]
That's called "reflection", and it's not weird at all. Also, self-modifying code isn't so bad in languages like Lisp, where code is data is code in a proper fashion. Of course, it's not the same as self-modifying machine code, but it does the same thing of modifying code (in place or not depending on the garbage collector etc) without having separate "generate code, compile, replace old code" steps.

The general term for this kind of thing is "metaprogramming", and it's done all the time with templates in C++, preprocessor statements in C, Common Lisp macros, etc.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Java programmers might play with self modifying executable code safely (most bad types of resulting source files, actually arrays, would return error code in compilation thus amount of crashes would be greatly reduced), at the cost of writing theirs own class loader.
Of course there are some isues, like what rights would have that self modified code.

This topic is closed to new replies.

Advertisement