navigazione attraverso il impressionanteOn-Line Encyclopedia of Integer Sequences (cfr en.wikipedia.org), sono incappato la seguente successione di interi:Prolog: calcolo OEIS A031877 ("numeri inversione non banali") usando CLP (FD)
A031877: numeri di inversione non banali (numeri che sono multipli interi di loro inversioni) esclusi numero palindromo e multipli di 10.
Grazie al riutilizzo del codice che ho scritto per la mia risposta in Oc e domanda correlata "Faster implementation of verbal arithmetic in Prolog" Potrei scrivere una soluzione senza alcuno sforzo, grazie a clpfd!
:- use_module(library(clpfd)).
Definiamo la relazione nucleoa031877_ndigits_/3
basati su digits_number/2
(definito in precedenza):
a031877_ndigits_(Z_big,N_digits,[K,Z_small,Z_big]) :-
K #> 1,
length(D_big,N_digits),
reverse(D_small,D_big),
digits_number(D_big,Z_big),
digits_number(D_small,Z_small),
Z_big #= Z_small * K.
Il rapporto nucleo è deterministico e termina universalmente ogniqualvolta N_digit
è un numero intero cemento . Guarda tu stesso i primi 100 valori di N_digit
!
?- time((N in 0..99,indomain(N),a031877_ndigits_(Z,N,Zs),false)).
% 3,888,222 inferences, 0.563 CPU in 0.563 seconds (100% CPU, 6903708 Lips)
false
Facciamo alcune domande!
?- a031877_ndigits_(87912000000087912,17,_). true % succeeds, as expected ; false. ?- a031877_ndigits_(87912000000987912,17,_). false. % fails, as expected
Avanti, troviamo alcuni numeri di inversione non banale che comprende esattamente quattro decimali-cifre:
?- a031877_ndigits_(Z,4,Zs), labeling([],Zs).
Z = 8712, Zs = [4,2178,8712]
; Z = 9801, Zs = [9,1089,9801]
; false.
OK! Misuriamo il runtime necessario per dimostrare la chiusura universale della query precedente!
?- time((a031877_ndigits_(Z,4,Zs),labeling([],Zs),false)).
% 11,611,502 inferences, 3.642 CPU in 3.641 seconds (100% CPU, 3188193 Lips)
false. % terminates universally
Ora, questo è così troppo lungo!
Cosa posso fare per velocizzare le cose? Utilizzare diversi e/o altri vincoli? Forse anche quelli ridondanti? O forse identificare ed eliminare le simmetrie che tagliano le dimensioni dello spazio di ricerca? Che dire dei diversi domini clp (*) (b, q, r, set)? O diverse tecniche di consistenza/propagazione? O piuttosto coroutining in stile Prolog?
Hai idee? Li voglio tutti! Grazie in anticipo.