2015-06-11 18 views
7

Trong khi sử dụng gprolog tôi thường có trường hợp ngoại lệ mà không cần bất kỳ loại số dòng hoặc bối cảnh như thế này:gprolog: Bắt một stacktrace sau khi một ngoại lệ

uncaught exception: error(instantiation_error,(is)/2) 

Nếu không có bất kỳ loại ngữ cảnh. Tôi biết tôi có thể làm một trace nhưng nó sẽ mất rất nhiều thời gian để gỡ lỗi nó với trace vì tôi cần phải thực hiện rất nhiều thứ trước khi đến nơi xảy ra lỗi.

Bất kỳ ý tưởng nào về cách có ngăn xếp này? Hoặc động trace/notrace?

CHỈNH SỬA: Hoặc chỉ tự động in toàn bộ đầu ra trace.

Trả lời

8

Câu trả lời của @ gusbro (s(X)) cho bạn biết cách bạn giải quyết vấn đề này bằng trình gỡ rối của GNU. Tuy nhiên, nếu bạn không thể đủ khả năng để xem tất cả việc in đang diễn ra, hoặc quá chậm, bạn có thể xem xét "trình gỡ lỗi" sau đây. Cá nhân tôi không sử dụng các trình gỡ rối được cung cấp bởi các hệ thống Prolog vì lý do đơn giản là hầu hết chúng in quá nhiều, thường tự lỗi, và có quy ước thay đổi cụ thể của riêng mình, tôi không thể học được.

:- op(900, fx, [@,$,$-]). 

$-(G_0) :- 
    catch(G_0, Ex, (portray_clause(exception:Ex:G_0), throw(Ex))). 

$(G_0) :- 
    portray_clause(call:G_0), 
    $-G_0, 
    portray_clause(exit:G_0). 

@(G_0) :- 
    ( $-G_0 
    *-> true 
    ; portray_clause(badfail:G_0), 
     throw(goal_failed(G_0)) 
    ). 

:- op(950, fy, *). 
*(_). 

Để sử dụng nó, chỉ cần thêm $-, $, hoặc @ trước một mục tiêu cụ thể.

$- có nghĩa là: chỉ là dấu hiệu ngoại lệ sẽ thông qua mục tiêu này

$ thêm hiển thị cuộc gọi và thoát

@ đảm bảo rằng có ít nhất một câu trả lời, và nếu không, nó được báo cáo và một ngoại lệ được ném .

Sử dụng chú thích ở trên một cách tiết kiệm!

* xóa mục tiêu. Điều này là để tổng quát một chương trình làm chương trình sửa đổi/cắt trong một chương trình đơn điệu thuần túy. Đối với ví dụ làm thế nào để sử dụng nó, nhìn thấy câu trả lời/phiên gỡ rối sau 1, 2, 3, 4, 5, 6, 7, 8.

_/*term*/ thay thế cụm từ bằng biến ẩn danh. Điều này tổng quát một chương trình thậm chí còn hơn một mình là chỉ một mình là *.phiên dụ: 1, 2, 3, 4, 5, 6, 7.

Bằng cách này, bạn có thể giảm thông tin bạn xem đáng kể.

Trong các hệ thống khác hỗ trợ meta_predicate chỉ thị như SICStus, YAP và SWI, thêm vào trước các chỉ thị sau:

:- meta_predicate(($-(0), $(0), @(0))). 
+0

Wow, cả hai giải pháp đều tuyệt vời! Cảm ơn rất nhiều! – damio

7

Bạn có thể trace/0leash/1 chỉ ngoại lệ cổng, ví dụ:

?- trace. 
?- leash([exception]). 

Sau đó, bạn chạy chương trình của bạn và nó sẽ in một dấu vết trên màn hình nhưng chỉ dừng lại khi một ngoại lệ xảy ra. Ở đó bạn có thể thấy dấu vết ngăn xếp " (tổ tiên) bằng cách nhấn chữ cái g.

+0

Cảm ơn một người đàn ông rất nhiều! Nghiêm túc, điều này thực sự tuyệt vời! – damio

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