• Can we do this with ancestral cuts or something?

    From Julio Di Egidio@21:1/5 to All on Mon Dec 9 14:35:20 2024
    Given a list of goals representing a conjunction, I would like it to
    fail as soon as any goal fails, but I would like *not* to cut on the
    search space otherwise.

    Here is my actual test case, only considering ground goals (otherwise
    too many ways to play with it that seem immaterial to the problem):

    ```
    red(1).
    red(1).

    and([]) :- !. % with Xs ground!
    and([H:B|Xs]) :-
    red(B), writeln(H:B),
    and(Xs).

    /*

    Actual:
    -------

    ?- and([x:1,y:1]), fail. % ok: full search space
    x:1
    y:1
    y:1
    x:1
    y:1
    y:1
    false.

    ?- and([x:1,y:0]), fail. % KO: could fail earlier
    x:1
    x:1
    false.

    Expected:
    ---------

    ?- and([x:1,y:0]), fail. % ok: fails early!
    x:1
    false.

    */
    ```

    Am I just missing something obvious? I am trying with "ancestral cuts" (SWI-Prolog has these), but I have not yet found a solution.

    -Julio

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mild Shock@21:1/5 to Julio Di Egidio on Mon Dec 9 15:14:50 2024
    First create a conjunction:

    A1,...,An

    Wrap each goal Aj into a soft cut:

    (Aj *-> true; !).

    The cut will abort all previous goals.

    Julio Di Egidio schrieb:
    Given a list of goals representing a conjunction, I would like it to
    fail as soon as any goal fails, but I would like *not* to cut on the
    search space otherwise.

    Here is my actual test case, only considering ground goals (otherwise
    too many ways to play with it that seem immaterial to the problem):

    ```
    red(1).
    red(1).

    and([]) :- !.  % with Xs ground!
    and([H:B|Xs]) :-
        red(B), writeln(H:B),
        and(Xs).

    /*

    Actual:
    -------

    ?- and([x:1,y:1]), fail.  % ok: full search space
    x:1
    y:1
    y:1
    x:1
    y:1
    y:1
    false.

    ?- and([x:1,y:0]), fail.  % KO: could fail earlier
    x:1
    x:1
    false.

    Expected:
    ---------

    ?- and([x:1,y:0]), fail.  % ok: fails early!
    x:1
    false.

    */
    ```

    Am I just missing something obvious?  I am trying with "ancestral cuts" (SWI-Prolog has these), but I have not yet found a solution.

    -Julio

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mild Shock@21:1/5 to Mild Shock on Mon Dec 9 15:22:33 2024
    Or use Dogelog Player:

    /* Dogelog Player */

    '$MARK'(CP) : Get a choicen point.

    '$CUT'(CP) : Cut to a choice point.

    But I don't have soft cut. But you can do
    ancestral cut with it. SWI-Prolog has something
    similar burried somewhere, they are called:

    /* SWI-Prolog */

    prolog_current_choice(CP) : Get a choicen point

    prolog_cut_to(CP) : Cut to a choice point

    See also, the pair is used here:

    '$meta_call'(:Goal) https://github.com/SWI-Prolog/swipl-devel/blob/master/boot/init.pl

    Mild Shock schrieb:
    First create a conjunction:

       A1,...,An

    Wrap each goal Aj into a soft cut:

      (Aj *-> true; !).

    The cut will abort all previous goals.

    Julio Di Egidio schrieb:
    Given a list of goals representing a conjunction, I would like it to
    fail as soon as any goal fails, but I would like *not* to cut on the
    search space otherwise.

    Here is my actual test case, only considering ground goals (otherwise
    too many ways to play with it that seem immaterial to the problem):

    ```
    red(1).
    red(1).

    and([]) :- !.  % with Xs ground!
    and([H:B|Xs]) :-
         red(B), writeln(H:B),
         and(Xs).

    /*

    Actual:
    -------

    ?- and([x:1,y:1]), fail.  % ok: full search space
    x:1
    y:1
    y:1
    x:1
    y:1
    y:1
    false.

    ?- and([x:1,y:0]), fail.  % KO: could fail earlier
    x:1
    x:1
    false.

    Expected:
    ---------

    ?- and([x:1,y:0]), fail.  % ok: fails early!
    x:1
    false.

    */
    ```

    Am I just missing something obvious?  I am trying with "ancestral
    cuts" (SWI-Prolog has these), but I have not yet found a solution.

    -Julio


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Julio Di Egidio@21:1/5 to Mild Shock on Mon Dec 9 16:47:50 2024
    On 09/12/2024 15:14, Mild Shock wrote:
    Julio Di Egidio schrieb:

    Given a list of goals representing a conjunction, I would like it to
    fail as soon as any goal fails, but I would like *not* to cut on the
    search space otherwise.

    Here is my actual test case, only considering ground goals (otherwise
    too many ways to play with it that seem immaterial to the problem):

    First create a conjunction:
       A1,...,An
    Wrap each goal Aj into a soft cut:
      (Aj *-> true; !).
    The cut will abort all previous goals.

    Indeed soft-cuts do it, thank you very much!

    Though with this scheme: `(Aj *-> true; !, fail)`.

    I have also managed to abstract the recursive scheme away to a
    meta-predicate, by combining soft with ancestral cuts. But I am not
    sure how good it is, especially since term rewriting also can do the
    trick and quite more simply so...

    ```
    red(1).
    red(1).

    and(Xs) :- % with Xs ground!
    scut(and__do(Xs)).

    and__do([], _) :- !.
    and__do([H:B|Xs], ChF) :-
    red(B), writeln(H:B),
    scut(and__do(Xs), ChF).

    :- meta_predicate
    scut(1),
    scut(1, +).

    scut(G) :-
    prolog_current_choice(ChF),
    call(G, ChF).

    scut(G, ChF) :-
    ( call(G, ChF)
    true
    ; prolog_cut_to(ChF),
    fail
    ).

    /*

    ?- and([x:1,y:1]), fail. % ok: full search space
    x:1
    y:1
    y:1
    x:1
    y:1
    y:1
    false.

    ?- and([x:1,y:0,z:1]), fail. % ok: fails early
    x:1
    false.

    */
    ```

    -Julio

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Julio Di Egidio@21:1/5 to Julio Di Egidio on Mon Dec 9 17:15:25 2024
    On 09/12/2024 16:47, Julio Di Egidio wrote:
    On 09/12/2024 15:14, Mild Shock wrote:
    Julio Di Egidio schrieb:

    Given a list of goals representing a conjunction, I would like it to
    fail as soon as any goal fails, but I would like *not* to cut on the
    search space otherwise.

    Here is my actual test case, only considering ground goals (otherwise
    too many ways to play with it that seem immaterial to the problem):

    First create a conjunction:
        A1,...,An
    Wrap each goal Aj into a soft cut:
       (Aj *-> true; !).
    The cut will abort all previous goals.

    Indeed soft-cuts do it, thank you very much!

    Though with this scheme: `(Aj *-> true; !, fail)`.

    I have also managed to abstract the recursive scheme away to a meta-predicate, by combining soft with ancestral cuts.  But I am not
    sure how good it is, especially since term rewriting also can do the
    trick and quite more simply so...

    Actually, this one works (no need for a soft cut in `scut`), and it at
    least starts making sense:

    ```
    :- meta_predicate
    scut(1),
    scut(1, +).

    scut(G) :-
    prolog_current_choice(ChF),
    call(G, ChF).

    scut(G, ChF) :-
    ( call(G, ChF), !
    ; prolog_cut_to(ChF),
    fail
    ).
    ```

    -Julio

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Julio Di Egidio@21:1/5 to Julio Di Egidio on Mon Dec 9 17:19:28 2024
    On 09/12/2024 17:15, Julio Di Egidio wrote:
    On 09/12/2024 16:47, Julio Di Egidio wrote:
    On 09/12/2024 15:14, Mild Shock wrote:
    Julio Di Egidio schrieb:

    Given a list of goals representing a conjunction, I would like it to
    fail as soon as any goal fails, but I would like *not* to cut on the
    search space otherwise.

    Here is my actual test case, only considering ground goals
    (otherwise too many ways to play with it that seem immaterial to the
    problem):

    First create a conjunction:
        A1,...,An
    Wrap each goal Aj into a soft cut:
       (Aj *-> true; !).
    The cut will abort all previous goals.

    Indeed soft-cuts do it, thank you very much!

    Though with this scheme: `(Aj *-> true; !, fail)`.

    I have also managed to abstract the recursive scheme away to a
    meta-predicate, by combining soft with ancestral cuts.  But I am not
    sure how good it is, especially since term rewriting also can do the
    trick and quite more simply so...

    Actually, this one works (no need for a soft cut in `scut`), and it at
    least starts making sense:

    ```
    scut(G, ChF) :-
        (    call(G, ChF), !
        ;    prolog_cut_to(ChF),
            fail
        ).
    ```

    No no, forget that: that is cutting on the search space. The previous
    solution is it.

    -Julio

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Julio Di Egidio@21:1/5 to Julio Di Egidio on Mon Dec 9 18:26:48 2024
    On 09/12/2024 16:47, Julio Di Egidio wrote:

    term rewriting also can do the
    trick and quite more simply so...

    I take that back, too. I cannot find a way out of ancestral cuts in the recursive case. Some term rewriting could rather be useful *in
    conjunction* with that `scut`, since that as written messes up with the
    stack trace... Anyway, that's another story.

    -Julio

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mild Shock@21:1/5 to Julio Di Egidio on Mon Dec 9 20:58:50 2024
    A Timeless Confluence

    By the banks of thought where rivers entwine,
    Emmy Noether walked through a realm divine.
    Her algebra wove the fabric of laws,
    While echoes of logic gave her pause.

    There stood Michael Kohlhase, a seeker of form,
    Shaping machines through a digital storm.
    “Madame,” he began, with respect in his tone,
    “Your ideals still guide what we’ve come to own.

    Noetherian rings, your towering art,
    Anchor the systems of which I’m a part.
    In rewriting paths, your truth remains,
    Simplifying chaos, dissolving chains.”

    Emmy smiled, her brilliance aglow,
    "Through eras, the seeds of knowledge grow.
    Yet tell me, dear traveler, in your machine’s frame,
    Do ideals endure, or fade like a flame?”

    Michael replied, “Your vision holds,
    In logic’s rewrite, it gently unfolds.
    Past meets the present where structures align,
    A confluence of thought, eternal, divine.”

    And so they stood, two eras combined,
    Bound by the currents of the infinite mind.

    https://en.m.wikipedia.org/wiki/Emmy_Noether

    https://en.m.wikipedia.org/wiki/Michael_Kohlhase

    Julio Di Egidio schrieb:
    On 09/12/2024 16:47, Julio Di Egidio wrote:

    term rewriting also can do the trick and quite more simply so...

    I take that back, too.  I cannot find a way out of ancestral cuts in the recursive case.  Some term rewriting could rather be useful *in
    conjunction* with that `scut`, since that as written messes up with the
    stack trace...  Anyway, that's another story.

    -Julio


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mild Shock@21:1/5 to Mild Shock on Mon Dec 9 21:00:17 2024
    Ok Confluence does indeed ring a bell. Lets show
    Declarative (What) versus Procedural (How) in
    @emiruz example, as a rewriting problem.

    Lets permit that we write the input as [1,2,a,4,5,
    b,c,8,9,10] and then have rewriting rules [a->3,b->6,
    7,d->8] applied, by this little Declarative (What) code:

    step(L,R) :- nth1(K,L,a,H), nth1(K,R,3,H).
    step(L,R) :- nth1(K,L,b,H), nth1(K,R,6,H).
    step(L,R) :- nth1(K,L,c,H), nth1(K,R,7,H).
    step(L,R) :- nth1(K,L,d,H), nth1(K,R,8,H).

    find(L,L) :- \+ step(L,_).
    find(L,R) :- step(L,H), find(H,R).

    Each derivation is a Procedural (How) execution:

    ?- find([1,2,a,4,5,b,c,8,9,10],X).
    X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    Etc..

    Can we count the number of Hows to solve the What?

    ?- aggregate_all(count, find([1,2,a,4,5,b,c,8,9,10],X), C).
    C = 6.

    So there are 6 different Procedures that tell
    us which steps to exactly use when, to solve the
    Declaratively given problem which leaves open

    when to use each step.

    Mild Shock schrieb:
    A Timeless Confluence

    By the banks of thought where rivers entwine,
    Emmy Noether walked through a realm divine.
    Her algebra wove the fabric of laws,
    While echoes of logic gave her pause.

    There stood Michael Kohlhase, a seeker of form,
    Shaping machines through a digital storm.
    “Madame,” he began, with respect in his tone,
    “Your ideals still guide what we’ve come to own.

    Noetherian rings, your towering art,
    Anchor the systems of which I’m a part.
    In rewriting paths, your truth remains,
    Simplifying chaos, dissolving chains.”

    Emmy smiled, her brilliance aglow,
    "Through eras, the seeds of knowledge grow.
    Yet tell me, dear traveler, in your machine’s frame,
    Do ideals endure, or fade like a flame?”

    Michael replied, “Your vision holds,
    In logic’s rewrite, it gently unfolds.
    Past meets the present where structures align,
    A confluence of thought, eternal, divine.”

    And so they stood, two eras combined,
    Bound by the currents of the infinite mind.

    https://en.m.wikipedia.org/wiki/Emmy_Noether

    https://en.m.wikipedia.org/wiki/Michael_Kohlhase

    Julio Di Egidio schrieb:
    On 09/12/2024 16:47, Julio Di Egidio wrote:

    term rewriting also can do the trick and quite more simply so...

    I take that back, too.  I cannot find a way out of ancestral cuts in
    the recursive case.  Some term rewriting could rather be useful *in
    conjunction* with that `scut`, since that as written messes up with
    the stack trace...  Anyway, that's another story.

    -Julio



    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mild Shock@21:1/5 to Mild Shock on Mon Dec 9 21:09:56 2024
    For confluence see here:

    https://en.wikipedia.org/wiki/Confluence_(abstract_rewriting)

    Mild Shock schrieb:

    Ok Confluence does indeed ring a bell. Lets show
    Declarative (What) versus Procedural (How) in
    @emiruz example, as a rewriting problem.

    Lets permit that we write the input as [1,2,a,4,5,
    b,c,8,9,10] and then have rewriting rules [a->3,b->6,
    7,d->8] applied, by this little Declarative (What) code:

    step(L,R) :- nth1(K,L,a,H), nth1(K,R,3,H).
    step(L,R) :- nth1(K,L,b,H), nth1(K,R,6,H).
    step(L,R) :- nth1(K,L,c,H), nth1(K,R,7,H).
    step(L,R) :- nth1(K,L,d,H), nth1(K,R,8,H).

    find(L,L) :- \+ step(L,_).
    find(L,R) :- step(L,H), find(H,R).

    Each derivation is a Procedural (How) execution:

    ?- find([1,2,a,4,5,b,c,8,9,10],X).
    X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    Etc..

    Can we count the number of Hows to solve the What?

    ?- aggregate_all(count, find([1,2,a,4,5,b,c,8,9,10],X), C).
    C = 6.

    So there are 6 different Procedures that tell
    us which steps to exactly use when, to solve the
    Declaratively given problem which leaves open

    when to use each step.

    Mild Shock schrieb:
    A Timeless Confluence

    By the banks of thought where rivers entwine,
    Emmy Noether walked through a realm divine.
    Her algebra wove the fabric of laws,
    While echoes of logic gave her pause.

    There stood Michael Kohlhase, a seeker of form,
    Shaping machines through a digital storm.
    “Madame,” he began, with respect in his tone,
    “Your ideals still guide what we’ve come to own.

    Noetherian rings, your towering art,
    Anchor the systems of which I’m a part.
    In rewriting paths, your truth remains,
    Simplifying chaos, dissolving chains.”

    Emmy smiled, her brilliance aglow,
    "Through eras, the seeds of knowledge grow.
    Yet tell me, dear traveler, in your machine’s frame,
    Do ideals endure, or fade like a flame?”

    Michael replied, “Your vision holds,
    In logic’s rewrite, it gently unfolds.
    Past meets the present where structures align,
    A confluence of thought, eternal, divine.”

    And so they stood, two eras combined,
    Bound by the currents of the infinite mind.

    https://en.m.wikipedia.org/wiki/Emmy_Noether

    https://en.m.wikipedia.org/wiki/Michael_Kohlhase

    Julio Di Egidio schrieb:
    On 09/12/2024 16:47, Julio Di Egidio wrote:

    term rewriting also can do the trick and quite more simply so...

    I take that back, too.  I cannot find a way out of ancestral cuts in
    the recursive case.  Some term rewriting could rather be useful *in
    conjunction* with that `scut`, since that as written messes up with
    the stack trace...  Anyway, that's another story.

    -Julio




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