Age | Commit message (Collapse) | Author |
|
Poorly documented, but works better than abort & destroy.
|
|
|
|
Run with "swipl main.pl".
|
|
Collects all the answers to a given query within the specified timeout.
|
|
|
|
|
|
|
|
|
|
The parser is currently unused.
|
|
Hope it does not break anything.
|
|
The only way to get residuals in CLP queries.
|
|
|
|
|
|
|
|
|
|
Also simplify rules for list expressions.
|
|
|
|
Also a testing loop to prolog.lexer.
|
|
|
|
|
|
In case SWI engine goes insane and returns a malformed reply (has
happened). Also fix the test case in this file to use the new, classless
methods.
|
|
Instead of splitting the program by line numbers, do limited parsing
(enough to distinguish , in "memb(X,Y)" from , in "a :- b, c."). Each
token in the parsed program is annotated with rule and part number.
Rewrite monkey.fix.step to take program as a sequence of annotated
tokens instead of lists of lines and rules. Improve message passing to
website.
|
|
|
|
|
|
|
|
Remove trailing sequences of COMMAs and PERIODs when extracting edits
from a trace. This is because subgoal order is rarely important in
Prolog, and we don't care if the edit happened on the last line or not.
This means that we treat for example
"conc(A,B)," → "conc(A,B,C)." the same as
"conc(A,B)" → "conc(A,B,C)".
|
|
|
|
Importing pymonkey into webmonkey, let's see how this works.
|
|
Depends on run_tests/3.
|
|
|
|
... which obsoletes *a lot* of effort in making the testing procedure
more robust in the past two years. Oh well. It seems to be the sanest
way of coping with more than one simultaneous user (who could have
predicted this use case?). The new way involves a PEngine server, and it
seems to work quite well. Remember Knuth: premature optimization (as in
ignoring possible solutions because they _might_ be to slow) is stupid.
TODO:
- library loading (again)
- use of previous solution (again)
- fix issues when converting non-ground terms to json
Side note, constructivism works: in the past few days I have reached a
much better but fundamentally ineffable intuition about Prolog, more so
than in the past two years teaching it. So, fuck ITS and rather fix the
schools by giving students something meaningful to do. Sigh.
|
|
|
|
|
|
Each fact library is loaded at most once, so different problems can
share the same library (e.g. family-relation problems).
|
|
|
|
For each query:
- generate a single solution
- incorrect solution / timeout / other error → FAIL
- generate (up to) ten solutions
- more than one distinct solution found → FAIL
- timeout is OK (a correct solution was found above)
- if reached this point → PASS
|
|
|
|
This prevents incorrect student solutions from overwriting or adding to
predicates in solution<n> modules.
|
|
Place functions for internal use at the end.
|
|
Using erase/1 keeps the dynamic property for all defined predicates in
the testing module. This overrides the clauses in solution modules. For
example, if the user defines conc/3 in the solution for the dup/2
problem, the correct conc/3 would not get used even after unloading all
user's clauses.
This commit also plugs a couple of memory leaks by opening (and later
discarding) a new Prolog frame in functions test, load_solution and
mark_solved.
|
|
|
|
Turns out unix:dup/2 exists and is autoloaded if the student solution
for dup/2 does not contain the predicate with this name; this can mess
up subsequent tests.
|
|
This is always required for the safe_goal/1 predicate.
|
|
|
|
|
|
Testing logic now lives in PrologEngine. The engine now has some notion
of problems and users, which is necessary to avoid repeatedly loading
code into Prolog.
TODO:
- support library loading
- fix PrologEngine.test for unusual cases (more than one solution, …)
- memoization of correct answers
|
|
Required for exercise 25 (genlist).
|
|
This will allow us to match line edits to original source locations.
|
|
Return a single mapping instead of generating all possible permutations.
Only the first solution was used anyway, with little effect on found
solutions.
|
|
|