• The future of Prolog dicts

    From Mostowski Collapse@21:1/5 to All on Tue Aug 24 18:27:30 2021
    I want to reintroduce Prolog dicts into Dogelog runtime.
    But they shoud also give me module access, thus the
    dot '.'/2 should replace ':'/2, and they should give me

    object access, thus the dot '.'/2 should replace '::'/2
    as well. Is this possible? There is now a new idea
    inspired by Python and JavaScrip.

    The core idea is:

    When we access some dict via '.'/2, a built-in will
    be executed. This built-in need not only perform an
    association lookup, it can also do more.

    By only modifying the behaviour of '.'/2 itself, it should
    be possible to create a variety of behaviours, even
    corresponding to '::'/2, i.e. single dispatch!!!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue Aug 24 18:38:12 2021
    Lets make two examples. The syntax of a method call
    will be like it was for (::)/2 except that the dot '.'/2 is used.
    So on the surface we will see:

    Receiver.Method(Arg1,..,Argn)

    This will be translated into the dict access built-in, which
    for illustration purpose is simply '.'/3. And more consequently
    than in the past, a call/n invokation:

    '.'(Receiver, Method, Temp),
    call(Temp, Arg1, .., Argn)

    This is new that call/n is involved. In the past we had some
    implementation (::)/2 wasnt further factored into the dictionary
    getter and the meta call. We can now do the following:

    1) For inheritance '.'/2 can follow some reexport chains. But
    unlike our old take of modules and reexport, these chains
    would now also exist for dicts.

    2) For virtual methods '.'/2 can return a closure. So basically
    if Method hits a virtual Function in the dictionary
    it would return Function(Receiver), a compound and not

    simple Function. When this return value is supplied
    to the meta call, the net effect will be that Function(Receiver,
    Arg1, .., Argn) is called, as desired for a virtual method.

    Combining 1) and 2) means that internally '.'/3 needs either
    a '.'/4 realization, that the on behalf Receiver can be passed
    down in case following a reexport chain hits a virtual Function.

    Or the result of '.'/3 calls another '.'''/2 which returns either
    (Value,0) or (Value,1) depending on whether non-virtual or
    virtual, and the wrapping is done in '.'/3.

    Mostowski Collapse schrieb am Mittwoch, 25. August 2021 um 03:27:31 UTC+2:
    I want to reintroduce Prolog dicts into Dogelog runtime.
    But they shoud also give me module access, thus the
    dot '.'/2 should replace ':'/2, and they should give me

    object access, thus the dot '.'/2 should replace '::'/2
    as well. Is this possible? There is now a new idea
    inspired by Python and JavaScrip.

    The core idea is:

    When we access some dict via '.'/2, a built-in will
    be executed. This built-in need not only perform an
    association lookup, it can also do more.

    By only modifying the behaviour of '.'/2 itself, it should
    be possible to create a variety of behaviours, even
    corresponding to '::'/2, i.e. single dispatch!!!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue Aug 24 18:44:34 2021
    Why do it this way, so complicated? Well we want to profit
    from the split into lookup '.'/3 and simple meta call call/n. We
    could then replicate for example this Python example,

    when x is an object and f is a virtual function, then:

    x.f()

    and this here:

    xf = x.f
    xf()

    Do the same. How is this possible? Python gives a nice explanation:

    9.3.4. Method Objects
    "If you still don’t understand how methods work, a look at the implementation can perhaps clarify matters. When a non-data
    attribute of an instance is referenced, the instance’s class is
    searched. If the name denotes a valid class attribute that is a
    function object, a method object is created by packing (pointers to)
    the instance object and the function object just found together
    in an abstract object: this is the method object. When the method
    object is called with an argument list, a new argument list is
    constructed from the instance object and the argument list,
    and the function object is called with this new argument list." https://docs.python.org/3/tutorial/classes.html

    Interestingly Java and JavaScript support such method
    objects. I was always marveling why the method handles have
    a bind() factory method, that binding a parameter and reducing

    the number of remaining parameters. But this is exactly what
    a future dicts should be able to do. If they step over a virtual function,
    they should bind it to the given receiver.

    Mostowski Collapse schrieb am Mittwoch, 25. August 2021 um 03:38:13 UTC+2:
    Lets make two examples. The syntax of a method call
    will be like it was for (::)/2 except that the dot '.'/2 is used.
    So on the surface we will see:

    Receiver.Method(Arg1,..,Argn)

    This will be translated into the dict access built-in, which
    for illustration purpose is simply '.'/3. And more consequently
    than in the past, a call/n invokation:

    '.'(Receiver, Method, Temp),
    call(Temp, Arg1, .., Argn)

    This is new that call/n is involved. In the past we had some
    implementation (::)/2 wasnt further factored into the dictionary
    getter and the meta call. We can now do the following:

    1) For inheritance '.'/2 can follow some reexport chains. But
    unlike our old take of modules and reexport, these chains
    would now also exist for dicts.

    2) For virtual methods '.'/2 can return a closure. So basically
    if Method hits a virtual Function in the dictionary
    it would return Function(Receiver), a compound and not

    simple Function. When this return value is supplied
    to the meta call, the net effect will be that Function(Receiver,
    Arg1, .., Argn) is called, as desired for a virtual method.

    Combining 1) and 2) means that internally '.'/3 needs either
    a '.'/4 realization, that the on behalf Receiver can be passed
    down in case following a reexport chain hits a virtual Function.

    Or the result of '.'/3 calls another '.'''/2 which returns either
    (Value,0) or (Value,1) depending on whether non-virtual or
    virtual, and the wrapping is done in '.'/3.
    Mostowski Collapse schrieb am Mittwoch, 25. August 2021 um 03:27:31 UTC+2:
    I want to reintroduce Prolog dicts into Dogelog runtime.
    But they shoud also give me module access, thus the
    dot '.'/2 should replace ':'/2, and they should give me

    object access, thus the dot '.'/2 should replace '::'/2
    as well. Is this possible? There is now a new idea
    inspired by Python and JavaScrip.

    The core idea is:

    When we access some dict via '.'/2, a built-in will
    be executed. This built-in need not only perform an
    association lookup, it can also do more.

    By only modifying the behaviour of '.'/2 itself, it should
    be possible to create a variety of behaviours, even
    corresponding to '::'/2, i.e. single dispatch!!!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue Aug 24 19:11:05 2021
    Whats a little problem, predicate indicators have not only
    a name, but also an arity. So what should be looked up is
    a name/arity pair. Unless we start forbidding multiple

    arities, or we lump sum multiple arities into one function.
    We could then lookup name, and arity is checked later while
    performing call/n. Some arity dispatch comes later.

    Such an arity polymorphic cache is already present in
    the Jekejeke Prolog atoms. Need to get my head around
    how this would work out in Dogelog runtime.

    Or have that these dicts are indeed keyed by predicate
    indicators, so that the translation would be. We could then
    pass different arities individually along inheritance chains:

    '.'(Receiver, Method/n, Temp),
    call(Temp, Arg1, .., Argn)

    So we would have dicts with predicate indicators as
    keys, this is what Prolog would demand. Or try some new
    lump sum approaches, JavaScript and Python

    do not demand that always the same number of arguments
    is passed. Python has *args and **pairs notation to even
    write routines that analyse theirs arguments in depth

    beyond simple defaults. No definite idea yet.

    Mostowski Collapse schrieb am Mittwoch, 25. August 2021 um 03:44:35 UTC+2:
    Why do it this way, so complicated? Well we want to profit
    from the split into lookup '.'/3 and simple meta call call/n. We
    could then replicate for example this Python example,

    when x is an object and f is a virtual function, then:

    x.f()

    and this here:

    xf = x.f
    xf()

    Do the same. How is this possible? Python gives a nice explanation:

    9.3.4. Method Objects
    "If you still don’t understand how methods work, a look at the implementation can perhaps clarify matters. When a non-data
    attribute of an instance is referenced, the instance’s class is
    searched. If the name denotes a valid class attribute that is a
    function object, a method object is created by packing (pointers to)
    the instance object and the function object just found together
    in an abstract object: this is the method object. When the method
    object is called with an argument list, a new argument list is
    constructed from the instance object and the argument list,
    and the function object is called with this new argument list." https://docs.python.org/3/tutorial/classes.html

    Interestingly Java and JavaScript support such method
    objects. I was always marveling why the method handles have
    a bind() factory method, that binding a parameter and reducing

    the number of remaining parameters. But this is exactly what
    a future dicts should be able to do. If they step over a virtual function, they should bind it to the given receiver.
    Mostowski Collapse schrieb am Mittwoch, 25. August 2021 um 03:38:13 UTC+2:
    Lets make two examples. The syntax of a method call
    will be like it was for (::)/2 except that the dot '.'/2 is used.
    So on the surface we will see:

    Receiver.Method(Arg1,..,Argn)

    This will be translated into the dict access built-in, which
    for illustration purpose is simply '.'/3. And more consequently
    than in the past, a call/n invokation:

    '.'(Receiver, Method, Temp),
    call(Temp, Arg1, .., Argn)

    This is new that call/n is involved. In the past we had some implementation (::)/2 wasnt further factored into the dictionary
    getter and the meta call. We can now do the following:

    1) For inheritance '.'/2 can follow some reexport chains. But
    unlike our old take of modules and reexport, these chains
    would now also exist for dicts.

    2) For virtual methods '.'/2 can return a closure. So basically
    if Method hits a virtual Function in the dictionary
    it would return Function(Receiver), a compound and not

    simple Function. When this return value is supplied
    to the meta call, the net effect will be that Function(Receiver,
    Arg1, .., Argn) is called, as desired for a virtual method.

    Combining 1) and 2) means that internally '.'/3 needs either
    a '.'/4 realization, that the on behalf Receiver can be passed
    down in case following a reexport chain hits a virtual Function.

    Or the result of '.'/3 calls another '.'''/2 which returns either (Value,0) or (Value,1) depending on whether non-virtual or
    virtual, and the wrapping is done in '.'/3.
    Mostowski Collapse schrieb am Mittwoch, 25. August 2021 um 03:27:31 UTC+2:
    I want to reintroduce Prolog dicts into Dogelog runtime.
    But they shoud also give me module access, thus the
    dot '.'/2 should replace ':'/2, and they should give me

    object access, thus the dot '.'/2 should replace '::'/2
    as well. Is this possible? There is now a new idea
    inspired by Python and JavaScrip.

    The core idea is:

    When we access some dict via '.'/2, a built-in will
    be executed. This built-in need not only perform an
    association lookup, it can also do more.

    By only modifying the behaviour of '.'/2 itself, it should
    be possible to create a variety of behaviours, even
    corresponding to '::'/2, i.e. single dispatch!!!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to All on Sun Aug 29 07:35:31 2021
    Interesting find, after some discussion Prolog vs LISP:

    The native code for Roomba is written in a dialect of Lisp. https://en.wikipedia.org/wiki/Roomba#Hacking_and_extending_Roomba

    and the Roomba, the autonomous robotic vacuum cleaner, whose software
    is written in L, a downwardly compatible subset of Common Lisp. https://gigamonkeys.com/book/introduction-why-lisp.html

    L – A Common Lisp for Embedded Systems https://www.researchgate.net/publication/2949173

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Sun Aug 29 07:40:41 2021
    L, from the 2004 paper, is somehow brother
    in spirit with Dogelog runtime:
    - it should produce reasonably efficient code
    - compilation speed should be fast
    - it should be target independent
    - it should be easy to maintain

    But L takes a different approach, since it has a CPU
    target and not a high level language target. Nevertheless
    interesting paper by Rodney A. Brooks.

    LoL

    Mostowski Collapse schrieb am Sonntag, 29. August 2021 um 16:35:32 UTC+2:
    Interesting find, after some discussion Prolog vs LISP:

    The native code for Roomba is written in a dialect of Lisp. https://en.wikipedia.org/wiki/Roomba#Hacking_and_extending_Roomba

    and the Roomba, the autonomous robotic vacuum cleaner, whose software
    is written in L, a downwardly compatible subset of Common Lisp. https://gigamonkeys.com/book/introduction-why-lisp.html

    L – A Common Lisp for Embedded Systems https://www.researchgate.net/publication/2949173

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Sun Aug 29 07:55:16 2021
    Corr.: The paper is from 1995:

    Rodney A. Brooks and Charles Rosenberg,
    "L - A Common Lisp for Embedded Systems",
    Lisp Users and Vendors Conference, sec. 2.4a, August 1995.

    Mostowski Collapse schrieb am Sonntag, 29. August 2021 um 16:40:42 UTC+2:
    L, from the 2004 paper, is somehow brother
    in spirit with Dogelog runtime:
    - it should produce reasonably efficient code
    - compilation speed should be fast
    - it should be target independent
    - it should be easy to maintain

    But L takes a different approach, since it has a CPU
    target and not a high level language target. Nevertheless
    interesting paper by Rodney A. Brooks.

    LoL
    Mostowski Collapse schrieb am Sonntag, 29. August 2021 um 16:35:32 UTC+2:
    Interesting find, after some discussion Prolog vs LISP:

    The native code for Roomba is written in a dialect of Lisp. https://en.wikipedia.org/wiki/Roomba#Hacking_and_extending_Roomba

    and the Roomba, the autonomous robotic vacuum cleaner, whose software
    is written in L, a downwardly compatible subset of Common Lisp. https://gigamonkeys.com/book/introduction-why-lisp.html

    L – A Common Lisp for Embedded Systems https://www.researchgate.net/publication/2949173

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Sun Aug 29 08:22:02 2021
    Ha Ha,

    LISP and PROLOG having tea in the morning... https://de.ulule.com/documentaire-alain-colmerauer/news/lisp-and-prolog-having-tea-in-the-morning-311098/

    Mostowski Collapse schrieb am Sonntag, 29. August 2021 um 16:55:17 UTC+2:
    Corr.: The paper is from 1995:

    Rodney A. Brooks and Charles Rosenberg,
    "L - A Common Lisp for Embedded Systems",
    Lisp Users and Vendors Conference, sec. 2.4a, August 1995.
    Mostowski Collapse schrieb am Sonntag, 29. August 2021 um 16:40:42 UTC+2:
    L, from the 2004 paper, is somehow brother
    in spirit with Dogelog runtime:
    - it should produce reasonably efficient code
    - compilation speed should be fast
    - it should be target independent
    - it should be easy to maintain

    But L takes a different approach, since it has a CPU
    target and not a high level language target. Nevertheless
    interesting paper by Rodney A. Brooks.

    LoL
    Mostowski Collapse schrieb am Sonntag, 29. August 2021 um 16:35:32 UTC+2:
    Interesting find, after some discussion Prolog vs LISP:

    The native code for Roomba is written in a dialect of Lisp. https://en.wikipedia.org/wiki/Roomba#Hacking_and_extending_Roomba

    and the Roomba, the autonomous robotic vacuum cleaner, whose software
    is written in L, a downwardly compatible subset of Common Lisp. https://gigamonkeys.com/book/introduction-why-lisp.html

    L – A Common Lisp for Embedded Systems https://www.researchgate.net/publication/2949173

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to All on Tue Aug 31 03:22:26 2021
    Lets take a time machine, and go back to the beginnings of
    Prolog. In my opinion, a must classic to read, when you want
    to talk about Prolog:

    Prolog - the language and its implementation compared with Lisp.
    David H. D. Warren, Luis M. Pereira, Fernando Pereira:
    Artificial Intelligence and Programming Languages 1977: 109-115 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.65.7097&rep=rep1&type=pdf

    From its content:

    We argue that pattern matching is a better method for
    expressing operations on structured data than
    conventional selectors and constructors - both for
    the user and for the implementor.
    […]
    The second factor favouring Prolog is structuresharing.
    Ironically, this technique was first devised by Boyer and
    Moore [1972] as a means of saving space. However it is
    even more important for its contribution to Prolog’s speed.

    Etc… Etc…

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue Aug 31 03:23:11 2021
    Pattern matching is quite important for commercial software. Its
    easier to write business rules sometimes with pattern matching,
    although it has a its trap doors.

    Pattern matching is found in a variety of languages now:

    Erlang
    Haskell
    JavaScript
    Scala
    Rust
    Python
    What else?

    Python has it only officially with release 3.10 this year 2021.
    The pattern matching found in Python is funny, since it has
    a disjunction operator ‘|’. So you can say:

    match x:
    case [(1 | 2),(3 | 4)]:

    Which doesn’t have a Prolog equivalent. So recently
    I was thinking about not only introducing (=>)/2 SSU to
    Prolog but also (’|’)/2 in the head. Anybody up to this challenge?

    Mostowski Collapse schrieb am Dienstag, 31. August 2021 um 12:22:27 UTC+2:
    Lets take a time machine, and go back to the beginnings of
    Prolog. In my opinion, a must classic to read, when you want
    to talk about Prolog:

    Prolog - the language and its implementation compared with Lisp.
    David H. D. Warren, Luis M. Pereira, Fernando Pereira:
    Artificial Intelligence and Programming Languages 1977: 109-115 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.65.7097&rep=rep1&type=pdf

    From its content:

    We argue that pattern matching is a better method for
    expressing operations on structured data than
    conventional selectors and constructors - both for
    the user and for the implementor.
    […]
    The second factor favouring Prolog is structuresharing.
    Ironically, this technique was first devised by Boyer and
    Moore [1972] as a means of saving space. However it is
    even more important for its contribution to Prolog’s speed.

    Etc… Etc…

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue Aug 31 03:33:27 2021
    Python has something that could speed up pattern matching
    with Dicts. Namely they call it named tuples. Python Dicts don’t
    have a type tag like SWI-Prolog dicts.

    On the other hand named tuples have a type tag. But named
    tuples have something more. If I am not mistaking they also
    allow positional access. So they are hybrid between compound

    and dict, implement both protocols. And subequently could
    be indexed like Prolog does index predicates. Not sure where
    this all leads to. I am new to Python.

    Mostowski Collapse schrieb am Dienstag, 31. August 2021 um 12:32:39 UTC+2:
    I discovered that Python has pattern matching when I implemented
    the Python version of the Dogelog runtime. Although I use it only
    as a substitute for a simple switch statement, which wasn’t available

    before in Python. You could model the Python match via a Prolog clause:

    p([A,B]) :- (A=1;A=2), (B=3;B=4).

    But the head movement that Jan W. has recently introduced in
    SWI-Prolog would not work for (;)/2 in the body, so where is the
    Prolog indexing for ('|')/2 patterns in the head?

    Because pattern matching is useful for business rules, the
    audience of Prolog is possibly not the same as for Rust. You
    might have more luck addressing the same people

    that are also interested in RuleML.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue Aug 31 03:24:54 2021
    After this excursion, lets come back to Prolog dicts.
    There is still quite some research going on about pattern
    matching. The viewpoint of modern pattern matching is

    that it should be more versatile than Prolog unification.
    So some pattern compilers allow attribute matching or
    sequence matching etc… Which are not part of the

    Prolog language. So for example to have Datalog in the form:

    ?- X #> 1000, alert(stock: "Apple", price: X, day: Y)

    Where X #> 1000 would be a constraint and mingled with some
    some index in the dynamic database, is not part and parcel of
    the Prolog language itself. If you do it like this,

    no indexing will be used, using SWI-Prolog dicts:

    ?- alert(D), D.stock = "Apple", D.price > 1000, Y = D.day.

    And you are doomed to have an O(N) algorithm, and N can be huge.
    Even SQL can do better when you do:

    SELECT day FROM alert
    WHERE stock = "Apple" AND price > 1000

    Mostowski Collapse schrieb am Dienstag, 31. August 2021 um 12:23:12 UTC+2:
    Pattern matching is quite important for commercial software. Its
    easier to write business rules sometimes with pattern matching,
    although it has a its trap doors.

    Pattern matching is found in a variety of languages now:

    Erlang
    Haskell
    JavaScript
    Scala
    Rust
    Python
    What else?

    Python has it only officially with release 3.10 this year 2021.
    The pattern matching found in Python is funny, since it has
    a disjunction operator ‘|’. So you can say:

    match x:
    case [(1 | 2),(3 | 4)]:

    Which doesn’t have a Prolog equivalent. So recently
    I was thinking about not only introducing (=>)/2 SSU to
    Prolog but also (’|’)/2 in the head. Anybody up to this challenge? Mostowski Collapse schrieb am Dienstag, 31. August 2021 um 12:22:27 UTC+2:
    Lets take a time machine, and go back to the beginnings of
    Prolog. In my opinion, a must classic to read, when you want
    to talk about Prolog:

    Prolog - the language and its implementation compared with Lisp.
    David H. D. Warren, Luis M. Pereira, Fernando Pereira:
    Artificial Intelligence and Programming Languages 1977: 109-115 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.65.7097&rep=rep1&type=pdf

    From its content:

    We argue that pattern matching is a better method for
    expressing operations on structured data than
    conventional selectors and constructors - both for
    the user and for the implementor.
    […]
    The second factor favouring Prolog is structuresharing.
    Ironically, this technique was first devised by Boyer and
    Moore [1972] as a means of saving space. However it is
    even more important for its contribution to Prolog’s speed.

    Etc… Etc…

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to All on Tue Aug 31 03:32:38 2021
    I discovered that Python has pattern matching when I implemented
    the Python version of the Dogelog runtime. Although I use it only
    as a substitute for a simple switch statement, which wasn’t available

    before in Python. You could model the Python match via a Prolog clause:

    p([A,B]) :- (A=1;A=2), (B=3;B=4).

    But the head movement that Jan W. has recently introduced in
    SWI-Prolog would not work for (;)/2 in the body, so where is the
    Prolog indexing for ('|')/2 patterns in the head?

    Because pattern matching is useful for business rules, the
    audience of Prolog is possibly not the same as for Rust. You
    might have more luck addressing the same people

    that are also interested in RuleML.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to All on Fri Sep 3 06:30:31 2021
    The bind construct is a facinating construct. Taking a
    n-ary function f and binding x1,..,xm parameters, giving
    a n-m ary function g = f(x1,..,xm).

    This closure construction exists also in Prolog, and is
    even part of the ISO core standard. We can simply form
    g = call(f,x1,..,xm), it will behave like a bound predicate,

    a predicate where some arguments have already an
    actual value. But the actual values x1,..,xm can also be
    logical variables, so giving it a special spin in Prolog. I am

    still thinking about introducing compiled lambdas in Dogelog.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Fri Sep 3 06:40:18 2021
    I made an intersting discovery today, concerning a new take
    on lambda expression, and maybe making them automatically
    compiled. So far there are various lambda libraries, they

    differ in how they see variables:

    - library(abstract): From Jekejeke Prolog, via (\)/2 it sees variables
    in the lambda body as global by default, and you can make
    variables from the lambda body local via the (^)/2.

    - library(lambda): From Ulrich Neumerkel, it sees variables
    in the lambda body as local by default, and you can make
    variables from the lambda body global via the (+)/2.

    This boils down that some variables in the body will be local
    and some will be global, and some syntax will tell which is
    which. Now how compile this?

    From disjunction and if-then-else indexing there is a new,
    which gives a reference data type:

    - kb_make_defined(L, P): internal only
    The built-in succeeds in P with an annonymous predicate for the clauses L.

    By the nature of Prolog clauses, all variables that do not appear
    in the head but appear in the body, are local. So how can we
    introduce a notion of global variables?

    Mostowski Collapse schrieb am Freitag, 3. September 2021 um 15:30:32 UTC+2:
    The bind construct is a facinating construct. Taking a
    n-ary function f and binding x1,..,xm parameters, giving
    a n-m ary function g = f(x1,..,xm).

    This closure construction exists also in Prolog, and is
    even part of the ISO core standard. We can simply form
    g = call(f,x1,..,xm), it will behave like a bound predicate,

    a predicate where some arguments have already an
    actual value. But the actual values x1,..,xm can also be
    logical variables, so giving it a special spin in Prolog. I am

    still thinking about introducing compiled lambdas in Dogelog.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Fri Sep 3 06:49:01 2021
    The answer is very simple, through binders with call/n.
    Take this example of an anonymous predicate. The
    Prolog variable P is supposed to hold an opaque reference type:

    P = {(X,Y) :- Y is X+Z}

    The intention is that Z is added to the formal parameter X,
    and the result is unified with the formal parameter Y. Unfortunatly
    Z is local, but lets say we want to have Z global.

    There are now two steps to do this:

    - Step 1: Extends the head by the global variables.
    Se we would create an anonymous predicate like this. The
    Prolog variable P' is supposed hold an opaque reference type:

    P' = {(Z,X,Y) :- Y is X+Z}

    - Step 2: Bind the global variables:
    Se we would form this closure. The Prolog variable P''
    is supposed to hold the call/2 compound:

    P'' = call(P', Z).

    This should do the job. The expected result is now:

    ?- Z=2, call(P'', 1, R).
    R = 3

    Mostowski Collapse schrieb am Freitag, 3. September 2021 um 15:40:19 UTC+2:
    I made an intersting discovery today, concerning a new take
    on lambda expression, and maybe making them automatically
    compiled. So far there are various lambda libraries, they

    differ in how they see variables:

    - library(abstract): From Jekejeke Prolog, via (\)/2 it sees variables
    in the lambda body as global by default, and you can make
    variables from the lambda body local via the (^)/2.

    - library(lambda): From Ulrich Neumerkel, it sees variables
    in the lambda body as local by default, and you can make
    variables from the lambda body global via the (+)/2.

    This boils down that some variables in the body will be local
    and some will be global, and some syntax will tell which is
    which. Now how compile this?

    From disjunction and if-then-else indexing there is a new,
    which gives a reference data type:

    - kb_make_defined(L, P): internal only
    The built-in succeeds in P with an annonymous predicate for the clauses L.

    By the nature of Prolog clauses, all variables that do not appear
    in the head but appear in the body, are local. So how can we
    introduce a notion of global variables?
    Mostowski Collapse schrieb am Freitag, 3. September 2021 um 15:30:32 UTC+2:
    The bind construct is a facinating construct. Taking a
    n-ary function f and binding x1,..,xm parameters, giving
    a n-m ary function g = f(x1,..,xm).

    This closure construction exists also in Prolog, and is
    even part of the ISO core standard. We can simply form
    g = call(f,x1,..,xm), it will behave like a bound predicate,

    a predicate where some arguments have already an
    actual value. But the actual values x1,..,xm can also be
    logical variables, so giving it a special spin in Prolog. I am

    still thinking about introducing compiled lambdas in Dogelog.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Fri Sep 3 20:55:57 2021
    Europe is a leading actor in the area of formal proofs:
    about 65% of the proof systems of the world are
    developed in Europe, including the two most used
    proof assistants, Coq and Isabelle.
    https://www.cost.eu/actions/CA20111/

    LoL how did they measure 65%?

    Do we always need HOL or FOL? What about these little gems:

    WILL CRICHTON (2020), The Usability of Ownership, Stanford University https://arxiv.org/pdf/2011.06171.pdf

    Chalk is a library that implements the Rust
    trait system, based on Prolog-ish logic rules. https://github.com/rust-lang/chalk

    Disclaimer: Have only glossed over the Rust stuff.
    Dont know what logic they really use.


    Mostowski Collapse schrieb:
    I want to reintroduce Prolog dicts into Dogelog runtime.
    But they shoud also give me module access, thus the
    dot '.'/2 should replace ':'/2, and they should give me

    object access, thus the dot '.'/2 should replace '::'/2
    as well. Is this possible? There is now a new idea
    inspired by Python and JavaScrip.

    The core idea is:

    When we access some dict via '.'/2, a built-in will
    be executed. This built-in need not only perform an
    association lookup, it can also do more.

    By only modifying the behaviour of '.'/2 itself, it should
    be possible to create a variety of behaviours, even
    corresponding to '::'/2, i.e. single dispatch!!!


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to All on Thu Sep 9 04:55:00 2021
    Isnt this little trick known? One can make clause indexing
    without head unification. For example if you want indexing
    over some book id. One could do instead of this proposal:

    book(book{title: "I Am Malala",
    author: 'Malala Yousafzai',
    publisher: 'Little, Brown & Co',
    year: 2013,
    isbn: 9780316322409,
    edition: 1}).
    Etc..

    One would store:

    book(9780316322409, book{title: "I Am Malala",
    author: 'Malala Yousafzai',
    publisher: 'Little, Brown & Co',
    year: 2013,
    isbn: 9780316322409,
    edition: 1}).
    Etc..

    And then define, to avoid that retract commits too early
    I use clause/3 and erase/1 combo:

    assertz_book(Book) :-
    assertz(book(Book.get(isbn,_), Book)).

    fetch_book(Select) :-
    book(Select.get(isbn,_), Book),
    Select :< Book.

    retract_book(Select) :-
    clause(book(Select.get(isbn,_), Book), true, Ref),
    Select :< Book,
    erase(Ref).

    I am also using the new, from a few weeks ago, get/2
    on dict and the older (:<)/2.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to All on Thu Sep 9 04:59:41 2021
    Doing such things is usually a mental problem:

    Do not under estimate expansion. DCG are also done via expansion.
    Now you can ask yourself:

    Is DCG expansion implemented in C (or some other host language)
    for your favorite Prolog system?
    Is DCG expansion implemented in Prolog
    for your favorite Prolog system?

    Possibly you find both approaches. You call expansion frivolous. But I
    call doing Prolog parts mainly in C (or some other host language) frivolous.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Thu Sep 9 04:56:57 2021
    Wouldn’t it be possible in SWI-Prolog to have this?

    Indexes on Computed Columns https://docs.microsoft.com/en-us/sql/relational-databases/indexes/indexes-on-computed-columns

    The computed column need not be stored as extending the predicate arity.

    The computed column is Select.get(isbn,_), but there is also
    a custom matcher involved, like (:<)/2. But the Prolog system could
    have a directive:

    get_isbn(Select, Isbn) :- Isbn = Select.get(isbn,_).
    :- computed_index book(1, get_isbn, :<).

    And then do everything under the hood, so that directly
    call, assertz and retract can be used with book/1, instead
    having the burden of book/2 for the end-user.

    Mostowski Collapse schrieb am Donnerstag, 9. September 2021 um 13:55:45 UTC+2:
    Works like a charm:

    ?- assertz_book(book{isbn:42, title:foo, year:1973}).

    ?- assertz_book(book{isbn:69, title:bar, year:1984}).

    ?- listing(book/2).
    book(42, book{isbn:42, title:foo, year:1973}).
    book(69, book{isbn:69, title:bar, year:1984}).

    ?- fetch_book(book{isbn:42, title:T}).
    T = foo.

    ?- fetch_book(book{isbn:I, title:bar}).
    I = 69.

    ?- retract_book(book{isbn:42, title:T}).
    T = foo.

    ?- listing(book/2).
    book(69, book{isbn:69, title:bar, year:1984}).
    Mostowski Collapse schrieb am Donnerstag, 9. September 2021 um 13:55:02 UTC+2:
    Isnt this little trick known? One can make clause indexing
    without head unification. For example if you want indexing
    over some book id. One could do instead of this proposal:

    book(book{title: "I Am Malala",
    author: 'Malala Yousafzai',
    publisher: 'Little, Brown & Co',
    year: 2013,
    isbn: 9780316322409,
    edition: 1}).
    Etc..

    One would store:

    book(9780316322409, book{title: "I Am Malala",
    author: 'Malala Yousafzai',
    publisher: 'Little, Brown & Co',
    year: 2013,
    isbn: 9780316322409,
    edition: 1}).
    Etc..

    And then define, to avoid that retract commits too early
    I use clause/3 and erase/1 combo:

    assertz_book(Book) :-
    assertz(book(Book.get(isbn,_), Book)).

    fetch_book(Select) :-
    book(Select.get(isbn,_), Book),
    Select :< Book.

    retract_book(Select) :-
    clause(book(Select.get(isbn,_), Book), true, Ref),
    Select :< Book,
    erase(Ref).

    I am also using the new, from a few weeks ago, get/2
    on dict and the older (:<)/2.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Thu Sep 9 04:55:44 2021
    Works like a charm:

    ?- assertz_book(book{isbn:42, title:foo, year:1973}).

    ?- assertz_book(book{isbn:69, title:bar, year:1984}).

    ?- listing(book/2).
    book(42, book{isbn:42, title:foo, year:1973}).
    book(69, book{isbn:69, title:bar, year:1984}).

    ?- fetch_book(book{isbn:42, title:T}).
    T = foo.

    ?- fetch_book(book{isbn:I, title:bar}).
    I = 69.

    ?- retract_book(book{isbn:42, title:T}).
    T = foo.

    ?- listing(book/2).
    book(69, book{isbn:69, title:bar, year:1984}).

    Mostowski Collapse schrieb am Donnerstag, 9. September 2021 um 13:55:02 UTC+2:
    Isnt this little trick known? One can make clause indexing
    without head unification. For example if you want indexing
    over some book id. One could do instead of this proposal:

    book(book{title: "I Am Malala",
    author: 'Malala Yousafzai',
    publisher: 'Little, Brown & Co',
    year: 2013,
    isbn: 9780316322409,
    edition: 1}).
    Etc..

    One would store:

    book(9780316322409, book{title: "I Am Malala",
    author: 'Malala Yousafzai',
    publisher: 'Little, Brown & Co',
    year: 2013,
    isbn: 9780316322409,
    edition: 1}).
    Etc..

    And then define, to avoid that retract commits too early
    I use clause/3 and erase/1 combo:

    assertz_book(Book) :-
    assertz(book(Book.get(isbn,_), Book)).

    fetch_book(Select) :-
    book(Select.get(isbn,_), Book),
    Select :< Book.

    retract_book(Select) :-
    clause(book(Select.get(isbn,_), Book), true, Ref),
    Select :< Book,
    erase(Ref).

    I am also using the new, from a few weeks ago, get/2
    on dict and the older (:<)/2.

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