DEV Community

Lucian Green
Lucian Green

Posted on • Edited on

NeuroProlog + Starlog Demo

NeuroProlog and Starlog

Courtesy of ChatGPT.

1. Load Starlog


bash
cd /path/to/Starlog
swipl
?- use_module(starlog).
true.

⸻

2. Starlog string concatenation

?- starlog_call(A is "x":"y").
A = "xy".

⸻

3. Starlog list append

?- starlog_call(L is [1] & [2]).
L = [1, 2].

⸻

4. Starlog atom concatenation

?- starlog_call(A is a • b).
A = ab.

⸻

5. Starlog arithmetic

?- starlog_call(X is 1+2).
X = 3.

⸻

6. Starlog nested functions

?- starlog_call(X is reverse(reverse([1,2,3]))).
X = [1, 2, 3].
?- starlog_call(X is length(reverse([1,2,3]))).
X = 3.

⸻

7. Starlog method chaining

?- starlog_call(R is reverse([1,2,3]) >> length).
R = 3.
?- starlog_call(R is ([1,2] & [3,4]) >> reverse >> length).
R = 4.

⸻

8. Starlog evaluation

?- starlog_eval("hello":"world", R).
R = "helloworld".
?- starlog_eval([a] & [b,c], R).
R = [a, b, c].

⸻

9. Starlog no-eval

?- starlog_no_eval(1+1, R).
R = 1+1.
?- starlog_no_eval("x":"y", R).
R = "x":"y".

⸻

10. Starlog forced eval inside no-eval

?- starlog_call(R is no_eval(eval(1+1) + 3)).
R = 2+3.

⸻

11. Starlog result capture

?- starlog_call(X is "hello":"world", R).
R = "helloworld".
?- starlog_call(Y is [1,2] & [3,4], R).
R = [1, 2, 3, 4].

⸻

12. Starlog dual expression solving

?- starlog_call(([1] & A) is (B & [2])).
A = [2],
B = [1].
?- starlog_call((A : a : C) is (b : a : c)).
A = b,
C = c.

⸻

13. Starlog find first solution

?- starlog_call(Result is find(X, member(X, [1,2,3]))).
Result = 1.
?- starlog_call(Result is find(R, starlog_call(R is "hello":"world"))).
Result = "helloworld".

⸻

14. Starlog find with pattern extraction

?- starlog_call(Result is find([A,C], starlog_call([A:a:C] is [a:a:c]))).
Result = [a, c].
?- starlog_call(Result is find([A,C], starlog_call([A:"_":C] is ["hello":"_":"world"]))).
Result = ["hello", "world"].

⸻

15. Starlog term construction

?- starlog_call(T is ..=([f,0,1])).
T = f(0, 1).
?- starlog_call(L is =..(f(0,1))).
L = [f, 0, 1].

⸻

16. Starlog expansion inspection

?- starlog_show_expansion(A is "x":"y").
string_concat("x", "y", A).

⸻

17. Starlog output code

?- starlog_output_code(string_concat("x","y",A), Code).
Code = (A is "x":"y").

⸻

18. Starlog Prolog-to-Starlog conversion

?- convert_prolog_to_starlog(string_concat("x","y",A), Starlog).
Starlog = (A is "x":"y").
?- convert_prolog_to_starlog(append([1],[2],L), Starlog).
Starlog = (L is [1]&[2]).

⸻

19. Starlog Gaussian elimination

Load the Gaussian module:

?- use_module(gaussian_elimination).
true.

Solve:

x + y = 2
2x + 3y = 5
?- solve_system([[1,1,2],[2,3,5]], Solution).
Solution = [1, 1].

⸻

20. Starlog row reduction

?- gaussian_elimination([[1,1,2],[2,3,5]], R).
R = [[1,1,2],[0,1,1]].

⸻

21. Starlog polynomial reconstruction

?- npl_reconstruct_polynomial(n, [0,0.5,0.5], Expr).
Expr = n*(n+1)/2.

⸻

22. Starlog polynomial validation

?- npl_validate_polynomial_fit([1-1,2-3,3-6], [0,0.5,0.5], n, Result).
Result = valid.

⸻

23. Starlog symbolic indexing

?- npl_assign_symbolic_indices([a,b,c], Indexed, Map).
Indexed = indexed([a,b,c]),
Map = map(_).

⸻

24. Starlog reduce goal to irreducibles

?- npl_reduce_predicate_to_pattern_irreducibles((member(X,[1,2]), X > 0), R).
R = reduced(sequence(_, _)).

⸻

25. Starlog trace index flow

?- npl_assign_symbolic_indices([a,b,c], Indexed, Map),
   npl_trace_index_flow(member(X,[a,b,c]), Map, Flow).
Indexed = indexed([a,b,c]),
Map = map(_),
Flow = flow_graph(_, _, _, trace(_)).

⸻

26. Starlog identify independent indices

?- npl_identify_independent_indices(flow([x-1,y-2]), Indices).
Indices = [i].

⸻

27. Starlog reconstruct index relations

?- npl_reconstruct_index_relations(flow([x-[1,2,3], y-[4,5,6]]), [i], Relations).
Relations = [_].

⸻

28. Starlog direct indexed rule

?- npl_reconstruct_direct_indexed_rule([x-(i+1)], [i], Rule).
Rule = direct_index_rule([x-(i+1)], coefficient_metadata([i])).

⸻

29. Starlog Stage 8 pipeline order

?- npl_stage8_pipeline_order(Order).
Order = [
  symbolic_index_assignment,
  pattern_irreducible_reduction,
  index_flow_tracing,
  independent_index_detection,
  relation_reconstruction,
  ir_build,
  ir_lowering
].

⸻

30. Starlog Stage 8 build IR

?- npl_stage8_build_ir(flow([]), [i], [x-(i+1)], [0,1], [], IR).
IR = ir_pipeline(_, _, meta(_)).

⸻

31. Starlog Stage 8 lower IR

?- IR = ir_pipeline([], [ir_poly_eval(n,[0,0.5,0.5],result)], meta([])),
   npl_stage8_lower_ir(IR, Lowered).
Lowered = lowered_ir([lowered_poly_eval(n, [0,0.5,0.5], result)]).

⸻

32. Starlog Stage 9 code generation

?- IR = lowered_ir([lowered_poly_eval(n, [0,0.5,0.5], result)]),
   npl_stage9_generate_code(IR, Code).
Code = generated_program([assign(result, n*(n+1)/2)]).

⸻

33. Starlog Stage 9 neurocode emission

?- IR = lowered_ir([lowered_poly_eval(n, [0,0.5,0.5], result)]),
   npl_stage9_emit_neurocode(IR, Neurocode).
Neurocode = neurocode([neuro_assign(result, n*(n+1)/2)]).

⸻

34. Starlog Stage 9 compile IR

?- IR = lowered_ir([lowered_poly_eval(n, [0,0.5,0.5], result)]),
   npl_stage9_compile_ir(IR, Neurocode).
Neurocode = neurocode([neuro_assign(result, n*(n+1)/2)]).

⸻

35. Starlog annotated source text

?- IR = lowered_ir([lowered_poly_eval(n, [0,0.5,0.5], result)]),
   Context = [source_file('examples/generated_input.pl'),
              optimisation_report('stage9_codegen')],
   npl_ir_to_annotated_source_text(IR, Context, Text).
Text = "...".

⸻

36. Starlog annotated source file

?- IR = lowered_ir([direct_index_rule(index_spec([i]),
                                      [x-(i+1)],
                                      result_collector(rows))]),
   Context = [source_file('examples/generated_input.pl')],
   npl_ir_to_annotated_source_file(IR, Context, 'out/annotated_stage9.pl').
true.

⸻

37. Starlog Stage 10 integration option

?- npl_stage10_integration_option(Option).
Option = option_b_port_and_align.
?- npl_stage10_gaussian_canonical_repository(Repo).
Repo = starlog.

⸻

38. Starlog Stage 12 transform decision

?- npl_stage12_transform_decision([deterministic, proven_equivalent, coefficients_valid], Decision).
Decision = transform.
?- npl_stage12_transform_decision([side_effecting], Decision).
Decision = do_not_transform.

⸻

39. Starlog Stage 13 toggleable passes

?- npl_stage13_toggleable_passes(Passes).
Passes = [
  pass(gaussian_elimination, true),
  pass(recursion_to_loop, true),
  pass(subterm_index_optimisation, true),
  pass(annotated_regeneration, true)
].

⸻

40. Starlog Stage 13 effective toggles

?- npl_stage13_effective_pass_toggles([pass(gaussian_elimination,false)], Toggles).
Toggles = [
  pass(gaussian_elimination, false),
  ...
].

⸻

NeuroProlog commands

41. Load NeuroProlog

cd /path/to/neuroprolog
swipl
?- consult('src/neuroprolog').
true.

⸻

42. Load main optimisation modules

?- use_module('src/gaussian_recursion').
true.
?- use_module('src/memoisation').
true.
?- use_module('src/subterm_addressing').
true.
?- use_module('src/nested_recursion').
true.
?- use_module('src/optimiser').
true.
?- use_module('src/optimiser_pipeline').
true.

⸻

43. Full optimiser

?- IR = [ir_clause(p, ir_seq(ir_true, ir_call(q)), info([]))],
   npl_optimise(IR, OptIR).
IR = [ir_clause(p, ir_seq(ir_true, ir_call(q)), info([]))],
OptIR = [ir_clause(p, ir_call(q), info([]))].
?- IR = [ir_clause(p, ir_disj(ir_fail, ir_call(q)), info([]))],
   npl_optimise(IR, OptIR).
IR = [ir_clause(p, ir_disj(ir_fail, ir_call(q)), info([]))],
OptIR = [ir_clause(p, ir_call(q), info([]))].
?- IR = [ir_clause(p, ir_if(ir_true, ir_call(q), ir_call(r)), info([]))],
   npl_optimise(IR, OptIR).
IR = [ir_clause(p, ir_if(ir_true, ir_call(q), ir_call(r)), info([]))],
OptIR = [ir_clause(p, ir_call(q), info([]))].

⸻

44. Compile a file

?- npl_compile('examples/hello.pl', 'neurocode/hello_nc.pl').
true.

⸻

45. Compile with pipeline config

?- npl_pipeline_default_config(Cfg),
   npl_compile_with_pipeline('examples/lists.pl', 'neurocode/lists_nc.pl', Cfg).
Cfg = ...,
true.

⸻

46. Safe compile

?- npl_compile_safe('examples/lists.pl', 'neurocode/lists_safe_nc.pl').
true.

⸻

47. Pipeline config

?- npl_pipeline_default_config(Cfg).
Cfg = ...

⸻

48. Disable a pass

?- npl_pipeline_default_config(Cfg0),
   npl_pipeline_disable(gaussian_elimination, Cfg0, Cfg1).
Cfg0 = ...,
Cfg1 = ...

⸻

49. Enable a pass

?- npl_pipeline_default_config(Cfg0),
   npl_pipeline_enable(subterm_address_conversion, Cfg0, Cfg1).
Cfg0 = ...,
Cfg1 = ...

⸻

50. Run pipeline manually

?- npl_pipeline_default_config(Cfg),
   IR = [ir_clause(p, ir_seq(ir_true, ir_call(q)), info([]))],
   npl_pipeline_run(Cfg, IR, OptIR, Report).
Cfg = ...,
OptIR = [ir_clause(p, ir_call(q), info([]))],
Report = ...

⸻

51. Run full pipeline

?- npl_pipeline_default_config(Cfg),
   IR = [ir_clause(p, ir_seq(ir_true, ir_call(q)), info([]))],
   npl_pipeline_run_full(Cfg, IR, OptIR, Neurocode, Report).
Cfg = ...,
OptIR = [ir_clause(p, ir_call(q), info([]))],
Neurocode = ...,
Report = ...

⸻

52. Dictionary simplification rules

?- npl_opt_dict_rules(Rules).
Rules = ...

⸻

53. Apply dictionary rules

?- IR = [ir_clause(test, ir_seq(ir_true, ir_call(goal)), info([]))],
   npl_opt_dict_rules(Rules),
   npl_apply_rules(Rules, IR, OptIR).
IR = [ir_clause(test, ir_seq(ir_true, ir_call(goal)), info([]))],
Rules = ...,
OptIR = [ir_clause(test, ir_call(goal), info([]))].
?- IR = [ir_clause(test, ir_disj(ir_fail, ir_call(goal)), info([]))],
   npl_opt_dict_rules(Rules),
   npl_apply_rules(Rules, IR, OptIR).
IR = [ir_clause(test, ir_disj(ir_fail, ir_call(goal)), info([]))],
Rules = ...,
OptIR = [ir_clause(test, ir_call(goal), info([]))].
?- IR = [ir_clause(test, ir_if(ir_true, ir_call(a), ir_call(b)), info([]))],
   npl_opt_dict_rules(Rules),
   npl_apply_rules(Rules, IR, OptIR).
IR = [ir_clause(test, ir_if(ir_true, ir_call(a), ir_call(b)), info([]))],
Rules = ...,
OptIR = [ir_clause(test, ir_call(a), info([]))].

⸻

54. Gaussian recursion classification

?- Group = [
      ir_clause(count(0), ir_true, info([])),
      ir_clause(count(N),
                ir_seq(ir_call(gt(N,0)),
                       ir_seq(ir_call(is(N1,N-1)),
                              ir_call(count(N1)))),
                info([]))
   ],
   npl_is_reducible(Group, Pattern).
Group = [...],
Pattern = linear_tail_recursion.

⸻

55. Gaussian recursion reduction

?- Group = [
      ir_clause(sum([],0), ir_true, info([])),
      ir_clause(sum([H|T],S),
                ir_seq(ir_call(sum(T,S1)),
                       ir_call(is(S, +(S1,H)))),
                info([]))
   ],
   npl_gaussian_reduce(Group, Reduced).
Group = [...],
Reduced = ...

⸻

56. Gaussian elimination matrix

?- Matrix = [
      [frac(1,1), frac(1,1), frac(2,1)],
      [frac(2,1), frac(3,1), frac(5,1)]
   ],
   npl_gauss_eliminate(Matrix, R).
Matrix = [[frac(1,1), frac(1,1), frac(2,1)],
          [frac(2,1), frac(3,1), frac(5,1)]],
R = ...

Expected mathematical output:

x = 1
y = 1

⸻

57. Gaussian polynomial discovery

?- Matrix = [
      [frac(1,1), frac(1,1), frac(1,1), frac(1,1)],
      [frac(4,1), frac(2,1), frac(1,1), frac(3,1)],
      [frac(9,1), frac(3,1), frac(1,1), frac(6,1)]
   ],
   npl_gauss_eliminate(Matrix, R).
Matrix = [[frac(1,1), frac(1,1), frac(1,1), frac(1,1)],
          [frac(4,1), frac(2,1), frac(1,1), frac(3,1)],
          [frac(9,1), frac(3,1), frac(1,1), frac(6,1)]],
R = ...

Expected mathematical output:

a = 1/2
b = 1/2
c = 0
S(n) = n(n+1)/2

⸻

58. Arithmetic sequence discovery

?- Matrix = [
      [frac(1,1), frac(1,1), frac(1,1)],
      [frac(2,1), frac(1,1), frac(3,1)]
   ],
   npl_gauss_eliminate(Matrix, R).
Matrix = [[frac(1,1), frac(1,1), frac(1,1)],
          [frac(2,1), frac(1,1), frac(3,1)]],
R = ...

Expected mathematical output:

f(n) = 2n - 1

⸻

59. 2D index formula discovery

?- Matrix = [
      [frac(1,1), frac(1,1), frac(2,1)],
      [frac(2,1), frac(1,1), frac(4,1)]
   ],
   npl_gauss_eliminate(Matrix, R).
Matrix = [[frac(1,1), frac(1,1), frac(2,1)],
          [frac(2,1), frac(1,1), frac(4,1)]],
R = ...

Expected mathematical output:

f(i) = 2i

⸻

60. Quadratic loop formula discovery

?- Matrix = [
      [frac(1,1), frac(1,1), frac(1,1), frac(1,1)],
      [frac(4,1), frac(2,1), frac(1,1), frac(4,1)],
      [frac(9,1), frac(3,1), frac(1,1), frac(9,1)]
   ],
   npl_gauss_eliminate(Matrix, R).
Matrix = [[frac(1,1), frac(1,1), frac(1,1), frac(1,1)],
          [frac(4,1), frac(2,1), frac(1,1), frac(4,1)],
          [frac(9,1), frac(3,1), frac(1,1), frac(9,1)]],
R = ...

Expected mathematical output:

T(n) = n^2

⸻

61. Nested recursion classification

?- Group = [
      ir_clause(fib(0,0), ir_true, info([])),
      ir_clause(fib(1,1), ir_true, info([])),
      ir_clause(fib(N,R),
        ir_seq(ir_call(is(N1, -(N,1))),
        ir_seq(ir_call(fib(N1,R1)),
        ir_seq(ir_call(is(N2, -(N,2))),
        ir_seq(ir_call(fib(N2,R2)),
               ir_call(is(R, +(R1,R2))))))),
        info([]))
   ],
   npl_nested_classify(Group, Class).
Group = [...],
Class = nested_data_fold(+).

⸻

62. Nested recursion elimination

?- npl_nested_eliminate_pass(Group, OptGroup).
OptGroup = ...

⸻

63. Memoise predicate

?- npl_memo(fib/2).
true.

⸻

64. Memoise safe goal

?- npl_memo_call(member(a,[a,b,c])).
true.

⸻

65. Memoise deterministic result

?- npl_memo_call_det(length([1,2,3]), R).
R = 3.

⸻

66. Memoise all solutions

?- npl_memo_call_all(member(X,[a,b,c]), X, Solutions).
Solutions = [a,b,c].

⸻

67. Memoise explicit subgoal

?- npl_memo_subgoal(fib_20, fib(20, R)).
R = ...

⸻

68. Inspect memo cache

?- npl_memo_inspect(fib/2, Entries).
Entries = ...

⸻

69. Memo stats

?- npl_memo_stats(fib(20,_), Hits, Misses).
Hits = ...,
Misses = ...

⸻

70. Clear memo table

?- npl_memo_clear(fib/2).
true.

⸻

71. Clear all memo tables

?- npl_memo_clear_all.
true.

⸻

72. Memo safety

?- npl_memo_is_safe(member(a,[a,b,c])).
true.
?- npl_memo_is_safe(writeln(hello)).
false.

⸻

73. Memoisation pass over IR

?- IR = [ir_clause(fib(N,R), ir_call(fib_body(N,R)), info([]))],
   npl_memo(fib/2),
   npl_memoisation_pass(IR, OptIR).
IR = [ir_clause(fib(N,R), ir_call(fib_body(N,R)), info([]))],
OptIR = ...

⸻

74. Subterm-address conversion

?- IR = [
      ir_clause(tree_sum(T,S),
                ir_loop_candidate(
                    ir_seq(ir_call(arg(1,T,L)),
                    ir_seq(ir_call(tree_sum(L,SL)),
                           ir_call(true)))),
                info([]))
   ],
   npl_subterm_address_pass(IR, OptIR).
IR = [...],
OptIR = ...

⸻

75. Pattern correlation

?- IR = [
      ir_clause(p(a), ir_true, info([])),
      ir_clause(p(b), ir_true, info([]))
   ],
   npl_pattern_correlate(IR, OptIR).
IR = [ir_clause(p(a), ir_true, info([])),
      ir_clause(p(b), ir_true, info([]))],
OptIR = [ir_clause(p(a), ir_true, info([])),
         ir_clause(p(b), ir_true, info([]))].

⸻

76. Data unfolding

?- npl_unfold_data(ir_seq(ir_call(a), ir_call(b)), X).
X = ir_seq(ir_call(a), ir_call(b)).

⸻

77. Source file to IR

?- npl_lex('examples/lists.pl', Tokens),
   npl_parse(Tokens, AST),
   npl_analyse(AST, AAST),
   npl_intermediate(AAST, IR).
Tokens = ...,
AST = ...,
AAST = ...,
IR = ...

⸻

78. Source string to IR

?- npl_parse_string("p(X,Y) :- Y is X+0.", AST),
   npl_analyse(AST, AAST),
   npl_intermediate(AAST, IR).
AST = ...,
AAST = ...,
IR = [ir_clause(p(X,Y), ir_call(is(Y, X+0)), Info)].

⸻

79. Source string to optimised IR

?- npl_parse_string("p(X,Y) :- Y is X+0.", AST),
   npl_analyse(AST, AAST),
   npl_intermediate(AAST, IR),
   npl_optimise(IR, OptIR).
AST = ...,
AAST = ...,
IR = [ir_clause(p(X,Y), ir_call(is(Y, X+0)), Info)],
OptIR = [ir_clause(p(X,Y), ir_call(is(Y, X)), Info2)].

⸻

80. Fact to IR

?- npl_parse_string("foo(1).", AST),
   npl_analyse(AST, AAST),
   npl_intermediate(AAST, IR).
AST = ...,
AAST = ...,
IR = [ir_clause(foo(1), ir_true, Info)].

⸻

81. Conjunction to IR

?- npl_parse_string("p :- a, b.", AST),
   npl_analyse(AST, AAST),
   npl_intermediate(AAST, IR).
AST = ...,
AAST = ...,
IR = [ir_clause(p, ir_seq(ir_call(a), ir_call(b)), Info)].

⸻

82. If-then-else to IR

?- npl_parse_string("p :- (a -> b ; c).", AST),
   npl_analyse(AST, AAST),
   npl_intermediate(AAST, IR).
AST = ...,
AAST = ...,
IR = [ir_clause(p, ir_if(ir_call(a), ir_call(b), ir_call(c)), Info)].

⸻

83. Grouped IR

?- npl_parse_string("
     p(1).
     p(2).
     q(X) :- p(X).
   ", AST),
   npl_analyse(AST, AAST),
   npl_ir_full(AAST, FullIR).
AST = ...,
AAST = ...,
FullIR = [
  ir_predicate_def(p/1, ..., _),
  ir_predicate_def(q/1, ..., _)
].

⸻

84. End-to-end compile

swipl -g "consult('src/neuroprolog')" \
      -g "npl_compile('examples/lists.pl','neurocode/lists_nc.pl')" \
      -t halt

Output:

neurocode/lists_nc.pl

⸻

85. End-to-end safe compile

swipl -g "consult('src/neuroprolog')" \
      -g "npl_compile_safe('examples/lists.pl','neurocode/lists_safe_nc.pl')" \
      -t halt

Output:

neurocode/lists_safe_nc.pl

⸻

86. Run tests

swipl -g "consult('tests/run_tests')" -g "run_all_tests" -t halt

Output:

true.

⸻

Main command list

Starlog:

starlog_call/1
starlog_call/2
starlog_eval/2
starlog_no_eval/2
starlog_show_expansion/1
starlog_output_code/1
starlog_output_code/2
starlog_output_code/3
convert_prolog_to_starlog/2
solve_system/2
gaussian_elimination/2
npl_reconstruct_polynomial/3
npl_validate_polynomial_fit/4
npl_assign_symbolic_indices/3
npl_trace_index_flow/3
npl_reconstruct_index_relations/3
npl_stage8_build_ir/6
npl_stage8_lower_ir/2
npl_stage9_generate_code/2
npl_stage9_emit_neurocode/2
npl_stage9_compile_ir/2
npl_ir_to_annotated_source_text/3
npl_ir_to_annotated_source_file/3

NeuroProlog:

npl_compile/2
npl_compile_with_pipeline/3
npl_compile_safe/2
npl_optimise/2
npl_pipeline_default_config/1
npl_pipeline_enable/3
npl_pipeline_disable/3
npl_pipeline_run/4
npl_pipeline_run_full/5
npl_opt_dict_rules/1
npl_apply_rules/3
npl_apply_rule/3
npl_gaussian_reduce/2
npl_is_reducible/2
npl_extract_recurrence/2
npl_gauss_eliminate/2
npl_nested_classify/2
npl_nested_eliminate_pass/2
npl_memo/1
npl_memo_call/1
npl_memo_call_det/2
npl_memo_call_all/3
npl_memo_subgoal/2
npl_memo_inspect/2
npl_memo_stats/3
npl_memo_clear/1
npl_memo_clear_all/0
npl_memoisation_pass/2
npl_subterm_address_pass/2
npl_pattern_correlate/2
npl_unfold_data/2
npl_parse_string/2
npl_lex/2
npl_parse/2
npl_analyse/2
npl_intermediate/2
npl_ir_full/2

Core idea:

Starlog gives readable syntax.
NeuroProlog turns readable logic into optimised IR, neurocode, formulas, memoised calls, and direct indexed rules.
Enter fullscreen mode Exit fullscreen mode

Top comments (0)