Skip to content

Commit d548909

Browse files
committed
Merge branch 'j5'
2 parents 277c6c0 + 9fbbadb commit d548909

File tree

79 files changed

+8347
-1805
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+8347
-1805
lines changed

.github/workflows/run-tests.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ jobs:
66
test:
77
runs-on: ubuntu-latest
88
steps:
9-
- uses: actions/checkout@v2
9+
- uses: actions/checkout@v4
1010
- name: run tests
1111
run: |
12-
timeout 15m make test
12+
timeout 15m make github-test

Makefile

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ JAVA ?= java
33

44
# this version should match the version in project.clj as that is what is going to be built by lein
55
JVERSION:= 0.1.0
6-
VERSION= $(shell date '+%Y%m%d')
6+
VERSION:= $(shell git describe --always --long --abbrev=12)-$(shell date '+%Y%m%d')
77

88
SOURCE=$(wildcard src/*/*/*.clj) $(wildcard src/*/*/*.java)
99
JAR_TARGET=target/dyna-$(JVERSION)-SNAPSHOT-standalone.jar
@@ -22,11 +22,15 @@ clean:
2222
rm -rf target/ dyna-standalone-* python_build/
2323

2424
test:
25-
_JAVA_OPTIONS='-Ddyna.debug=false -Ddyna.trace_rexpr_construction=false -Xss8m' $(LEIN) test
25+
_JAVA_OPTIONS='-Ddyna.debug=false -Ddyna.trace_rexpr_construction=false -Ddyna.debug_repl=false -Xss8m -ea' $(LEIN) test
2626

2727
test-debug:
2828
$(LEIN) test
2929

30+
# some of the tests are failing randomly or somehow failing depending on the order in which they run. Trying to fix this, but annoying right now with github running of the tests failing
31+
github-test:
32+
_JAVA_OPTIONS='-Ddyna.debug=false -Ddyna.trace_rexpr_construction=false -Ddyna.debug_repl=false -Xss8m -ea' $(LEIN) test || _JAVA_OPTIONS='-Ddyna.debug=false -Ddyna.trace_rexpr_construction=false -Ddyna.debug_repl=false -Xss8m -ea' $(LEIN) retest
33+
3034
# start the repl for dyna code from the source directory
3135
repl: dyna-repl
3236
dyna-repl: $(PARSER_TARGET)

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ make
1616

1717
A recent version of java is required. Running `make` should automattically
1818
download all dependencies. The dyna runtime will be compiled into
19-
`./dyna-standalone-*`.
19+
`./dyna-standalone-*.run`.
2020

2121
## Running dyna
2222
```
2323
make
24-
./dyna-standalone-*
24+
./dyna-standalone-*.run
2525
```
2626

2727
## Running tests

bugs.org

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
* bugs
2+
1. run-iterator is calling simplify after it binds each variable. This is
3+
causing the R-exprs to perform a lot of rewriting, hence be slow. This needs
4+
a "fast fail" flag which will attempt to just to simplification operations
5+
which can quickly get done without causing too much rewriting. Even if we
6+
keep going with an R-expr which is equivalent to 0 (without known) it will
7+
still be correct, but we will just waste time on additional inner loops
8+
- this is now setting a fast fail flag, which blocks some operations such as
9+
expanding user calls. This should at least prevent those from running and
10+
getting the result which corresponds with an error
11+
12+
2. I think that variable renaming is causing the quicksort program to fail atm
13+
- when one of the disjuncts causes it to unify with an expression, it will
14+
result in it finding that there is some result which handle that value.
15+
16+
3. factorial program is not terminating atm, but somehow pressing Ctrl-C is able
17+
to cause it to stop and return the right answer? Now sure why it would get
18+
interrupted and then somehow get the right answer. Though I suppose this
19+
could be something with backchaining going on for too long? It would have
20+
that there is something that might cause it to run for too long.
21+
- pressing Ctrl-C will set the thread interrupted flag, which stops
22+
simplification from continuing to run in a loop.
23+
- now this is just not stopping anymore, so seems like it is doing too many
24+
steps of simplification.
25+
26+
** bugs fixed
27+
1. Iterator when a variable is already bound to a constant, need to skip ahread in the iterator sequence
28+
2. ~$free~ when there is some value used in ~$memo~, the value will be passed.
29+
This should really just behave more like a no-op in this case.
30+
2. disjunct-op needs to allow for taking inner disjuncts which are returned and
31+
merging it into its internal representation.
32+
- this issue can be provoked by setting the simplify method of run-iterator
33+
to the identity (disabling simplify during each step of the iteration)
34+
2. Macros are not subsuiting the variables in correctly it seems
35+
36+
** bugs deferred
37+
1. make-memoization-controller-function is supposed to generate efficient
38+
memoization controller functions which do not have to call into R-exprs every
39+
time to evaluate the policy. This seems to currently be buggy.
40+
- going to just use the R-expr representation every time. Will eventually
41+
tie in the JIT such that it should get a good generated version of the
42+
code, so it hopefully will not be too bad.
43+
44+
* enhancements
45+
1. disjunct-op should know information about what is being stored. There are
46+
currently a lot of calls to perform rewriting/simplification, and if we knew
47+
that there was nothing but multiplicies inside of the trie (meaning it only
48+
contains ground values), then it would be able to short cut a lot of the operations.
49+
2. disjunct-op is being called with simplify many times where the variable
50+
bindings are unlikely to change that much. We should save the current
51+
bindings into the variable-slots and then will avoid redoing a simplification
52+
of the trie in the case that there are no additional variables which are
53+
ground.
54+
55+
3. the clojure ^:dynamic is very slower, as it indirects the reads through a
56+
clojure hash map. Ideally convert those to a java ThreadLocal which should
57+
be able to use an array access and be efficient. However, this will not play
58+
nicely with the
59+
60+
61+
* further out enhancements
62+
1. JIT compiler
63+
- integrate into the looping such that it will use it to perform the
64+
simplification for a given value of an expression.
65+
66+
2. memoization point wise update when a user-definition is changed. This needs
67+
to not rebuild the memo tables from scratch, as that is going to be slow.
68+
69+
70+
3. should track what the user call stack is for different operations. Currently
71+
it is too hard to figure out where something is going wrong. if it tracked
72+
the call stack, then it would be able to figure out which of the operations
73+
will correspond to it getting some result. But the call stack is going to
74+
become more complicated when it has different things like memoization
75+
involved, as those call stack sequence will not really correspond with
76+
anything.
77+
- I suppose that debugging the program could also be done by adding
78+
additional rules to track stuff, but not sure if that will work out
79+
correctly either? I think that debugging the programs is just going to
80+
difficult in general given the number of things which are getting combined
81+
together to make a final result. If everything is "simple" meaning that it
82+
is all ground values, then there is not that much of an issue, but once
83+
there are complex delayed constraints, those constraints are going to cause
84+
it to get some result which can only happen in the exact case where all of
85+
those delayed constraints combine together to make some inference.
86+
87+
88+
* working on a large relational system
89+
https://news.ycombinator.com/item?id=18442941
90+
- oracle database where new flags are added to handle the different use cases
91+
https://www.postgresql.org/message-id/flat/31cc6df9-53fe-3cd9-af5b-ac0d801163f4%40iki.fi
92+
- postgres has around 1666 variables which are "global" to a connection to tack
93+
various aspects of the session state. Conceptually similar to the case we
94+
have here

dyna

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash
22

3-
# this runs the dyna repl without having to generate the jar first
3+
# this runs the dyna repl
44

55
make
66
exec java -cp `make run-class-path` dyna.DynaMain "$@"

dyna_python_module/dyna/__init__.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,18 @@
1212
class Dyna:
1313

1414
def __init__(self):
15+
self.__system_v = None
16+
17+
@property
18+
def __system(self):
19+
v = self.__system_v
20+
if v is not None:
21+
return v
1522
# this will reference the python class which wrap the java class. This will block until the dyna runtime is loaded
1623
from .java_wrapper import DynaInstance
17-
self.__system = DynaInstance()
24+
v = DynaInstance()
25+
self.__system_v = v
26+
return v
1827

1928
def define_function(self, name=None, arity=None):
2029
"""

dyna_python_module/dyna/start_dyna_repl.py

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ def start_dyna_repl():
55
jar = importlib.resources.path('dyna', 'dyna.jar')
66
if not os.path.exists(jar):
77
print('Unable to find dyna runtime')
8+
sys.exit(1)
89
os.execv(jar, sys.argv)
910

1011
if __name__ == '__main__':

project.clj

+7-12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
:dependencies [[org.clojure/clojure "1.11.1" ;"1.12.0-mfl-SNAPSHOT"
66
]
77
[org.clojure/tools.namespace "1.2.0"]
8+
;[org.ow2.asm/asm "9.5"]
89
;[org.clojure/tools.macro "0.1.5"]
910
[aprint "0.1.3"] ;; for formatted printing
1011
;[clj-python/libpython-clj "2.00-beta-22"]
@@ -23,10 +24,6 @@
2324
;[reply "0.5.1"]
2425
]
2526
:repl-options {:init-ns dyna.core}
26-
;; :aot [dyna.interface
27-
;; dyna.parser_interface]
28-
;;:aot :all
29-
;;:aot [dyna.rexpr]
3027
:source-paths ["src/clojure"]
3128
:java-source-paths ["target/gen-src" "src/java"]
3229
:resource-paths ["src/resources"]
@@ -38,15 +35,13 @@
3835
:antlr-src-dir "src/antlr"
3936
:antlr-dest-dir "target/gen-src"
4037

41-
:profiles {:uberjar {:main dyna.DynaMain
42-
;; clojure only requires java 8, and we shouldn't need any of the "newer" features ourselves also
43-
;; so this should make this work with any version released after 1.8 (march 2014)
44-
:javac-options ["-source" "1.8" "-target" "1.8"]
45-
46-
;:aot [dyna.core] ;; this makes it start faster but run slower....
47-
}}
38+
:profiles {:uberjar {:main dyna.DynaMain}}
4839
:main dyna.core
4940

41+
;; clojure only requires java 8, and we shouldn't need any of the "newer" features ourselves also
42+
;; so this should make this work with any version released after 1.8 (march 2014)
43+
:javac-options ["-source" "1.8" "-target" "1.8" "-XDignore.symbol.file" "-Xlint:-options"]
44+
5045
;; this is needed to generate the uberjar, but it makes it slower to run when working on stuff
5146
;; so can comment out if running tests or something from the local directory
5247
:aliases {"compile" ["do" ["antlr"] ["javac"] "compile"]
@@ -55,7 +50,7 @@
5550

5651
;;:main dyna.DynaMain
5752
:global-vars {;*warn-on-reflection* true ;; useful for identifying where it uses clojure's reflection which is slow...
58-
;*unchecked-math* :warn-on-boxed ;; boxed math is slow9
53+
;*unchecked-math* :warn-on-boxed ;; boxed math is slow
5954
}
6055

6156
;; this will check the repo every time it runs...

src/antlr/dyna/dyna_grammar2.g4

+21-13
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ atom returns[String t]
8484
$t = $m.getText();
8585
$t = $t.substring(1, $t.length() - 1);
8686
if($t.startsWith("\$_"))
87-
throw new RuntimeException("the namespace \$_ is reserved for internal use");
87+
throw new DynaSyntaxError("the namespace \$_ is reserved for internal use");
8888
}
8989
;
9090

@@ -101,7 +101,7 @@ Variable
101101
// going to change this to only match the aggregators which are actually defined
102102
MergedAggregator
103103
: [&*\-+:|?] '='
104-
| [a-z][a-z&*\-+:|?]* '=' {
104+
| [a-z][a-z&*\-+:|?_]* '=' {
105105
// this checks that the aggregator name is defined in rexpr_aggregators.clj and will conditionally enable this lexer rule
106106
aggregator_defined(getText())}?
107107
;
@@ -277,12 +277,14 @@ term returns[DynaTerm rterm = null]
277277
String ttext = $t.ctx.start.getInputStream().getText(new Interval($t.ctx.start.getStartIndex(), $t.ctx.stop.getStopIndex()));
278278
$rterm = DynaTerm.create("\$print", $t.rterm, ttext, $t.ctx.getStart().getLine());
279279
}
280-
| 'debug_repl'
280+
| 'debug_repl_clojure'
281281
t=termBody["print="] EndTerm
282282
{
283283
String ttext = $t.ctx.start.getInputStream().getText(new Interval($t.ctx.start.getStartIndex(), $t.ctx.stop.getStopIndex()));
284284
$rterm = DynaTerm.create("\$_debug_repl", $t.rterm, ttext, $t.ctx.getStart().getLine());
285285
}
286+
| 'debug' EndTerm
287+
{ $rterm = DynaTerm.create("\$debug"); }
286288

287289
// there could be warnings if some library is used in a particular way. This should somehow defer in the case that some dynabase has not been constructed, but this would want to have that the expression would later come into existence
288290
| 'warning' '(' we=expression ')' t=termBody["warning="] EndTerm
@@ -544,6 +546,9 @@ expressionRoot returns [DynaTerm rterm]
544546
| mp=assocativeMap { $rterm=$mp.rterm; }
545547
| db=dynabase { $rterm = $db.rterm; }
546548
| v=Variable '(' arguments ')' {
549+
if($v.getText().equals("_")) {
550+
throw new DynaSyntaxError("Calling an unscore function is not supported");
551+
}
547552
// for doing an indirect call to some value
548553
$arguments.args.add(0, DynaTerm.create("\$variable", $v.getText()));
549554
$rterm = DynaTerm.create_arr("\$call", $arguments.args);
@@ -564,7 +569,7 @@ expressionDynabaseAccess returns[DynaTerm rterm]
564569
: a=expressionRoot {$rterm=$a.rterm;}
565570
('.' m=methodCall {
566571
if($rterm.name.equals("\$quote") || $rterm.name.equals("\$inline_function")) {
567-
throw new RuntimeException("syntax error");
572+
throw new DynaSyntaxError();//"syntax error");
568573
//assert(false); /// should be a syntax error
569574
}
570575
if($rterm.name.equals("\$quote1")) {
@@ -579,8 +584,7 @@ expressionDynabaseAccess returns[DynaTerm rterm]
579584
})*
580585
('.' bracketTerm {
581586
if($rterm.name.equals("\$quote") || $rterm.name.equals("\$quote1") || $rterm.name.equals("\$dynabase_quote1")) {
582-
throw new RuntimeException("syntax error");
583-
//assert(false); // should be a syntax error
587+
throw new DynaSyntaxError("Structured terms can not be used as a dynabase");
584588
}
585589
$rterm = DynaTerm.create("\$dynbase_quote1", $rterm, DynaTerm.create_arr($bracketTerm.name, $bracketTerm.args)); })?
586590
;
@@ -607,8 +611,7 @@ locals [DynaTerm add_arg=null]
607611
|| $rterm.name.equals("\$dynabase_create") || $rterm.name.equals("\$map_empty") || $rterm.name.equals("\$map_element")
608612
|| $rterm.name.equals("\$nil") || $rterm.name.equals("\$cons"))
609613
{
610-
throw new RuntimeException("syntax error");
611-
//assert(false); // this should return a syntax error rather than an assert(false)
614+
throw new DynaSyntaxError("Implicit call using {} can only be done to a term");
612615
}
613616
if($rterm.name.equals("\$dynabase_call")) {
614617
// have to put the argument onto the dynabase call element,
@@ -664,15 +667,20 @@ expressionAdditive returns [DynaTerm rterm]
664667
{$rterm = DynaTerm.create($op.getText(), $rterm, $b.rterm);})*
665668
;
666669

670+
expressionNot returns [DynaTerm rterm]
671+
: a=expressionAdditive {$rterm=$a.rterm;}
672+
| '!' a=expressionAdditive {$rterm = DynaTerm.create("!", $a.rterm);}
673+
;
674+
667675
expressionRelationCompare returns [DynaTerm rterm]
668676
locals[ArrayList<DynaTerm> expressions, ArrayList<String> ops]
669-
: a=expressionAdditive {$rterm = $a.rterm;}
670-
| a=expressionAdditive {
677+
: a=expressionNot {$rterm = $a.rterm;}
678+
| a=expressionNot {
671679
$expressions = new ArrayList<>();
672680
$ops = new ArrayList<>();
673681
$expressions.add($a.rterm);
674682
}
675-
(op=('>'|'<'|'<='|'>=') b=expressionAdditive
683+
(op=('>'|'<'|'<='|'>=') b=expressionNot
676684
{ $ops.add($op.getText());
677685
$expressions.add($b.rterm);
678686
})+
@@ -722,8 +730,8 @@ expression returns [DynaTerm rterm]
722730
compilerExpressionArgument returns [Object val]
723731
locals [ArrayList<Object> args=null]
724732
: p=primitive {$val=$p.v;}
725-
| {$args=new ArrayList<>();} a=atom ('(' (ag=compilerExpressionArgument Comma {$args.add($ag.val);})*
726-
(ag=compilerExpressionArgument Comma? {$args.add($ag.val);})? ')' )?
733+
| {$args=new ArrayList<>();} a=atom ('(' ((ag=compilerExpressionArgument Comma {$args.add($ag.val);})*
734+
ag=compilerExpressionArgument Comma? {$args.add($ag.val);})? ')' )?
727735
{$val = DynaTerm.create_arr($a.t, $args); }
728736
| '*' {$val = "*";}
729737
| '**' {$val = "**";}

0 commit comments

Comments
 (0)