Pure Prolog Scheme Quine

前端 未结 3 645
走了就别回头了
走了就别回头了 2021-01-21 06:15

There is this paper:

William E. Byrd, Eric Holk, Daniel P. Friedman, 2012
miniKanren, Live and Untagged
Quine Generation via Relational Interpret

3条回答
  •  孤城傲影
    2021-01-21 06:34

    One might ask whether an occurs check flag is superior to an explicit unify_with_occurs_check/2. In the solution with explicit unify_with_occurs_check/2 we have placed one such call in lookup2/3 and in quine/3. If we use an occurs check flag, we do not need to manually place such calls and can rely on the dynamics of the Prolog interpreter.

    We removed the explicit unify_with_occurs_check/2 in lookup2/3:

    lookup2(S, [S-T|_], T).
    lookup2(S, [T-_|E], R) :-
       dif(S, T),
       lookup(S, E, R).
    

    And also in quine/3, making it less generate and test, and more constraint logic like. Using the same variable Q twice acts like a constraint that is pushed into the execution:

    quine(Q, M, N) :-
       expr(Q),
       between(0, M, N),
       eval(Q, [], Q, [N], _).
    

    Here are some results for the new SWI-Prolog 8.3.17, which got its unify_with_occurs_check/2 fixed to gether with zhe occurs check flag fixed:

    /* explicit unify_with_occurs_check/2 */
    ?- time((dif(Q, []), quine(Q, 6, N))).
    % 208,612,270 inferences, 11.344 CPU in 11.332 seconds (100% CPU, 18390062 Lips)
    
    /* occurs_check=true */
    ?- time((dif(Q, []), quine(Q, 6, N))).
    % 48,502,916 inferences, 2.859 CPU in 2.859 seconds (100% CPU, 16962768 Lips)
    

    And also a preview for the upcoming Jekejeke Prolog 1.4.7, which will also feature an occurs check flag:

    /* explicit unify_with_occurs_check/2 */
    ?- time((dif(Q, []), quine(Q, 6, N))).
    % Up 37,988 ms, GC 334 ms, Threads 37,625 ms (Current 01/10/21 01:29:35)
    
    /* occurs_check=true */
    ?- time((dif(Q, []), quine(Q, 6, N))).
    % Up 13,367 ms, GC 99 ms, Threads 13,235 ms (Current 01/10/21 01:35:24)
    

    Quite amazing that the occurs check flag can lead to a 3-fold spead-up in both Prolog systems! The result is possibly indicative the way we explicitly placed unify_with_occurs_check/2 was faulty?

    BTW: Open source:

    Quine Generation via Relational Interpreters
    explicit unify_with_occurs_check/2
    https://gist.github.com/jburse/a05e04191dcc68e542567542a7183d3b#file-quine-pl

    Quine Generation via Relational Interpreters
    occurs_check=true
    https://gist.github.com/jburse/a05e04191dcc68e542567542a7183d3b#file-quine2-pl

提交回复
热议问题