prolog-trace-viz 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +148 -0
  2. package/dist/analyzer.d.ts +64 -0
  3. package/dist/analyzer.d.ts.map +1 -0
  4. package/dist/analyzer.js +903 -0
  5. package/dist/analyzer.js.map +1 -0
  6. package/dist/build-info.d.ts +15 -0
  7. package/dist/build-info.d.ts.map +1 -0
  8. package/dist/build-info.js +26 -0
  9. package/dist/build-info.js.map +1 -0
  10. package/dist/clauses.d.ts +15 -0
  11. package/dist/clauses.d.ts.map +1 -0
  12. package/dist/clauses.js +80 -0
  13. package/dist/clauses.js.map +1 -0
  14. package/dist/cli.d.ts +34 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +162 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/errors.d.ts +19 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +66 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/executor.d.ts +25 -0
  23. package/dist/executor.d.ts.map +1 -0
  24. package/dist/executor.js +115 -0
  25. package/dist/executor.js.map +1 -0
  26. package/dist/index.d.ts +3 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +128 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/mermaid.d.ts +47 -0
  31. package/dist/mermaid.d.ts.map +1 -0
  32. package/dist/mermaid.js +197 -0
  33. package/dist/mermaid.js.map +1 -0
  34. package/dist/output.d.ts +24 -0
  35. package/dist/output.d.ts.map +1 -0
  36. package/dist/output.js +40 -0
  37. package/dist/output.js.map +1 -0
  38. package/dist/parser.d.ts +84 -0
  39. package/dist/parser.d.ts.map +1 -0
  40. package/dist/parser.js +1007 -0
  41. package/dist/parser.js.map +1 -0
  42. package/dist/prolog-parser.d.ts +2 -0
  43. package/dist/prolog-parser.d.ts.map +1 -0
  44. package/dist/prolog-parser.js +2 -0
  45. package/dist/prolog-parser.js.map +1 -0
  46. package/dist/renderer.d.ts +33 -0
  47. package/dist/renderer.d.ts.map +1 -0
  48. package/dist/renderer.js +131 -0
  49. package/dist/renderer.js.map +1 -0
  50. package/dist/wrapper.d.ts +30 -0
  51. package/dist/wrapper.d.ts.map +1 -0
  52. package/dist/wrapper.js +87 -0
  53. package/dist/wrapper.js.map +1 -0
  54. package/package.json +55 -0
  55. package/scripts/generate-build-info.js +63 -0
  56. package/scripts/release.js +151 -0
  57. package/tracer.pl +202 -0
package/tracer.pl ADDED
@@ -0,0 +1,202 @@
1
+ % Custom Prolog Tracer using prolog_trace_interception/4
2
+ % This tracer captures execution events and exports them as JSON
3
+
4
+ :- dynamic trace_event/1.
5
+ :- dynamic trace_active/0.
6
+
7
+ %% install_tracer/0
8
+ % Install the trace interception hook
9
+ install_tracer :-
10
+ asserta(trace_active),
11
+ trace.
12
+
13
+ %% remove_tracer/0
14
+ % Remove the trace interception hook and clean up
15
+ remove_tracer :-
16
+ notrace,
17
+ retractall(trace_active),
18
+ clear_trace.
19
+
20
+ %% clear_trace/0
21
+ % Clear all recorded trace events
22
+ clear_trace :-
23
+ retractall(trace_event(_)).
24
+
25
+ %% user:prolog_trace_interception(+Port, +Frame, +Choice, -Action)
26
+ % Hook predicate that intercepts trace events
27
+ user:prolog_trace_interception(Port, Frame, _Choice, continue) :-
28
+ trace_active,
29
+ !,
30
+ catch(
31
+ capture_trace_event(Port, Frame),
32
+ Error,
33
+ handle_trace_error(Error, Port, Frame)
34
+ ).
35
+ user:prolog_trace_interception(_, _, _, continue).
36
+
37
+ %% handle_trace_error(+Error, +Port, +Frame)
38
+ % Handle errors during trace event capture
39
+ handle_trace_error(Error, Port, Frame) :-
40
+ catch(
41
+ (
42
+ prolog_frame_attribute(Frame, goal, Goal),
43
+ prolog_frame_attribute(Frame, level, Level),
44
+ assertz(trace_event(event(Port, Level, Goal, error(Error), no_clause, unknown)))
45
+ ),
46
+ _,
47
+ assertz(trace_event(event(Port, 0, error_goal, error(Error), no_clause, unknown)))
48
+ ).
49
+
50
+ %% capture_trace_event(+Port, +Frame)
51
+ % Capture a trace event with all relevant information
52
+ capture_trace_event(Port, Frame) :-
53
+ prolog_frame_attribute(Frame, goal, Goal),
54
+ prolog_frame_attribute(Frame, level, Level),
55
+ functor(Goal, Name, Arity),
56
+ format(atom(Predicate), '~w/~w', [Name, Arity]),
57
+
58
+ % Extract arguments for exit port
59
+ ( Port = exit
60
+ -> extract_frame_arguments(Frame, Arity, Arguments)
61
+ ; Arguments = []
62
+ ),
63
+
64
+ % Extract clause information
65
+ extract_clause_info(Frame, Goal, ClauseInfo),
66
+
67
+ % Record the event
68
+ assertz(trace_event(event(Port, Level, Goal, Arguments, ClauseInfo, Predicate))).
69
+
70
+ %% extract_frame_arguments(+Frame, +Arity, -Arguments)
71
+ % Extract actual argument values from a frame
72
+ extract_frame_arguments(_, 0, []) :- !.
73
+ extract_frame_arguments(Frame, Arity, Arguments) :-
74
+ Arity > 0,
75
+ prolog_frame_attribute(Frame, goal, Goal),
76
+ Goal =.. [_|Args],
77
+ Arguments = Args.
78
+
79
+ %% extract_clause_info(+Frame, +Goal, -ClauseInfo)
80
+ % Extract clause information (head, body, line number) from a frame
81
+ extract_clause_info(Frame, Goal, clause(Head, Body, Line)) :-
82
+ catch(
83
+ (
84
+ prolog_frame_attribute(Frame, clause, ClauseRef),
85
+ ClauseRef \= 0,
86
+ clause(Head, Body, ClauseRef),
87
+ clause_property(ClauseRef, line_count(Line))
88
+ ),
89
+ _,
90
+ fail
91
+ ),
92
+ % Verify this clause matches the goal
93
+ subsumes_term(Head, Goal),
94
+ !.
95
+ extract_clause_info(_, _, no_clause).
96
+
97
+ %% export_trace_json(+File)
98
+ % Export all trace events as JSON
99
+ export_trace_json(File) :-
100
+ findall(Event, trace_event(Event), Events),
101
+ open(File, write, Stream),
102
+ write_json_events(Stream, Events),
103
+ close(Stream).
104
+
105
+ %% write_json_events(+Stream, +Events)
106
+ % Write events as JSON array
107
+ write_json_events(Stream, Events) :-
108
+ write(Stream, '[\n'),
109
+ write_events_list(Stream, Events),
110
+ write(Stream, '\n]').
111
+
112
+ %% write_events_list(+Stream, +Events)
113
+ % Write list of events with comma separation
114
+ write_events_list(_, []).
115
+ write_events_list(Stream, [Event]) :-
116
+ !,
117
+ write(Stream, ' '),
118
+ write_json_event(Stream, Event).
119
+ write_events_list(Stream, [Event|Rest]) :-
120
+ write(Stream, ' '),
121
+ write_json_event(Stream, Event),
122
+ write(Stream, ',\n'),
123
+ write_events_list(Stream, Rest).
124
+
125
+ %% write_json_event(+Stream, +Event)
126
+ % Write a single event as JSON object
127
+ write_json_event(Stream, event(Port, Level, Goal, Arguments, ClauseInfo, Predicate)) :-
128
+ format(Stream, '{', []),
129
+ format(Stream, '"port": "~w"', [Port]),
130
+ format(Stream, ', "level": ~w', [Level]),
131
+ format(Stream, ', "goal": ', []),
132
+ write_json_term(Stream, Goal),
133
+ format(Stream, ', "predicate": "~w"', [Predicate]),
134
+
135
+ % Write arguments if present (exit port)
136
+ ( Arguments \= []
137
+ -> format(Stream, ', "arguments": ', []),
138
+ write_json_list(Stream, Arguments)
139
+ ; true
140
+ ),
141
+
142
+ % Write clause info if present
143
+ ( ClauseInfo = clause(Head, Body, Line)
144
+ -> format(Stream, ', "clause": {', []),
145
+ format(Stream, '"head": ', []),
146
+ write_json_term(Stream, Head),
147
+ format(Stream, ', "body": ', []),
148
+ write_json_term(Stream, Body),
149
+ format(Stream, ', "line": ~w', [Line]),
150
+ format(Stream, '}', [])
151
+ ; true
152
+ ),
153
+
154
+ format(Stream, '}', []).
155
+
156
+ %% write_json_term(+Stream, +Term)
157
+ % Write a Prolog term as JSON string
158
+ write_json_term(Stream, Term) :-
159
+ format(atom(TermAtom), '~w', [Term]),
160
+ write_json_string(Stream, TermAtom).
161
+
162
+ %% write_json_string(+Stream, +Atom)
163
+ % Write an atom as JSON string with proper escaping
164
+ write_json_string(Stream, Atom) :-
165
+ atom_chars(Atom, Chars),
166
+ write(Stream, '"'),
167
+ write_escaped_chars(Stream, Chars),
168
+ write(Stream, '"').
169
+
170
+ %% write_escaped_chars(+Stream, +Chars)
171
+ % Write characters with JSON escaping
172
+ write_escaped_chars(_, []).
173
+ write_escaped_chars(Stream, [Char|Rest]) :-
174
+ ( Char = '"'
175
+ -> write(Stream, '\\"')
176
+ ; Char = '\\'
177
+ -> write(Stream, '\\\\')
178
+ ; Char = '\n'
179
+ -> write(Stream, '\\n')
180
+ ; Char = '\t'
181
+ -> write(Stream, '\\t')
182
+ ; write(Stream, Char)
183
+ ),
184
+ write_escaped_chars(Stream, Rest).
185
+
186
+ %% write_json_list(+Stream, +List)
187
+ % Write a list as JSON array
188
+ write_json_list(Stream, List) :-
189
+ write(Stream, '['),
190
+ write_json_list_items(Stream, List),
191
+ write(Stream, ']').
192
+
193
+ %% write_json_list_items(+Stream, +Items)
194
+ % Write list items with comma separation
195
+ write_json_list_items(_, []).
196
+ write_json_list_items(Stream, [Item]) :-
197
+ !,
198
+ write_json_term(Stream, Item).
199
+ write_json_list_items(Stream, [Item|Rest]) :-
200
+ write_json_term(Stream, Item),
201
+ write(Stream, ', '),
202
+ write_json_list_items(Stream, Rest).