term_to_atom/2 and atom_concat/3

View: New views
10 Messages — Rating Filter:   Alert me  

term_to_atom/2 and atom_concat/3

by Eva Stoewe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I have a question about term_to_atom/2 and atom_concat/3. I have written the following predicate. My intention is to build a file path when I only know some parts of the path and to put them together as needed:

combine_two_path_elements(First,Second,Combination):-
    term_to_atom(First,FirstAtom)
    term_to_atom(Second,SecondAtom)
    atom_concat(FirstAtom,'/',First_slash),
    atom_concat(First_slash,SecondAtom,Combination).
         
I expected to get an atom that starts with the first element, followed directly with a / and than the second element. My problem is that if the first element is already an atom (which is also a term so I thought that it would just stay as it was) it did something that I did not expect:

?- combine_two_path_elements('z:/workspacepdt/pdt.runtime',pif_observe,A).
A = '\'z:/workspacepdt/pdt.runtime\'/pif_observe'.

term_to_atom/2 catches the quotes of the first argument as you can see here:

?- term_to_atom('z:/workspacepdt/pdt.runtime',A), term_to_atom(pif_observe,B), atom_concat(A,'/',C), atom_concat(C,B,D).
A = '\'z:/workspacepdt/pdt.runtime\'',
B = pif_observe,
C = '\'z:/workspacepdt/pdt.runtime\'/',
D = '\'z:/workspacepdt/pdt.runtime\'/pif_observe'.

But when I do the following nothing is catched:

?- term_to_atom('atom',A), atom_concat(A,'/',B), atom_concat(B,'*',C).
A = atom,
B = 'atom/',
C = 'atom/*'.

?- term_to_atom('atom',A), atom_concat(A,'/',B), atom_concat(B,B,C).
A = atom,
B = 'atom/',
C = 'atom/atom/'.

?- term_to_atom('atom',A), atom_concat(A,'/',B), atom_concat(B,B,C), atom_concat(C,C,D).
A = atom,
B = 'atom/',
C = 'atom/atom/',
D = 'atom/atom/atom/atom/'.

I fixed it for me by only casting from a term to an atom if the term is not already an atom. But I do not understand when the catching occurs and when not, so I would be happy if someone could explain that to me.

Thanks and have a nice weekend,
   Eva Stöwe.
--
GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT!
Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01
_______________________________________________
SWI-Prolog mailing list
SWI-Prolog@...
https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog

Re: term_to_atom/2 and atom_concat/3

by Eckard Brauer-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello Eva,

could string_concat/3 be your friend?

If not sufficient, please explain a bit closer what you expect.

Cheers,
Eckard

Am Fri, 09 Oct 2009 20:46:21 +0200
schrieb "Eva Stöwe" <Katzazi@...>:

> Hi,
>
> I have a question about term_to_atom/2 and atom_concat/3. I have
> written the following predicate. My intention is to build a file path
> when I only know some parts of the path and to put them together as
> needed:
>
> combine_two_path_elements(First,Second,Combination):-
>     term_to_atom(First,FirstAtom)
>     term_to_atom(Second,SecondAtom)
>     atom_concat(FirstAtom,'/',First_slash),
>     atom_concat(First_slash,SecondAtom,Combination).
>
> I expected to get an atom that starts with the first element,
> followed directly with a / and than the second element. My problem is
> that if the first element is already an atom (which is also a term so
> I thought that it would just stay as it was) it did something that I
> did not expect:
>
> ?-
> combine_two_path_elements('z:/workspacepdt/pdt.runtime',pif_observe,A).
> A = '\'z:/workspacepdt/pdt.runtime\'/pif_observe'.
>
> term_to_atom/2 catches the quotes of the first argument as you can
> see here:
>
> ?- term_to_atom('z:/workspacepdt/pdt.runtime',A),
> term_to_atom(pif_observe,B), atom_concat(A,'/',C),
> atom_concat(C,B,D). A = '\'z:/workspacepdt/pdt.runtime\'', B =
> pif_observe, C = '\'z:/workspacepdt/pdt.runtime\'/',
> D = '\'z:/workspacepdt/pdt.runtime\'/pif_observe'.
>
> But when I do the following nothing is catched:
>
> ?- term_to_atom('atom',A), atom_concat(A,'/',B), atom_concat(B,'*',C).
> A = atom,
> B = 'atom/',
> C = 'atom/*'.
>
> ?- term_to_atom('atom',A), atom_concat(A,'/',B), atom_concat(B,B,C).
> A = atom,
> B = 'atom/',
> C = 'atom/atom/'.
>
> ?- term_to_atom('atom',A), atom_concat(A,'/',B), atom_concat(B,B,C),
> atom_concat(C,C,D). A = atom,
> B = 'atom/',
> C = 'atom/atom/',
> D = 'atom/atom/atom/atom/'.
>
> I fixed it for me by only casting from a term to an atom if the term
> is not already an atom. But I do not understand when the catching
> occurs and when not, so I would be happy if someone could explain
> that to me.
>
> Thanks and have a nice weekend,
>    Eva Stöwe.

--
Buffer overflow in BundTroj.exe: Can't send KeyLog. Exiting.


signature.asc (205 bytes) Download Attachment

RE: term_to_atom/2 and atom_concat/3

by Feliks Kluzniak-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I think it is easy to confuse differences in how the top-level presents the
values of the variables with differences in what you really get.  The top
level seems to use writeq/1.

For example,

?- X = atom.
X = atom

?- X = 'atom'.
X = atom

?- X = ' strange*'.
X = ' strange*'.

?- X = ' strange*',  write( 'result: ' ),  write( X ),  nl.
result:  strange*
X = ' strange*'

Now, term_to_atom/2, as used in this case, is supposed to behave as if
write/1 were used to produce the value of the atom.  But it behaves as if
writeq/1 were used instead:

?- term_to_atom( ' str/ange*', X ),  write( 'result: ' ),  write( X ),  nl.
result: ' str/ange*'
X = '\' str/ange*\''.

What happened was that the value that was "written" did not conform to the
syntax of a "normal" atom, so it got quoted, and the quotes are now a part
of the resulting atom.  Then the top level presents it by adding more quotes
and escapes to preserve the strange characters (including the quotes) in the
atom.

So term_to_atom/2 does not behave as specified, and you would be justified
in filing a bug report.


Does this answer your question?

Regards,
-- Feliks


-----Original Message-----
From: swi-prolog-admin@...
[mailto:swi-prolog-admin@...] On Behalf Of "Eva Stöwe"
Sent: Friday, October 09, 2009 1:46 PM
To: SWI-Prolog list
Subject: [SWIPL] term_to_atom/2 and atom_concat/3

Hi,

I have a question about term_to_atom/2 and atom_concat/3. I have written the
following predicate. My intention is to build a file path when I only know
some parts of the path and to put them together as needed:

combine_two_path_elements(First,Second,Combination):-
    term_to_atom(First,FirstAtom)
    term_to_atom(Second,SecondAtom)
    atom_concat(FirstAtom,'/',First_slash),
    atom_concat(First_slash,SecondAtom,Combination).
         
I expected to get an atom that starts with the first element, followed
directly with a / and than the second element. My problem is that if the
first element is already an atom (which is also a term so I thought that it
would just stay as it was) it did something that I did not expect:

?- combine_two_path_elements('z:/workspacepdt/pdt.runtime',pif_observe,A).
A = '\'z:/workspacepdt/pdt.runtime\'/pif_observe'.

term_to_atom/2 catches the quotes of the first argument as you can see here:

?- term_to_atom('z:/workspacepdt/pdt.runtime',A),
term_to_atom(pif_observe,B), atom_concat(A,'/',C), atom_concat(C,B,D).
A = '\'z:/workspacepdt/pdt.runtime\'',
B = pif_observe,
C = '\'z:/workspacepdt/pdt.runtime\'/',
D = '\'z:/workspacepdt/pdt.runtime\'/pif_observe'.

But when I do the following nothing is catched:

?- term_to_atom('atom',A), atom_concat(A,'/',B), atom_concat(B,'*',C).
A = atom,
B = 'atom/',
C = 'atom/*'.

?- term_to_atom('atom',A), atom_concat(A,'/',B), atom_concat(B,B,C).
A = atom,
B = 'atom/',
C = 'atom/atom/'.

?- term_to_atom('atom',A), atom_concat(A,'/',B), atom_concat(B,B,C),
atom_concat(C,C,D).
A = atom,
B = 'atom/',
C = 'atom/atom/',
D = 'atom/atom/atom/atom/'.

I fixed it for me by only casting from a term to an atom if the term is not
already an atom. But I do not understand when the catching occurs and when
not, so I would be happy if someone could explain that to me.

Thanks and have a nice weekend,
   Eva Stöwe.
--
GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT!
Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01
_______________________________________________
SWI-Prolog mailing list
SWI-Prolog@...
https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog

_______________________________________________
SWI-Prolog mailing list
SWI-Prolog@...
https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog

RE: term_to_atom/2 and atom_concat/3

by Jan Wielemaker-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Fri, 2009-10-09 at 17:19 -0500, Feliks Kluzniak wrote:

> Hi,
>
> I think it is easy to confuse differences in how the top-level presents the
> values of the variables with differences in what you really get.  The top
> level seems to use writeq/1.
>
> For example,
>
> ?- X = atom.
> X = atom
>
> ?- X = 'atom'.
> X = atom
>
> ?- X = ' strange*'.
> X = ' strange*'.
>
> ?- X = ' strange*',  write( 'result: ' ),  write( X ),  nl.
> result:  strange*
> X = ' strange*'
>
> Now, term_to_atom/2, as used in this case, is supposed to behave as if
> write/1 were used to produce the value of the atom.  But it behaves as if
> writeq/1 were used instead:
>
> ?- term_to_atom( ' str/ange*', X ),  write( 'result: ' ),  write( X ),  nl.
> result: ' str/ange*'
> X = '\' str/ange*\''.
>
> What happened was that the value that was "written" did not conform to the
> syntax of a "normal" atom, so it got quoted, and the quotes are now a part
> of the resulting atom.  Then the top level presents it by adding more quotes
> and escapes to preserve the strange characters (including the quotes) in the
> atom.
>
> So term_to_atom/2 does not behave as specified, and you would be justified
> in filing a bug report.

But the bug concerns the documentation rather than the implementation.
As far as I'm concerned, Prolog write/1 is a big mistake.  If you want
to write terms, you want them in a form they can be interpreted.  That
means they need to be quoted correctly (as in writeq/1).  If you want
to write text, you can use write with an atom, but format/1 is a much
more sensible way to emit text.

> Does this answer your question?

As least it helped me understanding the question by the original
poster :-)

     Cheers --- Jan



_______________________________________________
SWI-Prolog mailing list
SWI-Prolog@...
https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog

Re: term_to_atom/2 and atom_concat/3

by Kuniaki Mukai :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Jan,

On Oct 10, 2009, at 5:18 PM, Jan Wielemaker wrote:

> On Fri, 2009-10-09 at 17:19 -0500, Feliks Kluzniak wrote:
>> Hi,
>>
>> I think it is easy to confuse differences in how the top-level  
>> presents the
>> values of the variables with differences in what you really get.  
>> The top
>> level seems to use writeq/1.
>>
>> For example,
>>
>> ?- X = atom.
>> X = atom
>>
>> ?- X = 'atom'.
>> X = atom
>>
>> ?- X = ' strange*'.
>> X = ' strange*'.
>>
>> ?- X = ' strange*',  write( 'result: ' ),  write( X ),  nl.
>> result:  strange*
>> X = ' strange*'
>>
>> Now, term_to_atom/2, as used in this case, is supposed to behave as  
>> if
>> write/1 were used to produce the value of the atom.  But it behaves  
>> as if
>> writeq/1 were used instead:
>>
>> ?- term_to_atom( ' str/ange*', X ),  write( 'result: ' ),  write
>> ( X ),  nl.
>> result: ' str/ange*'
>> X = '\' str/ange*\''.
>>
>> What happened was that the value that was "written" did not conform  
>> to the
>> syntax of a "normal" atom, so it got quoted, and the quotes are now  
>> a part
>> of the resulting atom.  Then the top level presents it by adding  
>> more quotes
>> and escapes to preserve the strange characters (including the  
>> quotes) in the
>> atom.
>>
>> So term_to_atom/2 does not behave as specified, and you would be  
>> justified
>> in filing a bug report.
>
> But the bug concerns the documentation rather than the implementation.
> As far as I'm concerned, Prolog write/1 is a big mistake.  If you want
> to write terms, you want them in a form they can be interpreted.  That
> means they need to be quoted correctly (as in writeq/1).  If you want
> to write text, you can use write with an atom, but format/1 is a much
> more sensible way to emit text.


The behavior of term_to_atom/2 still seems not natural to me.

?- X = "ABC", atom_codes(Y, X),  term_to_atom(Y, Z),
        atom_codes(Z, U), length(X, X_len), length(U, U_len).
X = [65, 66, 67],
Y = 'ABC',
Z = '\'ABC\'',
U = [39, 65, 66, 67, 39],
X_len = 3,
U_len = 5.

The main reason why this seems not natural is that an atom is
a term by definition.  So it is natural for one to expect that
with Atom being  unified an atom,  term_to_atom(Atom, Y)
should  unify Y with Atom  so that Y==Atom holds afterward.

The second reason is that when one says that an atom
has a name, say '#$%', usually we take it without quotes, I believe.

Kuniaki


>
>> Does this answer your question?
>
> As least it helped me understanding the question by the original
> poster :-)
>
>     Cheers --- Jan
>
>
>
> _______________________________________________
> SWI-Prolog mailing list
> SWI-Prolog@...
> https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog

_______________________________________________
SWI-Prolog mailing list
SWI-Prolog@...
https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog

Re: term_to_atom/2 and atom_concat/3

by Jan Wielemaker-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, 2009-10-11 at 01:13 +0900, Kuniaki Mukai wrote:

> The behavior of term_to_atom/2 still seems not natural to me.
>
> ?- X = "ABC", atom_codes(Y, X),  term_to_atom(Y, Z),
>         atom_codes(Z, U), length(X, X_len), length(U, U_len).
> X = [65, 66, 67],
> Y = 'ABC',
> Z = '\'ABC\'',
> U = [39, 65, 66, 67, 39],
> X_len = 3,
> U_len = 5.
>
> The main reason why this seems not natural is that an atom is
> a term by definition.  So it is natural for one to expect that
> with Atom being  unified an atom,  term_to_atom(Atom, Y)
> should  unify Y with Atom  so that Y==Atom holds afterward.
>
> The second reason is that when one says that an atom
> has a name, say '#$%', usually we take it without quotes, I believe.

What is totally unclear to me is why you want to use term_to_atom/2.
Basically the predicate does read and write, so

        term_to_atom(Term, Atom),
        term_to_atom(T2, Atom),
        variant(Term, T2)

should be true.  In other words, Atom is not just any atom, but
an atom in valid Prolog syntax.  I see no sensible other definition.

If you want the unquoted output you get from the useless predicate
write/1, use

        format(atom(Atom), '~w', [Term])

Just about the only reason I can see to use that in your context
of filenames is to translate name/name2/name3 into an atom.  Be
careful with that.  It is way better to get the names in a list and
use atomic_list_concat(List, /, Atom).  That avoid all nasty
quoting, bracket and spacing issues associated with write(q).

     Cheers --- Jan

_______________________________________________
SWI-Prolog mailing list
SWI-Prolog@...
https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog

Re: term_to_atom/2 and atom_concat/3

by Günter Kniesel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Jan Wielemaker schrieb:

> On Sun, 2009-10-11 at 01:13 +0900, Kuniaki Mukai wrote:
>> The behavior of term_to_atom/2 still seems not natural to me.
>>
>> ?- X = "ABC", atom_codes(Y, X),  term_to_atom(Y, Z),
>>         atom_codes(Z, U), length(X, X_len), length(U, U_len).
>> X = [65, 66, 67],
>> Y = 'ABC',
>> Z = '\'ABC\'',
>> U = [39, 65, 66, 67, 39],
>> X_len = 3,
>> U_len = 5.
>>
>> The main reason why this seems not natural is that an atom is
>> a term by definition.  So it is natural for one to expect that
>> with Atom being  unified an atom,  term_to_atom(Atom, Y)
>> should  unify Y with Atom  so that Y==Atom holds afterward.
>>
>> The second reason is that when one says that an atom
>> has a name, say '#$%', usually we take it without quotes, I believe.
>
> What is totally unclear to me is why you want to use term_to_atom/2.
> Basically the predicate does read and write, so
>
> term_to_atom(Term, Atom),
> term_to_atom(T2, Atom),
> variant(Term, T2)
>
> should be true.  In other words, Atom is not just any atom, but
> an atom in valid Prolog syntax.  I see no sensible other definition.

The syntax and the internal representation of an atom are two different
issues. When I do term_to_atom(Term, Atom) I expect that the system
knows this is an atom and will treat it like an atom henceforth. For
instance, I expect that it will write quotes around teh atom when writing
is required.
However I do not expect that the *internal representation* of Atom includes
quotes. So if I concatenate two such atoms I do not expect quotes in the
middle of the resulting atom.

I think the unnatural behaviour pointed out by Eva, Feliks and Kuniaki
results from the implementation choice that you just described:
"Basically the predicate does read and write".

This shouldn't be the case since it mixes the internal representation
and the output format of atoms, which to me are still two different
concerns. Not that I could suggest a better implementation, lacking
deep knowledge of the SWI-Prolog iternals. But in any case, the
behaviour is inconsistent for a user, no matter how it looks from
an implementation point of view.

> Just about the only reason I can see to use that in your context
> of filenames is to translate name/name2/name3 into an atom.  

Yes. That is required because SWI-Prolog does not seem to turn
file names into atoms in the first place. Therefore, certain predicates
that need atoms throw exceptions on file names, which forced Eva to use
the term_to_atom conversion. The atoms created that way unfortunately
exhibited the anomaly that she reported. So Eva's scenario, is more
like:

start_of_all_problems :-
     parse_a_file,
     find_a_file_loading_directive_in_it(Directive),
     Directive =.. [_, FileParam],
     % <-- from here we get a name/name2/name3 that is NOT an atom
     % although we would have expected it to be 'name/name2/name3'
     term_to_atom(FileParam,FilePAtom),
     builtin_that_needs_an_atom(FilePAtom),
     predicate_that_contains_more_such_builtins(FilePAtom).

And then, somewhere deep in predicate_that_contains_more_such_builtins/1
it happens that its assumed atom paramter is concatenated giving
surprising results:

     atom_concat(FilePAtom,SecondAssumedAtom,Combination).

> It is way better to get the names in a list and
> use atomic_list_concat(List, /, Atom).  

That would be a good solution if the concatenation would not happen
long after term_to_atom had to be used.

Regards,
Güner
_______________________________________________
SWI-Prolog mailing list
SWI-Prolog@...
https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog

Re: term_to_atom/2 and atom_concat/3

by Jan Wielemaker-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, 2009-10-11 at 01:07 +0200, Günter Kniesel wrote:

> Jan Wielemaker schrieb:
> > On Sun, 2009-10-11 at 01:13 +0900, Kuniaki Mukai wrote:
> >> The behavior of term_to_atom/2 still seems not natural to me.
> >>
> >> ?- X = "ABC", atom_codes(Y, X),  term_to_atom(Y, Z),
> >>         atom_codes(Z, U), length(X, X_len), length(U, U_len).
> >> X = [65, 66, 67],
> >> Y = 'ABC',
> >> Z = '\'ABC\'',
> >> U = [39, 65, 66, 67, 39],
> >> X_len = 3,
> >> U_len = 5.
> >>
> >> The main reason why this seems not natural is that an atom is
> >> a term by definition.  So it is natural for one to expect that
> >> with Atom being  unified an atom,  term_to_atom(Atom, Y)
> >> should  unify Y with Atom  so that Y==Atom holds afterward.
> >>
> >> The second reason is that when one says that an atom
> >> has a name, say '#$%', usually we take it without quotes, I believe.
> >
> > What is totally unclear to me is why you want to use term_to_atom/2.
> > Basically the predicate does read and write, so
> >
> > term_to_atom(Term, Atom),
> > term_to_atom(T2, Atom),
> > variant(Term, T2)
> >
> > should be true.  In other words, Atom is not just any atom, but
> > an atom in valid Prolog syntax.  I see no sensible other definition.
>
> The syntax and the internal representation of an atom are two different
> issues. When I do term_to_atom(Term, Atom) I expect that the system
> knows this is an atom and will treat it like an atom henceforth. For
> instance, I expect that it will write quotes around teh atom when writing
> is required.
> However I do not expect that the *internal representation* of Atom includes
> quotes. So if I concatenate two such atoms I do not expect quotes in the
> middle of the resulting atom.

You mean as in here?

term_to_atom('ABC', X), term_to_atom('XYZ', Y), atom_concat(X,Y,Z)

> I think the unnatural behaviour pointed out by Eva, Feliks and Kuniaki
> results from the implementation choice that you just described:
> "Basically the predicate does read and write".
>
> This shouldn't be the case since it mixes the internal representation
> and the output format of atoms, which to me are still two different
> concerns. Not that I could suggest a better implementation, lacking
> deep knowledge of the SWI-Prolog iternals. But in any case, the
> behaviour is inconsistent for a user, no matter how it looks from
> an implementation point of view.

Passing atoms without quotes would violate the promise that the 2nd
argument isn't just an atom, but an atom holding valid Prolog
term-syntax.

> > Just about the only reason I can see to use that in your context
> > of filenames is to translate name/name2/name3 into an atom.  
>
> Yes. That is required because SWI-Prolog does not seem to turn
> file names into atoms in the first place. Therefore, certain predicates
> that need atoms throw exceptions on file names, which forced Eva to use
> the term_to_atom conversion. The atoms created that way unfortunately
> exhibited the anomaly that she reported. So Eva's scenario, is more
> like:
>
> start_of_all_problems :-
>      parse_a_file,
>      find_a_file_loading_directive_in_it(Directive),
>      Directive =.. [_, FileParam],
>      % <-- from here we get a name/name2/name3 that is NOT an atom
>      % although we would have expected it to be 'name/name2/name3'
>      term_to_atom(FileParam,FilePAtom),
>      builtin_that_needs_an_atom(FilePAtom),
>      predicate_that_contains_more_such_builtins(FilePAtom).

The argument to many file operations (such as use_module/1) is a term
that is valid for absolute_file_name/3.  So, if you need an atom, just
call this predicate and you get what you expect.  In particular:

        absolute_file_name(Spec, File, [type(prolog), access(read)])

will return an atom pointing to the file, doing all the nasty stuff
to find the file.  This is precisely what load_files/2 does.

> And then, somewhere deep in predicate_that_contains_more_such_builtins/1
> it happens that its assumed atom paramter is concatenated giving
> surprising results:
>
>      atom_concat(FilePAtom,SecondAssumedAtom,Combination).
>
> > It is way better to get the names in a list and
> > use atomic_list_concat(List, /, Atom).  
>
> That would be a good solution if the concatenation would not happen
> long after term_to_atom had to be used.

Using term_to_atom/2 in this context surely leads to problems ...


    Cheers --- Jan

_______________________________________________
SWI-Prolog mailing list
SWI-Prolog@...
https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog

Re: term_to_atom/2 and atom_concat/3

by Eva Stoewe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thank you for all the answers.

> On Sun, 11 Oct 2009 10:04:49 +0200 Jan Wielemaker wrote
> The argument to many file operations (such as use_module/1) is a term
> that is valid for absolute_file_name/3.  So, if you need an atom, just
> call this predicate and you get what you expect.  In particular:
>
> absolute_file_name(Spec, File, [type(prolog), access(read)])
>
> will return an atom pointing to the file, doing all the nasty stuff
> to find the file.  This is precisely what load_files/2 does.

I use absolute_file_name when possible. My problem is that I sometimes do not have the file_name but only a part of the path. The name of absolute_file_name and it's manual description brought me to the idea that it only works for files not for folders, but I will try to play around with it, later.

I want to describe my original situation some more. I want to build an own representation of the load-graph of a prolog project (which files load which files). I may have to be able to do this even when I cannot consult all the files so I cannot just ask swi about it. That is the case if there are two files with the same module names in the project.

To build the load graph I have to look at each consult/use_module/... that I find in the directives of the files. Many programmers do not use only relative file names but use file_search_path to point to the destination of the file to load. You can do this recursively like this:

:- assert(file_search_path(a, 'c:')).
:- assert(file_search_path(b, a('something')).
:- assert(file_search_path(c, b('somethingelse')).

If I now ask file_search_path about a key I do not get the whole path but only part of it. I tried to use absolute_file_name/3 directly but it does not give the path I search, if I use library(filename) as a first argument for absolute_file_name. (Or at least does not work if it is another key from file_search_path than library.)

Because of that I have to look up each key with file_search_path and compose it with the file-name manually.

>
> > And then, somewhere deep in predicate_that_contains_more_such_builtins/1
> > it happens that its assumed atom paramter is concatenated giving
> > surprising results:
> >
> >      atom_concat(FilePAtom,SecondAssumedAtom,Combination).
> >
> > > It is way better to get the names in a list and
> > > use atomic_list_concat(List, /, Atom).  
> >
> > That would be a good solution if the concatenation would not happen
> > long after term_to_atom had to be used.
>
> Using term_to_atom/2 in this context surely leads to problems ...

I just tried it with atomic_list_concat and got a likewise syntax error as I got with atom_concat, before. But maybe I forgot to change something else by the switch to atomic_list_concat. I will look into this tomorrow.

Cheers,
   Eva Stöwe.
--
GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT!
Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01
_______________________________________________
SWI-Prolog mailing list
SWI-Prolog@...
https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog

Re: term_to_atom/2 and atom_concat/3

by Jan Wielemaker-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, 2009-10-11 at 15:37 +0200, "Eva Stöwe" wrote:

> Thank you for all the answers.
>
> > On Sun, 11 Oct 2009 10:04:49 +0200 Jan Wielemaker wrote
> > The argument to many file operations (such as use_module/1) is a term
> > that is valid for absolute_file_name/3.  So, if you need an atom, just
> > call this predicate and you get what you expect.  In particular:
> >
> > absolute_file_name(Spec, File, [type(prolog), access(read)])
> >
> > will return an atom pointing to the file, doing all the nasty stuff
> > to find the file.  This is precisely what load_files/2 does.
>
> I use absolute_file_name when possible. My problem is that I sometimes do not have the file_name but only a part of the path. The name of absolute_file_name and it's manual description brought me to the idea that it only works for files not for folders, but I will try to play around with it, later.
>
> I want to describe my original situation some more. I want to build an own representation of the load-graph of a prolog project (which files load which files). I may have to be able to do this even when I cannot consult all the files so I cannot just ask swi about it. That is the case if there are two files with the same module names in the project.
>
> To build the load graph I have to look at each consult/use_module/... that I find in the directives of the files. Many programmers do not use only relative file names but use file_search_path to point to the destination of the file to load. You can do this recursively like this:
>
> :- assert(file_search_path(a, 'c:')).
> :- assert(file_search_path(b, a('something')).
> :- assert(file_search_path(c, b('somethingelse')).
>
> If I now ask file_search_path about a key I do not get the whole path but only part of it. I tried to use absolute_file_name/3 directly but it does not give the path I search, if I use library(filename) as a first argument for absolute_file_name. (Or at least does not work if it is another key from file_search_path than library.)
>
> Because of that I have to look up each key with file_search_path and compose it with the file-name manually.

User-supplied rules for file_search_path/2 can indeed complicate the
process.  If you do not want to update file_search_path/2 directly,
you would indeed have to emulate absolute_file_name/2.  Simplest
way is of course to look at its source :-)  It might be easier to
temporary assert the additional rules and call absolute_file_name/3
itself (do not forget the relative_to option).

Note that no matter how hard you try, you're not going to get this
foolproof.  There are many ways to add clauses for file_search_path/2.

This is one of the reasons why ?- gxref. works on the loaded program ...

    --- Jan



_______________________________________________
SWI-Prolog mailing list
SWI-Prolog@...
https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog