Page 1 of 1

Simple list head rest split syntax

Posted: 30 Nov 2015 4:19
by kingchris
If I retrieve a string-list from a fact is there a simple syntax-sugar way to split it into the typical head
rest vars

Code: Select all

class facts     filename:(string,string,string,string,core::string_list).   clauses    somePred():-     filename(_._._,_,Name_Parts_Str),       [Head,Rest] := Name_Parts_Str, % this is wrong but you get the idea of the split


I do know that I could write a predicate to split the list and return Head & Rest by unification but I just wondered if it was possible.

Posted: 30 Nov 2015 9:39
by Thomas Linder Puls

Posted: 30 Nov 2015 17:04
by kingchris
For those of you who want the cliff notes. This worked for me

Code: Select all

class facts     filename:(string,string,string,string,core::string_list).   clauses    somePred():-     filename(CurrentName._._,_,Name_Parts_Str),       [Head,_Rest] = Name_Parts_Str,     console::write(CurrentName," ",Head),console::nl().

So simple when you know how.

Posted: 30 Nov 2015 19:12
by Vitaly Markov

Code: Select all

class facts     filename:(string,string,string,string,core::string_list).   clauses    somePred():-     filename(CurrentName,_,_,_,[Head|_]),     console::write(CurrentName," ",Head),console::nl().

Posted: 1 Dec 2015 4:39
by kingchris
True. That would work perfectly.
I just wanted to highlight for myself that lists could be split across the equals/assigment barrier :D

I recall copying some code a while back that did this but I misplaced the code and couldn't recall how to do it.

Sometimes for debugging purposes its easier to show intermediate steps.

Posted: 1 Dec 2015 7:10
by Peter Muraya
Kingchris,
Vitaly's method is the correct way to get the head of a list, if there is at least one member in it. Your method will work if and only if there are 2 elements in the list -- which I don't think is your intention.

Code: Select all

class facts     filename:(string,string,string,string,core::string_list).   clauses    somePred():-     filename(CurrentName,_,_,_,Name_Parts_Str), %I replaced the full stops with commas     [Head,_Rest] = Name_Parts_Str,  %This would work only if there are 2 elements in the list     console::write(CurrentName," ",Head),console::nl().

Posted: 1 Dec 2015 15:50
by kingchris
No. I disagree.

Code: Select all

        build_filename_db():-           dir(CurrentDir),           console::write("Processing Dir ",CurrentDir),console::nl(),           extension(CurrentSearchExtension),           CurrentFilename = directory::getFilesInDirectoryAndSub_nd(CurrentDir,CurrentSearchExtension),           %console::write("Found Filename ",CurrentFilename),console::nl(),           CurrentExtension = filename::getExtension(CurrentFilename),           CurrentPath = filename::getPath(CurrentFilename),           CurrentName = filename::getname(CurrentFilename),           CurrentNameUpper = string::toUpperCase(CurrentName),           %CurrentNameUpper = toUpperCase(CurrentName),           NameList00 = split(CurrentNameUpper," .[]-()_#"),           NameList = list::removeAll(NameList00,""),           assert_filename(CurrentFilename,CurrentPath,CurrentNameUpper,CurrentExtension,NameList),                   PathList = split(CurrentPath,"\\"),           [Head|ReversePathList] = list::reverse(PathList), % EXAMPLE 1           [Next|Rest] = ReversePathList,           console::write(Head,Rest,Next," ",ReversePathList,"\n"),           CurrentPathUpper = string::toUpperCase(CurrentPath),           PathNameList = split(string::toUpperCase(Next)," .[]-()_#"),           fail_if_equal_list(NameList,PathNameList),            assert_filename(CurrentPath,CurrentPath,CurrentPathUpper,CurrentExtension,PathNameList),           fail.    build_filename_db():-             !.
This is an actual working fragment of code that is dealing with lists of strings.

If you look at the line with EXAMPLE 1 as a comment. Head will contain a string and ReversePathList contains the list of remaining elements

So if I debug and halt my code in the second assert_filename line.

PathList = ["i:","usr","movies","Movies 1-99",""]
Head = ""
ReversePathList = ["Movies 1-99","movies","usr","i:"]

So it does seem to work as I expect.