2012-07-06 32 views
12

Tôi có một điều khoản như sau:đếm số lượng các cuộc gọi của một khoản

lock_open:- 
     conditional_combination(X), 
     equal(X,[8,6,5,3,6,9]),!, 
     print(X). 

khoản này thành công. Nhưng tôi muốn biết bao nhiêu lần conditional_combination() được gọi trước khi equal(X,[8,6,5,3,6,9]) trở thành sự thật. chương trình là tạo ra một hoán vị bằng cách làm theo một số quy tắc. Và tôi cần phải có bao nhiêu hoán vị là cần phải tạo ra để có được một giá trị cụ thể như 865369.

Trả lời

12

Điều bạn thực sự muốn có gì đó hơi khác: Bạn muốn đếm số câu trả lời (cho đến nay) của một mục tiêu.

Vị từ sau call_nth(Goal_0, Nth) thành công như call(Goal_0) nhưng có một đối số bổ sung cho biết câu trả lời được tìm thấy là câu trả lời thứ n. Định nghĩa này rất cụ thể đối với SWI hoặc YAP. Làm không phải sử dụng những thứ như nb_setarg/3 trong các chương trình chung của bạn, nhưng sử dụng chúng cho các trường hợp được gói gọn như trường hợp này. Ngay cả trong phạm vi hai hệ thống này, ý nghĩa chính xác của các cấu trúc này không được xác định rõ ràng cho trường hợp chung. Here is a definition for SICStus.

 
call_nth(Goal_0, C) :- 
    State = count(0,_), % note the extra argument which remains a variable 
    Goal_0, 
    arg(1, State, C1), 
    C2 is C1+1, 
    nb_setarg(1, State, C2), 
    C = C2. 

Một trừu tượng mạnh mẽ hơn được cung cấp bởi Eclipse:

call_nth(Goal_0, Nth) :- 
    shelf_create(counter(0), CounterRef), 
    call(Goal_0), 
    shelf_inc(CounterRef, 1), 
    shelf_get(CounterRef, 1, Nth). 
 
?- call_nth(between(1,5,I),Nth). 
I = Nth, Nth = 1 ; 
I = Nth, Nth = 2 ; 
I = Nth, Nth = 3 ; 
I = Nth, Nth = 4 ; 
I = Nth, Nth = 5. 

Vì vậy, chỉ đơn giản là quấn nó xung quanh:

 
lock_open :- 
    call_nth(conditional_combination(X), Nth), 
    X = [8,6,5,3,6,9], 
    !, 
    .... 
+1

Tôi thấy một cách để thực hiện ** tập hợp ** O (N) trong khoảng thời gian ** và ** không gian bằng cách sử dụng nguyên thủy như vậy. Cảm ơn! – CapelliC

+0

Phải suy nghĩ lại giới hạn/2 và bù đắp/2 triển khai, có lẽ vị từ nguyên thủy và phổ quát hơn sẽ là call_nth/2. –

+0

Tôi không nhận ra rằng một mục tiêu có thể được gọi như vậy (dòng thứ ba của danh sách 'call_nth/2'). Tôi nghĩ người ta luôn cần 'gọi (Mục tiêu)', nhưng rõ ràng, chỉ là 'Mục tiêu' là đủ! –

4

Nếu bạn đang sử dụng SWI Prolog bạn có thể sử dụng nb_getval/2nb_setval/2 để đạt được những gì bạn muốn:

lock_open:- 
    nb_setval(ctr, 0), % Initialize counter 
    conditional_combination(X), 
    nb_inc(ctr), % Increment Counter 
    equal(X,[8,6,5,3,6,9]), 
    % Here you can access counter value with nb_getval(ctr, Value) 
    !, 
    print(X). 

nb_inc(Key):- 
    nb_getval(Key, Old), 
    succ(Old, New), 
    nb_setval(Key, New). 

prologs khác có các phương tiện khác để làm tương tự, hãy tìm các biến toàn cầu trong việc thực hiện prolog của bạn. Trong đoạn này tôi đã sử dụng thuật ngữ ctr để giữ bộ đếm mục tiêu hiện tại. Bạn có thể sử dụng bất kỳ thuật ngữ nào không được sử dụng trong chương trình của bạn.

+1

Một cuộc gọi cho 'nb_setval/2' trong' conditional_combination/1' sẽ ảnh hưởng đến kết quả. Một cái tên như 'ctr' có thể được sử dụng cho một số đếm khác ... – false

+0

@false: true, OP nên sử dụng bất kỳ thuật ngữ nào không được sử dụng trong chương trình của anh ta. – gusbro

+3

Vấn đề là bạn không thể đảm bảo rằng không kiểm tra toàn bộ chương trình của bạn. – false

Các vấn đề liên quan