• Re: Towards OS Polyglott Prolog Systems

    From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue May 24 03:22:34 2022
    Here comes last_sub_atom/5 to the rescue. The proposal is simple.
    sub_atom/5 search forward, last_sub_atom/5 searches backward:

    Here from ISO core standard:

    ?- sub_atom('baaab', X, Y, Z, 'aa').
    X = 1, Y = 2, Z = 2;
    X = 2, Y = 2, Z = 1;
    fail.

    ?- sub_atom('abracadabra', X, Y, Z, 'abra').
    X = 0, Y = 4, Z = 7;
    X = 7, Y = 4, Z = 0.

    And here the analogue searching backward:

    ?- last_sub_atom('baaab', X, Y, Z, 'aa').
    X = 2, Y = 2, Z = 1;
    X = 1, Y = 2, Z = 2;
    fail.

    ?- last_sub_atom('abracadabra', X, Y, Z, 'abra').
    X = 7, Y = 4, Z = 0;
    X = 0, Y = 4, Z = 7.

    I introduced this some years ago in formerly Jekejeke Prolog.
    And since this week its also available in Dogelog Player.

    Mostowski Collapse schrieb am Dienstag, 24. Mai 2022 um 12:19:25 UTC+2:
    I noticed that in my new Dogelog Player the absolute_file_name/2
    predicate might either return one of the two:

    /* WSL */
    ?- absolute_file_name('baz.p', X).
    X = '/mnt/c/foo/bar/baz.p'

    /* Windows 10 */
    ?- absolute_file_name('baz.p', X).
    X = 'C:\\foo\\bar\\baz.p'

    So what to do? Normalize it and always use '/' and eliminate '\\' ?
    This is what I did for formerly Jekejeke Prolog.

    How do everything 100% in Prolog?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to All on Tue May 24 03:19:24 2022
    I noticed that in my new Dogelog Player the absolute_file_name/2
    predicate might either return one of the two:

    /* WSL */
    ?- absolute_file_name('baz.p', X).
    X = '/mnt/c/foo/bar/baz.p'

    /* Windows 10 */
    ?- absolute_file_name('baz.p', X).
    X = 'C:\\foo\\bar\\baz.p'

    So what to do? Normalize it and always use '/' and eliminate '\\' ?
    This is what I did for formerly Jekejeke Prolog.

    How do everything 100% in Prolog?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue May 24 12:43:47 2022
    Here are some example runs:

    ?- sys_file_parent('/mnt/c/foo/bar/baz.p', X).
    X = '/mnt/c/foo/bar/'.

    ?- sys_file_name('C:/foo/bar/baz.p', X).
    X = 'baz.p'.

    ?- sys_file_parent('C:\\foo\\bar\\baz.p', X).
    X = 'C:\\foo\\bar\\'.

    ?- sys_file_name('C:\\foo\\bar\\baz.p', X).
    X = 'baz.p'.

    Its not the same as decompose_file_name/3 from Logtalk,
    which is possibly also not OS polyglott. Its not the same
    since it leaves the directory delemiter, either '/' or '\\'

    at the end of the parent intact. So the reverse function
    of this decomposition is simply atom_concat/3:

    ?- atom_concat('/mnt/c/foo/bar/', 'baz.p', X).
    X = '/mnt/c/foo/bar/baz.p'.

    ?- atom_concat('C:\\foo\\bar\\', 'baz.p', X).
    X = 'C:\\foo\\bar\\baz.p'.

    Mostowski Collapse schrieb:
    Here is a use case for last_sub_atom/5. Its useful to make an OS polyglott Prolog system, at least polyglott among Unix, Windows and Mac. You
    can get rid of Logtalks internal_os_path/2, which I think is a little

    design flaw in my old Prolog system, which my new Prolog system tries
    to avoid. One can do the following like here, maybe there are also other agorithms based on last_sub_atom/5, but this is easiest to understand:

    sys_file_parent(Path, Dir) :-
    (last_sub_atom(Path, Pos1, _, _, '/') -> true; Pos1 = -1),
    (last_sub_atom(Path, Pos2, _, _, '\\') -> true; Pos2 = -1),
    Pos is max(Pos1, Pos2), Pos \== -1, !,
    Pos3 is Pos+1,
    sub_atom(Path, 0, Pos3, _, Dir).
    sys_file_parent(_, '').

    sys_file_name(Path, Name) :-
    (last_sub_atom(Path, Pos1, _, _, '/') -> true; Pos1 = -1),
    (last_sub_atom(Path, Pos2, _, _, '\\') -> true; Pos2 = -1),
    Pos is max(Pos1, Pos2), Pos \== -1, !,
    Pos3 is Pos+1,
    atom_length(Path, Len),
    Len2 is Len-Pos3,
    sub_atom(Path, Pos3, Len2, _, Name).
    sys_file_name(Path, Path).

    Maybe regex could do the same. But can regex search backwards?
    You would need a kind of greedy regex pattern, that nevertheless
    has an alternative in it. And a regex library is more heavier, than some

    last_sub_atom/5 which is still relative lightweight to provide, only
    a variant of sub_atom/5.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue May 24 03:27:16 2022
    Here is a use case for last_sub_atom/5. Its useful to make an OS polyglott Prolog system, at least polyglott among Unix, Windows and Mac. You
    can get rid of Logtalks internal_os_path/2, which I think is a little

    design flaw in my old Prolog system, which my new Prolog system tries
    to avoid. One can do the following like here, maybe there are also other agorithms based on last_sub_atom/5, but this is easiest to understand:

    sys_file_parent(Path, Dir) :-
    (last_sub_atom(Path, Pos1, _, _, '/') -> true; Pos1 = -1),
    (last_sub_atom(Path, Pos2, _, _, '\\') -> true; Pos2 = -1),
    Pos is max(Pos1, Pos2), Pos \== -1, !,
    Pos3 is Pos+1,
    sub_atom(Path, 0, Pos3, _, Dir).
    sys_file_parent(_, '').

    sys_file_name(Path, Name) :-
    (last_sub_atom(Path, Pos1, _, _, '/') -> true; Pos1 = -1),
    (last_sub_atom(Path, Pos2, _, _, '\\') -> true; Pos2 = -1),
    Pos is max(Pos1, Pos2), Pos \== -1, !,
    Pos3 is Pos+1,
    atom_length(Path, Len),
    Len2 is Len-Pos3,
    sub_atom(Path, Pos3, Len2, _, Name).
    sys_file_name(Path, Path).

    Maybe regex could do the same. But can regex search backwards?
    You would need a kind of greedy regex pattern, that nevertheless
    has an alternative in it. And a regex library is more heavier, than some

    last_sub_atom/5 which is still relative lightweight to provide, only
    a variant of sub_atom/5.

    Mostowski Collapse schrieb am Dienstag, 24. Mai 2022 um 12:22:35 UTC+2:
    Here comes last_sub_atom/5 to the rescue. The proposal is simple.
    sub_atom/5 search forward, last_sub_atom/5 searches backward:

    Here from ISO core standard:

    ?- sub_atom('baaab', X, Y, Z, 'aa').
    X = 1, Y = 2, Z = 2;
    X = 2, Y = 2, Z = 1;
    fail.

    ?- sub_atom('abracadabra', X, Y, Z, 'abra').
    X = 0, Y = 4, Z = 7;
    X = 7, Y = 4, Z = 0.

    And here the analogue searching backward:

    ?- last_sub_atom('baaab', X, Y, Z, 'aa').
    X = 2, Y = 2, Z = 1;
    X = 1, Y = 2, Z = 2;
    fail.

    ?- last_sub_atom('abracadabra', X, Y, Z, 'abra').
    X = 7, Y = 4, Z = 0;
    X = 0, Y = 4, Z = 7.

    I introduced this some years ago in formerly Jekejeke Prolog.
    And since this week its also available in Dogelog Player.
    Mostowski Collapse schrieb am Dienstag, 24. Mai 2022 um 12:19:25 UTC+2:
    I noticed that in my new Dogelog Player the absolute_file_name/2
    predicate might either return one of the two:

    /* WSL */
    ?- absolute_file_name('baz.p', X).
    X = '/mnt/c/foo/bar/baz.p'

    /* Windows 10 */
    ?- absolute_file_name('baz.p', X).
    X = 'C:\\foo\\bar\\baz.p'

    So what to do? Normalize it and always use '/' and eliminate '\\' ?
    This is what I did for formerly Jekejeke Prolog.

    How do everything 100% in Prolog?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Aleksy Grabowski@21:1/5 to Mostowski Collapse on Tue May 24 21:35:39 2022
    Hello,

    Why you didn't decide to use more classic dirname and basename? Meaning would've been immediately obvious for any experienced programmer.

    Best Regards,
    Alex

    On 5/24/22 12:43, Mostowski Collapse wrote:
    Here are some example runs:

    ?- sys_file_parent('/mnt/c/foo/bar/baz.p', X).
    X = '/mnt/c/foo/bar/'.

    ?- sys_file_name('C:/foo/bar/baz.p', X).
    X = 'baz.p'.

    ?- sys_file_parent('C:\\foo\\bar\\baz.p', X).
    X = 'C:\\foo\\bar\\'.

    ?- sys_file_name('C:\\foo\\bar\\baz.p', X).
    X = 'baz.p'.

    Its not the same as decompose_file_name/3 from Logtalk,
    which is possibly also not OS polyglott. Its not the same
    since it leaves the directory delemiter, either '/' or '\\'

    at the end of the parent intact. So the reverse function
    of this decomposition is simply atom_concat/3:

    ?- atom_concat('/mnt/c/foo/bar/', 'baz.p', X).
    X = '/mnt/c/foo/bar/baz.p'.

    ?- atom_concat('C:\\foo\\bar\\', 'baz.p', X).
    X = 'C:\\foo\\bar\\baz.p'.

    Mostowski Collapse schrieb:
    Here is a use case for last_sub_atom/5. Its useful to make an OS
    polyglott
    Prolog system, at least polyglott among Unix, Windows and Mac. You
    can get rid of Logtalks internal_os_path/2, which I think is a little

    design flaw in my old Prolog system, which my new Prolog system tries
    to avoid. One can do the following like here, maybe there are also other
    agorithms based on last_sub_atom/5, but this is easiest to understand:

    sys_file_parent(Path, Dir) :-
        (last_sub_atom(Path, Pos1, _, _, '/') -> true; Pos1 = -1),
        (last_sub_atom(Path, Pos2, _, _, '\\') -> true; Pos2 = -1),
        Pos is max(Pos1, Pos2), Pos \== -1, !,
        Pos3 is Pos+1,
        sub_atom(Path, 0, Pos3, _, Dir).
    sys_file_parent(_, '').

    sys_file_name(Path, Name) :-
        (last_sub_atom(Path, Pos1, _, _, '/') -> true; Pos1 = -1),
        (last_sub_atom(Path, Pos2, _, _, '\\') -> true; Pos2 = -1),
        Pos is max(Pos1, Pos2), Pos \== -1, !,
        Pos3 is Pos+1,
        atom_length(Path, Len),
        Len2 is Len-Pos3,
        sub_atom(Path, Pos3, Len2, _, Name).
    sys_file_name(Path, Path).

    Maybe regex could do the same. But can regex search backwards?
    You would need a kind of greedy regex pattern, that nevertheless
    has an alternative in it. And a regex library is more heavier, than some

    last_sub_atom/5 which is still relative lightweight to provide, only
    a variant of sub_atom/5.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Aleksy Grabowski on Wed May 25 23:29:57 2022
    Its different from dirname. The predicate sys_file_parent/2
    gives a slashified directory:

    ?- sys_file_parent('/mnt/c/foo/bar/baz.p', X).
    X = '/mnt/c/foo/bar/'.

    Whareas the usual dirname would give it without slash.

    ?- file_directory_name('/mnt/c/foo/bar/baz.p', X).
    X = '/mnt/c/foo/bar'.

    file_directory_name/2 exits already in SWI-Prolog. But
    it is not OS Polyglott:

    ?- file_directory_name('C:\\foo\\bar\\baz.p', X).
    X = ('.').

    Aleksy Grabowski schrieb:
    Hello,

    Why you didn't decide to use more classic dirname and basename? Meaning would've been immediately obvious for any experienced programmer.

    Best Regards,
    Alex

    On 5/24/22 12:43, Mostowski Collapse wrote:
    Here are some example runs:

    ?- sys_file_parent('/mnt/c/foo/bar/baz.p', X).
    X = '/mnt/c/foo/bar/'.

    ?- sys_file_name('C:/foo/bar/baz.p', X).
    X = 'baz.p'.

    ?- sys_file_parent('C:\\foo\\bar\\baz.p', X).
    X = 'C:\\foo\\bar\\'.

    ?- sys_file_name('C:\\foo\\bar\\baz.p', X).
    X = 'baz.p'.

    Its not the same as decompose_file_name/3 from Logtalk,
    which is possibly also not OS polyglott. Its not the same
    since it leaves the directory delemiter, either '/' or '\\'

    at the end of the parent intact. So the reverse function
    of this decomposition is simply atom_concat/3:

    ?- atom_concat('/mnt/c/foo/bar/', 'baz.p', X).
    X = '/mnt/c/foo/bar/baz.p'.

    ?- atom_concat('C:\\foo\\bar\\', 'baz.p', X).
    X = 'C:\\foo\\bar\\baz.p'.

    Mostowski Collapse schrieb:
    Here is a use case for last_sub_atom/5. Its useful to make an OS
    polyglott
    Prolog system, at least polyglott among Unix, Windows and Mac. You
    can get rid of Logtalks internal_os_path/2, which I think is a little

    design flaw in my old Prolog system, which my new Prolog system tries
    to avoid. One can do the following like here, maybe there are also other >>> agorithms based on last_sub_atom/5, but this is easiest to understand:

    sys_file_parent(Path, Dir) :-
        (last_sub_atom(Path, Pos1, _, _, '/') -> true; Pos1 = -1),
        (last_sub_atom(Path, Pos2, _, _, '\\') -> true; Pos2 = -1),
        Pos is max(Pos1, Pos2), Pos \== -1, !,
        Pos3 is Pos+1,
        sub_atom(Path, 0, Pos3, _, Dir).
    sys_file_parent(_, '').

    sys_file_name(Path, Name) :-
        (last_sub_atom(Path, Pos1, _, _, '/') -> true; Pos1 = -1),
        (last_sub_atom(Path, Pos2, _, _, '\\') -> true; Pos2 = -1),
        Pos is max(Pos1, Pos2), Pos \== -1, !,
        Pos3 is Pos+1,
        atom_length(Path, Len),
        Len2 is Len-Pos3,
        sub_atom(Path, Pos3, Len2, _, Name).
    sys_file_name(Path, Path).

    Maybe regex could do the same. But can regex search backwards?
    You would need a kind of greedy regex pattern, that nevertheless
    has an alternative in it. And a regex library is more heavier, than some >>>
    last_sub_atom/5 which is still relative lightweight to provide, only
    a variant of sub_atom/5.



    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to All on Mon May 30 00:54:17 2022
    Question of the day:

    Look-ahead might not be a bad idea?

    Rather an pretty bad idea without any benefit, since
    the intended use case of non-det last_sub_atom/5, is
    det lastIndexOf(_), namely like here, slightly optimized

    version now with only one clause:

    sys_file_name(Path, Name) :-
    atom_length(Path, Len),
    (last_sub_atom(Path, _, _, Pos1, '/') -> true; Pos1 = Len),
    (last_sub_atom(Path, _, _, Pos2, '\\') -> true; Pos2 = Len),
    Pos is min(Pos1, Pos2),
    sub_atom(Path, _, Pos, 0, Name).

    So there is a (->)/2, which cuts away last_sub_atom/5. So if
    you do some extra work in last_sub_atom/5, you will:

    - Not eliminate the choice point. For example if the file
    name is "foo/bar/baz.p", the look ahead will find another
    “/”, and you will get a choice point.

    - Only generate overhead. Since you will internally search
    the first “/” from left, and then the second “/” from left.

    The only thing that removes the choice point is the
    local cut in (->)/2. And one way to avoid some extra work
    is to not have look-ahead.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Mon May 30 09:59:24 2022
    BTW, its utterly trivial to implement last_sub_atom/5.
    Just copy paste the implementation of sub_atom/5, and
    change ++ into --, <= text.length into \>= 0, etc...

    Extremly straight forward. Costs you less than a day.


    Mostowski Collapse schrieb:
    Question of the day:

    Look-ahead might not be a bad idea?

    Rather an pretty bad idea without any benefit, since
    the intended use case of non-det last_sub_atom/5, is
    det lastIndexOf(_), namely like here, slightly optimized

    version now with only one clause:

    sys_file_name(Path, Name) :-
    atom_length(Path, Len),
    (last_sub_atom(Path, _, _, Pos1, '/') -> true; Pos1 = Len),
    (last_sub_atom(Path, _, _, Pos2, '\\') -> true; Pos2 = Len),
    Pos is min(Pos1, Pos2),
    sub_atom(Path, _, Pos, 0, Name).

    So there is a (->)/2, which cuts away last_sub_atom/5. So if
    you do some extra work in last_sub_atom/5, you will:

    - Not eliminate the choice point. For example if the file
    name is "foo/bar/baz.p", the look ahead will find another
    “/”, and you will get a choice point.

    - Only generate overhead. Since you will internally search
    the first “/” from left, and then the second “/” from left.

    The only thing that removes the choice point is the
    local cut in (->)/2. And one way to avoid some extra work
    is to not have look-ahead.


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)