-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathssi.pl
547 lines (416 loc) · 18.8 KB
/
ssi.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
%% ssi.pl
%% State Saving Interpreter
%%
%% Introduces retry in trace
%% convert alg to state machine (sm)
%% it is a nondeterministic (nd) state machine, i.e. it has forks between parts of the sm if there are nd choices left or it has failed a clause, with backtracking to the last choice point on the line - predicates and clauses are signposted in the sm
%% predicates, clauses and individual predicate sms
%% - predicates and clauses sms are separate because the sm goes from one predicate to next x only clauses not predicates sm x predicates sm as well because they are separate but have back-connection origin values that make temporary parts of (a separate) state machine that correspond to level numbers in the trace x there are sm links from ends of predicates to where the predicate was called from
%% clauses in clauses sms catch fails from previous clauses
%% try without recursion at first
%% x sm not nec, just scope ds with var, (recursive states x) nd states
%% - can fail predicate that doesn't call another predicate, then try another predicate
%% on if then, goes to other clause if fails, etc.
%% unique number for every line of program
%% line (from command) to rectangle (e.g. predicate)
%% track list for backtracking
%% 1 predicate number, 1,2 line number or bracketed part, etc.
%% - failed predicates removed from track list
%% doesn't need to split predicates in half to turn algorithms into web services
%% a :- b, c. not a:-a.
%% a(1,1,Result):- Result is 1+1.
/**
crop down pred from top x just goes to next command
- sets up antecedant(s) in if, not, or if, brackets backtracks to it
- x based on states, it continues on from antecedants
**/
%% find called line
%% find next line
%% - go to next numbered line if in brackets, etc.
%% - if last line of brackets
%% - if antecedent that is true, ..., vv
%% if fails, returns to last choice point
%:-include('listprologinterpreter1listrecursion4.pl'). % enabling these 3 causes a hang on loading
%:-include('listprologinterpreter3preds5.pl').
%:-include('grammar.pl').
%:-include('../../../GitHub/listprologinterpreter/lpiverify4.pl').
%:-include('ssi_find_state_machine.pl').
%ssi_verify(Debug,N) :-
% test(N,Query,Functions,Result),
% ssi(Debug,Query,Functions,Result).
%:-include('interpretstatement3.pl').
:-include('ssi-api.pl').
:-include('interpretstatement3.pl').
:-include('../listprologinterpreter/listprolog.pl').
:-include('find_pred_sm.pl').
:-include('ssi_find_state_machine.pl').
%:-include('find_types_sm.pl').
%:-include('go_forward_or_backtrack.pl').
:-include('ssi3.pl').
:-include('ssi_verify4_test_lang_all.pl').
:-include('ssi_verify4.pl').
:-include('ssi_verify4_types.pl').
:-include('ssi_verify4_test_bt_lang_all.pl').
:-include('ssi_verify4_open.pl').
:-include('ssi_verify4_open_types.pl').
:-include('ssi_listrecursion4.pl').
:-include('ssi_3preds5.pl').
:-include('d.pl').
:-include('e.pl').
:-include('cp_since_findall_start2.pl').
:-include('pred_minus_three.pl').
:-include('pred_minus_one_fail2.pl').
:-include('flush_after_last_findall').
:-include('process_cp.pl').
:-include('end_nested_findall.pl').
:-include('used_by_call_command.pl').
:-include('sessions.pl').
:-include('ssi-api-key.pl').
%:-include('replace_in_term.pl').
%:-include('local_and_global_cp_trails.pl').
:-include('optimisations.pl').
:-include('only_ssi_verify4.pl').
:-include('ssi_verify_pl.pl').
:- dynamic debug2/1.
:- dynamic debug3/1.
:- dynamic debug4/1.
:- dynamic retry_back/1.
:- dynamic retry_back_stack/1.
:- dynamic retry_back_stack_n/1.
:- dynamic cumulative_or_current_text/1.
:- dynamic number_of_current_text/1.
:- dynamic html_api_maker_or_terminal/1.
:- dynamic session_number/1.
%:- dynamic screen_text/1.
%:- dynamic curr_screen_text/1.
:- dynamic pred_numbers/1.
%:- dynamic curr_cp/1.
:- dynamic curr_cp_index/1.
:- dynamic pred_id/1.
:- dynamic types/1.
:- dynamic typestatements/1.
:- dynamic modestatements/1.
main2:-
time((
only_ssi_test(off,NTotal1,Score1),
ssi_test_all00("en",off,NTotal2,Score2),
ssi_test_all00("en2",off,NTotal3,Score3),
ssi_test_all_bt00("en2",off,NTotal4,Score4),
writeln(only_ssi_test(off,NTotal1,Score1)),
writeln(ssi_test_all00("en",off,NTotal2,Score2)),
writeln(ssi_test_all00("en2",off,NTotal3,Score3)),
writeln(ssi_test_all_bt00("en2",off,NTotal4,Score4)))).
%:- dynamic hidden/1.
/*
ssi(Debug,Query,Functions1,Result) :-
%load_lang_db, % * check this is done once for whole ssi
retractall(debug(_)),
assertz(debug(Debug)),
convert_to_grammar_part1(Functions1,[],Functions2,_),
add_line_numbers_to_algorithm1(Functions2,Functions2a),
%%writeln1(Functions2a),
find_pred_sm(Reserved_words1),%,"en"),
find_pred_numbers(Functions2a,Reserved_words,Pred_numbers),
find_state_machine1(Functions2a,Functions3,Pred_numbers),
%%writeln1(Functions3),
prep_predicate_call(Query,Functions3,
All_predicate_numbers),
ssi1([1,1,"predicate",Query,[],
All_predicate_numbers],Functions3,[],Result,[],_Choice_point_trail).
*/
prep_predicate_call(Query,Functions3,All_predicate_numbers) :-
%writeln(prep_predicate_call(Query,Functions3,All_predicate_numbers)),
%trace,
Query=[Name|Arguments1],
(Arguments1=[]->Arguments_length=0;
(Arguments1=[Arguments3],
length(Arguments3,Arguments_length))),
findall(Predicate_number1,
(
%member([Predicate_number1,Name|
% [Arguments2|_]],Functions3),
%length(Arguments2,Arguments_length)
get_lang_word("n",Dbw_n1),Dbw_n1=Dbw_n,
get_lang_word("true",Dbw_true1),Dbw_true1=Dbw_true,
member([Predicate_number1,Name|Rest],Functions3),
(Rest=[Args,":-",Lines]->length(Args,Arguments_length);
(Rest=[Args]->(Lines=[[[Dbw_n,Dbw_true]]],length(Args,Arguments_length));
(Rest=[":-",Lines]->Arguments_length=0;
(Rest=[],Lines=[[[Dbw_n,Dbw_true]]],Arguments_length=0))))
),
All_predicate_numbers).
add_line_numbers_to_algorithm1(Algorithm1,Algorithm2) :-
add_line_numbers_to_algorithm2(Algorithm1,[],Algorithm2,0,_).
add_line_numbers_to_algorithm2([],Algorithm,Algorithm,N,N) :- !.
add_line_numbers_to_algorithm2(Algorithm1,Algorithm2,Algorithm3,Number1,Number2) :-
get_lang_word("n",Dbw_n1),Dbw_n1=Dbw_n,
get_lang_word("true",Dbw_true1),Dbw_true1=Dbw_true,
Algorithm1=[Function1|Functions],
((Function1=[Name,Arguments1,Symbol1,Body1],symbol(Symbol1,Symbol2),
findall(Arguments3,(member(Arguments2,Arguments1),slp2lp_variables(Arguments2,Arguments3)),Arguments4),
%Number1a is Number1+1,
add_line_numbers_to_algorithm_body2(Body1,Body2,0,_),
append(Algorithm2,[[Number1,Name,Arguments4,Symbol2,Body2]],Algorithm4))->true;
((Function1=[Name,Symbol1,Body1],symbol(Symbol1,Symbol2),
%Number1a is Number1+1,
add_line_numbers_to_algorithm_body2(Body1,Body2,0,_),
append(Algorithm2,[[Number1,Name,[],Symbol2,Body2]],Algorithm4))->true;
((Function1=[Name,Arguments1],symbol(":-",Symbol2),
findall(Arguments3,(member(Arguments2,Arguments1),slp2lp_variables(Arguments2,Arguments3)),Arguments4),
add_line_numbers_to_algorithm_body2([[[Dbw_n,Dbw_true]]],Body2,0,_),
append(Algorithm2,[[Number1,Name,Arguments4,Symbol2,Body2]],Algorithm4))->true;
(Function1=[Name],symbol(":-",Symbol2),
add_line_numbers_to_algorithm_body2([[[Dbw_n,Dbw_true]]],Body2,0,_),
append(Algorithm2,[[Number1,Name,[],Symbol2,Body2]],Algorithm4))->true;
% [":-", [n, include], ['../b/b.pl']]
((Function1=[Symbol2,Name,Arguments1],symbol(":-",Symbol2),
findall(Arguments3,(member(Arguments2,Arguments1),slp2lp_variables(Arguments2,Arguments3)),Arguments4),
add_line_numbers_to_algorithm_body2([[[Dbw_n,Dbw_true]]],Body2,0,_),
append(Algorithm2,[[Number1,Symbol2,Name,Arguments4,Body2]],Algorithm4)))))),
Number1a is Number1+1,
%%writeln1([Number1,Name,Arguments4,Symbol2,Body2]),
add_line_numbers_to_algorithm2(Functions,Algorithm4,Algorithm3,Number1a,Number2).
symbol(Symbol,Symbol) :-!.
%%slp2lp_variables(Name1,[v,Name1]) :- predicate_or_rule_name(Name1),!.
slp2lp_variables(Name,Name) :- !.
/**
add_line_numbers_to_algorithm_body(Body1,Body2) :-
findall(*,(member(Statement1,Body1
add_line_numbers_to_algorithm_body(Body1,[],Body2) :-
**/
%%predicate_or_rule_name([A,B]) :- atom(A),is_list(B),!.
predicate_or_rule_name([V_or_n,_Name]) :- get_lang_word("n",Dbw_n1),Dbw_n1=Dbw_n,
get_lang_word("v",Dbw_v1),Dbw_v1=Dbw_v,
(V_or_n=Dbw_v->true;V_or_n=Dbw_n),!.%%,atom(Name),!.
%% x: predicate_or_rule_name(V_or_n) :- (V_or_n=v->true;V_or_n=n),fail,!.
add_line_numbers_to_algorithm_body2([],[],N,N):-!.%%,Body3
%%add_line_numbers_to_algorithm_body2([],Body,Body) :- !.
add_line_numbers_to_algorithm_body2(Body1,Body2%%,Body3
,Number1,Number2) :-
get_lang_word("n",Dbw_n1),Dbw_n1=Dbw_n,
Body1=[[Statements1|Statements1a]|Statements2
],
not(predicate_or_rule_name(Statements1)),
Number1a is Number1+1,
add_line_numbers_to_algorithm_body2([Statements1],Body3,Number1a,Number3), %% 2->1
add_line_numbers_to_algorithm_body2(Statements1a,Body4,Number3,Number4),
add_line_numbers_to_algorithm_body2(Statements2,Body5,Number4,Number2),
%% append([Body3,Body4],Body6),
%% append([[Body6],Body5],Body2),
append(Body3,Body4,Body34),
Body6=[Number1,[Dbw_n,"[]"],Body34
],
append([Body6],Body5,Body2),
!.
add_line_numbers_to_algorithm_body2(Body1,Body2,Number1,Number2) :-
get_lang_word("n",Dbw_n1),Dbw_n1=Dbw_n,
get_lang_word("not",Dbw_not1),Dbw_not1=Dbw_not,
Body1=[[[Dbw_n,Dbw_not],Statement]|Statements2 %% [] removed from Statement
],
Number1a is Number1+1,
add_line_numbers_to_algorithm_body2(Statement,Body3,Number1a,Number3),
add_line_numbers_to_algorithm_body2(Statements2,Body4,Number3,Number2),
%trace,
append([Number1,%%*,
[Dbw_n,Dbw_not]],Body3,Body5),
append([Body5],Body4
,Body2),
!.
add_line_numbers_to_algorithm_body2(Body1,Body2,Number1,Number2) :-
get_lang_word("n",Dbw_n1),Dbw_n1=Dbw_n,
get_lang_word("or",Dbw_or1),Dbw_or1=Dbw_or,
Body1=[[[Dbw_n,Dbw_or],[Statements1,Statements2]]|Statements3],
Number1a is Number1+1,
add_line_numbers_to_algorithm_body2([Statements1],Body3,Number1a,Number3),
add_line_numbers_to_algorithm_body2([Statements2],Body4,Number3,Number4),
add_line_numbers_to_algorithm_body2(Statements3,Body5,Number4,Number2),
append(Body3,Body4,Body34),
Body6=[Number1,[Dbw_n,Dbw_or],Body34
],
append([Body6],Body5,Body2),
!.
add_line_numbers_to_algorithm_body2(Body1,Body2,Number1,Number2) :-
get_lang_word("n",Dbw_n1),Dbw_n1=Dbw_n,
Body1=[[[Dbw_n,"->"],[Statements1,Statements2]]|Statements3],
Number1a is Number1+1,
add_line_numbers_to_algorithm_body2([Statements1],Body3,Number1a,Number3),
add_line_numbers_to_algorithm_body2([Statements2],Body4,Number3,Number4),
add_line_numbers_to_algorithm_body2(Statements3,Body5,Number4,Number2),
append(Body3,Body4,Body34),
Body6=[Number1,[Dbw_n,"->"],Body34
],
append([Body6],Body5,Body2),
!.
add_line_numbers_to_algorithm_body2(Body1,Body2,Number1,Number2) :-
get_lang_word("n",Dbw_n1),Dbw_n1=Dbw_n,
Body1=[[[Dbw_n,"->"],[Statements1,Statements2,Statements2a]]|Statements3],
Number1a is Number1+1,
add_line_numbers_to_algorithm_body2([Statements1],Body3,Number1a,Number3),
add_line_numbers_to_algorithm_body2([Statements2],Body4,Number3,Number4),
%%trace,
add_line_numbers_to_algorithm_body2([Statements2a],Body5,Number4,Number5),
add_line_numbers_to_algorithm_body2(Statements3,Body6,Number5,Number2),
append_list2([Body3,Body4,Body5],Body345),
Body7=[Number1,[Dbw_n,"->"],Body345],
append([Body7],Body6,Body2),
!.
add_line_numbers_to_algorithm_body2(Body1,Body2,Number1,Number2) :-
Body1=[Statement|Statements],
not(predicate_or_rule_name(Statement)),
add_line_numbers_to_algorithm_statement1(Statement,Result1,Number1,Number3),
add_line_numbers_to_algorithm_body2(Statements,Result2,Number3,Number2),
append_list2([Result1,Result2],Body2),!.
add_line_numbers_to_algorithm_statement1(Statement,Result1,Number1,Number2) :-
get_lang_word("n",Dbw_n1),Dbw_n1=Dbw_n,
get_lang_word("findall",Dbw_findall1),Dbw_findall1=Dbw_findall,
((Statement=[[Dbw_n,Dbw_findall],[Arguments1,Arguments2,Arguments3]],
%Arguments=Result2,
%trace,
Number1a is Number1+1,
add_line_numbers_to_algorithm_body2([Arguments2],Body3,Number1a,Number2),
%%*** [Arguments2] to Arguments2
%findall(Argument,(member(Argument,Arguments),(predicate_or_rule_name(Argument))),Result2),
Result1=[[Number1,[Dbw_n,Dbw_findall],[Arguments1,Arguments3,Body3]]])).
/*
add_line_numbers_to_algorithm_statement1(Statement,Result1,Number1,Number2) :-
((Statement=[[n,maplist],[Arguments1,Arguments2,Arguments3,Arguments4]],
%Arguments=Result2,
%trace,
Number1a is Number1+1,
add_line_numbers_to_algorithm_body2([Arguments1],Body3,Number1a,Number2),
%findall(Argument,(member(Argument,Arguments),(predicate_or_rule_name(Argument))),Result2),
Result1=[[Number1,[n,maplist],[Arguments2,Arguments3,Arguments4,Body3]]])).
*/
add_line_numbers_to_algorithm_statement1(Statement,Result1,Number1,Number2) :-
get_lang_word("n",Dbw_n1),Dbw_n1=Dbw_n,
get_lang_word("findall",Dbw_findall1),Dbw_findall1=Dbw_findall,
%(Statement=[[n,cut]]->trace;true),
((Statement=[[Dbw_n,Name],Arguments],
not(Name=Dbw_findall),
Arguments=Result2,
%findall(Argument,(member(Argument,Arguments),(predicate_or_rule_name(Argument))),Result2),
Result1=[[Number1,[Dbw_n,Name],Result2]])->true;
(Statement=[[Dbw_n,Name]],
Result1=[[Number1,[Dbw_n,Name],[]]])),
Number2 is Number1+1.
add_line_numbers_to_algorithm_statement1(Statement,Result1,Number1,Number2) :-
get_lang_word("v",Dbw_v1),Dbw_v1=Dbw_v,
((Statement=[[Dbw_v,Name],Arguments],
%not(Name=findall),
Arguments=Result2,
%findall(Argument,(member(Argument,Arguments),(predicate_or_rule_name(Argument))),Result2),
Result1=[[Number1,[Dbw_v,Name],Result2]])->true;
(Statement=[[Dbw_v,Name]],
Result1=[[Number1,[Dbw_v,Name],[]]])),
Number2 is Number1+1.
%%*del:Functions2,
%% *** don't worry about sublevels, just level numbers x
%ssi0
% newer than comments in next section:
% go to types, pred or lines pred
% - whether this pred determines which to go to, or it is already decided x
% - * sm connects types at start - no call/exit preds, just goes to next item in sm,
% - types sm creator - checks types (do non types sm first)
% - * sm of preds (to clauses from calls, allowing backtracking)
% - whether need call and exit preds, or do anyway x
/**
ssi1([Level,Sublevel,"predicate",Query,Predicate_numbers_finished,All_predicate_numbers],Functions1,Result1,Result2,Choice_point_trail1,Choice_point_trail2) :-
append(Predicate_numbers_finished,Curr_predicate_queue,All_predicate_numbers),
(Curr_predicate_queue=[]->
(% No other clauses of this predicate to try
% add to cps
append(Choice_point_trail1,[[Level,Sublevel,"predicate",Query,Predicate_numbers_finished,All_predicate_numbers]],Choice_point_trail3),
%call first line
%*
% when reach last line:
%predicate finished, no more results from it
% if level 1 end x, call prev cp
%- if not level 1 call prev lev - find var state of last line of prev lev - update vars
%
)
;(
% Some clauses of this predicate left to try
% add to cps
% call first line of pred,
% when reach last line, call next clause (dup vars *(one list for old results, one for curr results x label var results with cp, *sublevel at least x, also need ()x-predicate and line numbers*), add to new var list, delete cps back to pred call)
% * var results/cps saved from where began when try each clause, deleted back until and to when trying and failing respectively
)),
% * return from call-header to call first line x check types without being called by pred header (do separately)
% * check types separately (and call, exit separately) from pred, line (after pred)
% when call a pred from a line, use lpi_list_rec find_result etc
% * predicates and lines have separate call and exit/fail preds
% * second sm for types, pred, lines
% when retries, deletes vars, cps up to and not including that call (*cps have sublevel to delete back until)
call_first_line1() :-
query_to_vars(),
Sublevel2 is Sublevel1+1,
ssi1([Level,Sublevel2,"line",1, % line number
Query*,Predicate_numbers_finished,All_predicate_numbers],Functions1,Result1,Result2,Choice_point_trail1,Choice_point_trail2),
query_to_vars(Query,) :-
%****
find_called_lines(Query,Functions1,Predicate_numbers),
ssi_call(Query,Functions1,Predicate_numbers,Result1),
true.
**/
/*
find_called_lines(Query,Functions1,Predicate_numbers) :-
findall(Number1,(Query=[Name|Arguments1],
length(Arguments1,Arguments_length),
member([Number1,Name|Arguments2],Functions1),
(Arguments2=[Arguments3,":-",_Body1]->true;
(Arguments2=[":-",_Body2]->Arguments3=[];
(Arguments2=[Arguments3]->true;
(Arguments2=[]->Arguments3=[])))),
length(Arguments3,Arguments_length)),Predicate_numbers).
ssi_call(Query,Functions1,Predicate_numbers,Vars21) :- %% ** added vars21
findall(Vars2,(member(Predicate_number,Predicate_numbers),
%% *** findall xx
member([Predicate_number,_|Arguments2],Functions1),
Query=[Name|Arguments1], % Name,Arguments1 -> Name|Arguments1
%% checktypes_inputs(Name,Arguments1)
(Arguments2=[Arguments3,":-",Body]->true;
(Arguments2=[":-",Body]->Arguments3=[];
(Arguments2=[Arguments3]->Body=[];
(Arguments2=[]->(Arguments3=[],Body=[]))))),
checkarguments(Arguments1,Arguments3,[],Vars1,[],FirstArgs),
%% debug_call(Skip,[Name,Arguments1]),
%% find first line to run, keeping track list of command numbers gone past
find_first_line_to_run(Body,Vars1,Vars2)),Vars21),
%run_line
true.
%% find called line
%% find next line
%% - go to next numbered line if in brackets, etc.
%% - if last line of brackets
%% - if antecedent that is true, ..., vv
%% if fails, returns to last choice point
find_first_line_to_run([],Vars,Vars) :- !.
*/
%%find_first_line_to_run(Body,Vars1,Vars2) :-
%% line 0, - easy to find
%% usually for next line finds structure of pred,
%% finds next line
%% find_next_line_to_run (Predicate_number,Previous_line_number) :-
%% Predicate_number= ...
%% Previous_line_number = -1 if just called the predicate
%% pass nondeterminism, recursion, variable states
%% exit status of previous line, e.g. fail so backtrack
%% go to line+1 if in body, different if in different body structure, different if in consequent 1 of 2 consequents of statement
%% as goes, record line numbers to go to when reach a line number based on if then, work these out when at start, delete these x
%% predicate line -2 is return from predicate
%% later: check for singleton in branch
%% if goes past choice-point (e.g. member, some function calls) add it on to stack
%% recursion is found as go
/**
Predicate line
0 for first line
-1 if just called the predicate
-2 to return from predicate
-3 if failed the predicate
**/
/*
find_next_line_to_run(Predicate_number,-1) :-
run(Predicate_number,0),!.
find_next_line_to_run(Predicate_number,Previous_line_number) :-
true.
*/