A.I. programming in Prolog and Assembler

May 8, 2009

Ultra-Fast Hybrid Genetic Algorithm in Assembly Language for the Travelling Salesman Problem (DLL for LPA Prolog)

UPDATE (8 Oct. 2009): new HD YouTube video about this project:

You can also watch a (slightly dated) slide-show about this algorithm here:

http://omadeon.com/tsp

I am currently using this algorithm’s DLL inside a large-scale Scheduling Application for Multiple Tasks, in LPA WIN-Prolog. Some screen-shots from the program’s main window are shown in the following animated GIF:

O.G.T.S.P. Algorithm sample screen-shots

O.G.T.S.P. Algorithm sample screen-shots

Enhanced by Zemanta
Advertisements

October 14, 2007

DreamProver: A visual theorem prover for “Multiple Form Logic” (etc.) in LPA Win-Prolog 4.6

Chart showing the stages in the software relea...Image via Wikipedia

Visual DreamProver 1.0 is a new theorem-proving program, developed in LPA Win-Prolog 4.6, with multi-coloured graphics displays of (potentially unlimited) Logic expressions, theorem proofs and deductions in Multiple Form Logic, in the primary algebra of “Laws of Form“, in Boolean Algebra and in a variety of other logic systems (to a large extent used-defined). Here is an animated GIF slide-show of DreamProver’s visual display. It offers unlimited control of size, colour, shape and content for all Logic Expressions and all theorem proofs:

dreamprover430x.gif

(Click on this image for a better quality animated GIF, of size 450Kb)

Although DreamProver is still at the “alpha stage“, I decided to publish a preliminary first report about its features and capabilities, to a large extent already working, to a lesser extent requiring minor debugging and final extensions, before release. I am also doing this for the benefit (and amusement) of a friendly innovative company: “Logic Programming Associates Ltd”, where I worked for a short pleasant period of a few weeks, some years ago (in 2001). LPA are the creators of the LPA Win-Prolog compiler. I hope that LPA continues a long tradition of innovative success through the latest version of their compiler, which also has MIDI (music) programming capabilities (featured in a recent posting, here).

I am also… officially requesting, after the release of DreamProver (and the ensuing free promotion of LPA’s amazing compiler) a small… personal favour: -A legitimate free copy of their newest LPA Win-Prolog 4.7 compiler! 🙂 (as my license for using version 4.6 ends on the last day of 2007).

DreamProver is particularly suited for the display of so-called “Boundary Logic Systems” (first created by George Spencer Brown in “Laws of Form” and then extended by various people in various ways – including my own “Multiple Form Logic” system). However, its (almost unlimited) potential allows the display of many other logic systems, including Parse-Trees of used-defined grammars, since both the shapes and the data-structures they represent can be redefined “on the fly”. In the display shown above, only a small example of a logic expression is used, mainly to demonstrate graphics capabilities. However, if -for example- the Grammar of a subset of English is used, instead of a Logic Expression, the ensuing graphic display of coloured shapes resembles a tree which is symmetric with respect to a “horizon” line in the middle.

The data-structure for this unusual kind of tree-representation is relatively simple, straight-forward and documented (in the final release of DreamProver). It is separate from the internal Logic representation but related to it through specific user-defined rules: Both the “productions” and the “leaves” of such a grammar tree are user-defined in shape and content. The only difference between other kinds of systems and those built-in (as regards the current first version of DreamProver) is that the other systems do not include internal Proof Algorithms and automated deductions, and can only be fed from the results of such processes (through external third-party software). Before final release it is hoped that the input-expressions in other systems are expressed in standard XML, so as to make the software useful to almost any researcher or developer, in any topic that includes parsed tree-expressions. The ultimate goal is also to develop a kind of Universal DreamProver library, available under a professional license to developers for a small fee (that might help sustain this work and pay for the effort of future upgrades). However, the current version of DreamProver is likely to appear as Open Source in the near future. Keep in touch!

Zemanta Pixie

September 27, 2007

reading/writing/sorting Prolog variables, using the original variable-names (LPA Prolog code)

Filed under: LPA Win-Prolog, Prolog, source code — Omadeon @ 2:17 pm

Typically, Prolog variables are assigned by the compiler “internal names”, so that it is impossible to sort them using their original names (those provided by the user or by an input file).

However, in LPA Win-Prolog it is possible to preserve the original variable names, as well as sort them on the basis of these names. Finally it is also possible to retrieve the variables with their original names. Some examples follow:

1) LPA Prolog has predicates handling variable names (eread/2 and eprint/2). E.g. if you want Prolog to read a term with variables, preserving user-given variable names and then printing them out, you can use code like this:

| ?- eread(EXP,Vars), nl, eprint(EXP,Vars), nl, nl, nl.
|: this(THING,V,X,W).
this(THING,V,X,W)
EXP = this(_38218,_38220,_38226,_38232) ,
Vars = [('THING',_38218),('V',_38220),('X',_38226),('W',_38232)]
| ?-  

In LPA Prolog, eread/2 reads a term with variables and the it produces a list of names-and-variables [(Name,Var)|…] as a second argument. This has elements like (‘THING’,_38218) -in this example- where ‘THING’ is the user-defined variable name and _38218 is an “internal variable code”, generated by the compiler. The second predicate eprint/2 is similar: If the second argument of eprint/2 is bound to the names-and-variables-list (extracted previously) then the result is a printout of the expression as it was originally entered, preserving all the user-defined variable names.

Now, here is another example, only slightly more complicated. This time, it uses a small source-code file, which you can create easily, by copying and pasting the code that follows into a text file (of extension ‘.pl’).

The program asks the user to type a list (consisting of variables and constants) and then it is required to sort the variables, finally printing-out the resulting list with Variables sorted, but with names exactly the same as those typed originally. So, here is a piece of code that reads such a list from a user-prompt, sorts the list with respect to its variables, and then prints out the resulting list, with all the variables sorted:

test:- repeat, write('type a list of variables and constants:'), nl,
    eread(List,VL), sort(VL,VLsorted), sort(List,List1), varsort(List1,VLsorted,ListOut),
    write('sorted w.r.t. variables: '), eprint(ListOut,VL), nl, 
    write('press escape to exit, any other key to go on: '), get0(CHAR), CHAR = -1, !.
removevar(V,[A|L],L):- V == A, !.
removevar(V,[A|L],[A|Lx]):- removevar(V,L,Lx).

varsort([],_,[]):- !.
varsort(L,[],L):- !.
varsort(L,[(_Name,V)|VL],[V|XL]):-  removevar(V,L,L2), !, varsort(L2,[(_,V)|VL],XL).
varsort(L,[_|VL],XL):- !, varsort(L,VL,XL).

This piece of code is complete; you can copy it, paste it to a file ando compile it in LPA Win-Prolog. After doing this, type ‘test’ at the Prolog prompt. You will get a dialogue such as this:

| ?- test1.
type a list of variables and constants:
|: [A,D,C,2,B,34,X,F,D].
sorted w.r.t. variables: [A,B,C,D,F,X,2,34]
press escape to exit, any other key to go on: |:
yes
| ?-

The main predicate ‘test’ calls ‘eread/2’, which reads user- (or file-) input expressions and parses them into Prolog terms with variables. Then the variable-name-list is sorted. The original list is also sorted, and then the sorted variable names’ list is used to rearrange the sorted original list a second time, this time sorting it as regards variable names.

A very crucial predicate here is ‘removevar/3’, which is similar to the built-in predicate ‘remove/3’, removing an element of a list and producing the list without this element each time it’s called. However, unlike the built-in predicate ‘remove/3’, this one only deletes list-elements which are “identical to the first argument”, without doing any unification. I.e. it is capable of removing variables, if they exist in the list (of arg 2) but does not confuse them with other variables through unification.

Another new predicate in the code above is ‘ varsort’. It assumes that arg-1 contains an input-list (a mixture of variables and constants) and it makes use of the sorted list of variable names, to rearrange the list so that all the variable names are sorted, in the third (output-)argument:

[A,D,C,2,B,34,X,F,D] becomes [A,B,C,D,F,X,2,34] .

As an exercise, if you have some Prolog experience you can now try to write a similar piece of code that works on ANY kind of Prolog term, not just a list. If you do write such code, you can also send it as a comment in this posting, or an e-mail to omadeon@hotmail.com (with your name and any other details you’d like to see included), and I will publish it in this blog (with your name or alias) exactly as you’ve written it (provided of course that… it works 🙂 )!

September 22, 2007

LPA Win-Prolog: A professional Prolog compiler with unique features

In early 2001, I had the pleasure of working closely together with a friendly bunch of people, the creators of LPA Win-Prolog, for a a period of a few months: This company, who made LPA Win-Prolog is “Logic Programming Associates“, a group of dedicated developers and computer scientists led by Brian Steel, who also happens to be a musician and an orchestra conductor. A long time ago (in the eighties) Brian Steel had caused quite a stir in the so-called “home computer” industry, by writing the first Prolog compiler that could run on a ZX Spectrum, a machine with only 48Kb of RAM and a Z80 8-bit processor. At that embryonic stage of the computer industry’s evolution, it was considered impossible to cram a working Prolog compiler in only so little RAM and in such a slow computer. However, Brian Steel was also an Assembly Language programmer (just like me -although long before my time). He still writes very efficient Assembly Language code (today for Intel Pentiums – 32-bit and 64-bit code) which empowers today’s LPA compiler with a tremendous speed, compared to its rivals. Brian also thought deeply about the best way to implement certain commonly needed operations (such as string search) and so he set out to improve the ISO-prolog-compatible LPA compiler with special and unique instructions that increase its speed and efficiency even more (e.g. the multi-faceted predicate “find/3“).

Well, I am still using LPA Win-Prolog, ever since that happy period of a few months I spent in the UK, back in 2001, as an employee of LPA Ltd. In fact, I was forced to return to Greece because of a bad accident (a broken tendon in a foot), otherwise I’d rather stay in the UK and work with LPA… forever! BTW, Brian Steel is also -like me- a winter swimmer, in the English sea (in Cornwall) making it even more apealling for me -at the time- to… follow his example. 🙂

The latest versions of LPA Prolog (version 4.6 is the one I use at the moment) are full of extra goodies, such as a coloured syntax editor, a nice dialog editor (for the visual design of menus, windows, dialog boxes, etc), and so on. (Not to mention several good extra packages, included in the compiler, such as Flex, Datamite, Proweb, Chimaira Agents, and so on; you can read all about them in LPA Prolog’s site, here).

My only complaint is that (at the moment) the LPA package does not include a Constraints programming extension, (such as CLP, CLP/fd, CHR, etc). However, I plan to adapt some open source code for such extensions and include it inside LPA Prolog, in the near future. Unless -of course- this innovative company has already embarked on a similar project, adding to their compiler Constraints handling extensions. Finally, the very latest (recently announced) next version of LPA Prolog includes something very special, which is useful to musically inclined programmers and hobbyists: A midi interface!

I was probably among those people who first proposed to Brian Steel -back in 2001- that a midi interface would prove to be very popular, as well as a way to expand LPA’s customer base even further. At the time (2001), most of their customers were academics, universities and serious professional people. Today (2007) my guess is that their clients begin to be also musically oriented hobbyists and computer-literate composers. I -for one- (as a composer and remixer) can’t wait to get my hands on this new version of their compiler, since it’s the best way to experiment with L-systems for computer music generation, Prolog-based grammars for parsing and analysing existing MIDI music pieces, and so on.

However, now that the MIDI music Logic Programming client-base of LPA Prolog is beginniing to grow, the issue of Constraints extensions can no longer be neglected. Some of the best work in musical Artificial Intelligence is already using Constraints programming methods.

In this blog, I hope to write quite often about programming projects and experiments with LPA Win-Prolog, including my own (public domain) source-code. In addition, you can browse some professional projects implemented with LPA Prolog in recent years (2001-2005), in my source-code and programming projects’ page.

Finally, there are some rather unusual web-pages I wrote a few years ago, with tips and free code to combine LPA Win-Prolog, with… one of its rivals (PDC/Visual Prolog). At the time, it became evident that it was perfectly possible to combine the best features of both these professional compilers, so the title of the main web-page about this work was “A tale of Two Prologs“.

September 20, 2007

Bridging gaps between Prologs (SWI-Prolog predicates implented in LPA Win-Prolog)

Filed under: Code Conversion, LPA Win-Prolog, Prolog, source code, SWI-Prolog — Omadeon @ 4:36 pm

Today I spent too much time trying to force a SWI-Prolog project (of timetable scheduling, custom-made for a specific company) to run in a different compiler: LPA Win-Prolog. I needed badly to use certain graphics routines and other goodies of LPA Prolog (a commercial compiler), entire volumes of them in fact. So, I ended up writing code in LPA Prolog that implements some quite common SWI-Prolog predicates. Here are some of them:

The SWI-Prolog predicate ‘between/3’ generates (non-deterministically) a number, ranging from a minimum value to a maximum Value (as ‘bound’ 1st and 2nd arguments). I.e., in the SWI-Prolog console:

?- between(1,3,X).
X = 1 ;
X = 2 ;
X = 3 ;

Well, here is an LPA Win-Prolog implementation of this predicate (also valid in any other ISO-compatible Prolog):

between(Min,_,Min).
between(Min,Max,Out):- M2 is Min+1, M2 =< Max, between(M2,Max,Out).

OK, This was an easy example, while most probably the same code already exists in elementary Prolog textbooks. Here are some other (not-so-obvious) examples:

In LPA Prolog there are some very special, very efficient unique commands, like ‘find/3, which operates on ‘input streams’ to locate (sub-)strings inside them. Now, the so-called ‘input stream’ can itself (effectively) be just another string (turned into a stream through the special LPA command ‘<~’). The use of this predicate, ‘find/3’ to write quickly efficient code for non-deterministic search (of substrings inside larger strings) is a natural happy consequence. E.g.

findsubs(SubSTR,STR,Px):- len(SubSTR,Len), findrep(SubSTR,Len,Px) <~ STR.

findrep(_,Len,Px):- inpos(EndP), EndP > 0, Px is EndP-Len.
findrep(SubSTR,Len,Px):- find(SubSTR,0,Sx), +Sx=``, findrep(SubSTR,Len,Px). 

I wrote this code after understanding the (well-documented) similar non-deterministic predicate ‘replace’ (not a built-in command but given as simple source-code in LPA-Prolog’s Reference Quide, page 226). The reason I wrote it is because I needed it as a sub-predicate to implement of SWI-Prolog‘s superb predicate ‘sub_atom‘. (This was already used -alas in several places- inside the SWI-Prolog project, which was to be converted into LPA WIn-Prolοg).So, here is the resulting LPA-Prolog implementation of ‘sub_atom‘, valid for (almost) all possible flow-patterns (at least those used in my project, plus a few more):

/*********************************************************************************************
(a description of sub_atom/5 from SWI-Prolog's Open Source documentation):
sub atom(+Atom, ?Before, ?Len, ?After, ?Sub)
    ISO predicate for breaking atoms. It maintains the following relation: Sub is a sub-atom of Atom
    that starts at Before, has Len characters and Atom contains After characters after the match.
?- sub_atom(abc, 1, 1, A, S).
 A = 1, S = b
   The implementation minimises non-determinism and creation of atoms. This is a very flexible
   predicate that can do search, prefix- and suffix-matching, etc.
**********************************************************************************************/
% HERE is my LPA Win-Prolog (exact) implementation of 'sub_atom/5':
%%%%%%%%%% (also valid in most other ISO-ish Prologs) %%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (i,i,i,o,o)
sub_atom(Atom,Start,Len,LenAfterX,SubX):-
   nonvar(Atom), nonvar(Start), nonvar(Len), var(LenAfterX), var(SubX),
   cat(Lx,Atom,[Start,Len]), Lx = [_,SubX,End], len(End,LenAfterX).
% (i,o,i,i,o)
sub_atom(Atom,Start,Len,LenAfter,SubX):-
   nonvar(Atom), nonvar(Len), nonvar(LenAfter), var(Start), var(SubX),
   len(Atom,LenTotal), Start is LenTotal - LenAfter - Len,
   cat(Lx,Atom,[Start,Len]), Lx = [_,SubX,_].
% (i,o,o,o,i)  (effectively a non-deterministic search-function)
sub_atom(Atom,Startx,SubLenx,LenAfterX,Sub):-
   nonvar(Atom), nonvar(Sub), var(SubLenx), var(LenAfterx), var(Startx),
   len(Sub,SubLenx),  atom_string(Atom,STR), atom_string(Sub,SubSTR), len(STR,Slen),
   findrep(SubSTR,SubLenx,Startx) <~ STR, LenAfterX is Slen-Startx-SubLenx.
% where 'findrep/3' was written previously as a part of 'findsubs' (top of this post).
%(i,i,o,o,o)
sub_atom(Atom,Start,Len,LenAfterX,SubX):-
   nonvar(Atom), nonvar(Start), var(Len), var(LenAfterX), var(SubX),
  cat(Lx,Atom,[Start]), Lx = [_,End], len(End,Len2),
  between(0,Len2,Lenx), cat(Lxx,End,[Lenx]),
  Lxx = [SubX,End2], len(End2,LenAfterX), Len=Lenx.
%(i,o,o,o,o)
sub_atom(Atom,Start,Len,LenAfterX,SubX):-
   nonvar(Atom), var(Start), var(Len), var(LenAfterX), var(SubX),
   len(Atom,Len1), between(0,Len1,Pos),
  cat(Lx,Atom,[Pos]), Lx = [_,End], len(End,Len2),
  between(0,Len2,Lenx), cat(Lxx,End,[Lenx]),
  Lxx = [SubX,End2], len(End2,LenAfterX), Len=Lenx, Start=Pos.
%(i,o,i,o,o)
sub_atom(Atom,Start,Len,LenAfterX,SubX):-
   nonvar(Atom), var(Start), nonvar(Len), var(LenAfterX), var(SubX),
   len(Atom,Len1), LenPre is Len1-Len, between(0,LenPre,Pos),
  cat(Lx,Atom,[Pos,Len]), Lx = [_,Mid,End],
  SubX = Mid, LenAfterX is Len1-Pos-Len, Start=Pos.

%%%%%%%%%% (end of code) %%%%%%%%

Well, that’s it, for the moment, I’m afraid.

I must go back to my project now, but (rest assured) I will be coming back here, soon, again and again, and again…

Create a free website or blog at WordPress.com.