Code: Select all
1 begin
2 begin
3 begin
3 fail
I also tried the eight queens demo in 32 bit. That however worked well.
Code: Select all
1 begin
2 begin
3 begin
3 fail
Code: Select all
delegate
interface array2M{@ItemType} to ar2M
Code: Select all
getBackTrackTop = "?GetBackTrackTop@Kernel@VIP@@YAQAVTBackTrackBlock@12@XZ".
Code: Select all
getBackTrackTop = "?GetBackTrackTop@Kernel@VIP@@YAQAVTBackTrackBlock@12@XZ".
Code: Select all
class btReversion
open core
predicates
addUndoAction : (predicate Undo).
predicates
undoOnFailure_mt : () multi.
end class btReversion
%---
implement btReversion
open core
domains
trailEntry = trailEntry(programControl::stackMark StackMark, predicate Undo).
class facts
trailTree : redBlackTree::tree{multiThread_native::threadID ThreadID, varM{trailEntry*} TrailM} := redBlackTree::emptyUnique().
class predicates
getTrailM : () -> varM{trailEntry*} TrailM.
clauses
getTrailM() = TrailM :-
ThreadId = multiThread_native::getCurrentThreadId(),
if TrailM = redBlackTree::tryLookUp(trailTree, ThreadId) then
else
TrailM = varM::new([]),
trailTree := redBlackTree::insert(trailTree, ThreadId, TrailM)
end if.
clauses
undoOnFailure_mt().
undoOnFailure_mt() :-
TrailM = getTrailM(),
undoOnFailure_fl(TrailM).
class predicates
undoOnFailure_fl : (varM{trailEntry*} TrailM) failure.
clauses
undoOnFailure_fl(TrailM) :-
[trailEntry(StackMark, Undo) | RestTrail] = TrailM:value,
StackMark <= programControl::getBackTrack(),
TrailM:value := RestTrail,
try
Undo()
finally
undoOnFailure_fl(TrailM)
end try.
clauses
addUndoAction(Undo) :-
TrailM = getTrailM(),
StackMark = programControl::getBackTrack(),
TrailM:value := [trailEntry(StackMark, Undo) | TrailM:value].
end implement btReversion
%===
interface array2B{@ItemType} supports array2M{@ItemType}
end interface array2B
%---
class array2B{@ItemType} : array2B{@ItemType}
open core
constructors
new : (positive SizeX, positive SizeY).
constructors
newInitialize : (positive SizeX, positive SizeY, @ItemType InitValue).
constructors
newPointer : (pointer Data, positive SizeX, positive SizeY).
end class array2B
%---
implement array2B{@ItemType}
open core, btReversion
delegate
interface array2M{@ItemType} to ar2M
facts
ar2M : array2M{@ItemType}.
clauses
new(SizeX, SizeY) :-
ar2M := array2M::new(SizeX, SizeY).
clauses
newInitialize(SizeX, SizeY, Init) :-
ar2M := array2M::newInitialize(SizeX, SizeY, Init).
clauses
newPointer(Buffer, SizeX, SizeY) :-
ar2M := array2M::newPointer(Buffer, SizeX, SizeY).
clauses
set(X, Y, Value) :-
OldValue = ar2M:get(X, Y),
ar2M:set(X, Y, Value),
addUndoAction({ :- ar2M:set(X, Y, OldValue) }).
clauses
set(tuple(X, Y), Value) :-
set(X, Y, Value).
clauses
set_optional(tuple(X, Y), some(Value)) :-
set(X, Y, Value).
set_optional(XY, none) :-
ar2M:set_optional(XY, none). %raises exception
clauses
insert(tuple(XY, Value)) :-
set(XY, Value).
clauses
insertList(TupleList) :-
OldAr2M = ar2M:createCopy(),
ar2M:insertList(TupleList),
addUndoAction({ :- ar2M := OldAr2M }).
clauses
insertCollection(TupleCollection) :-
OldAr2M = ar2M:createCopy(),
ar2M:insertCollection(TupleCollection),
addUndoAction({ :- ar2M := OldAr2M }).
clauses
insertEnumerator(TupleEnum_nd) :-
OldAr2M = ar2M:createCopy(),
ar2M:insertEnumerator(TupleEnum_nd),
addUndoAction({ :- ar2M := OldAr2M }).
end implement array2B
%===
implement main
open core
constants
boardSize : positive = 8.
class facts
boardB : array2B{unsigned8} := array2B::new(boardSize, boardSize).
solutionCount : positive := 0.
clauses
run() :-
stdIO::nl(),
solve_nd(0, 0),
fail.
run() :-
stdIO::writeF("Total solutions for a %ux%u board: %u.\n", boardSize, boardSize, solutionCount).
class predicates
show : ().
clauses
show() :-
stdIO::writeF("Solution %u:\n", solutionCount),
foreach Y = std::downTo(boardSize - 1, 0) do
stdIO::writeF("%2u", Y + 1),
foreach X = std::fromTo(0, boardSize - 1) do
Field = if boardB:get(X, Y) = 0 then '.' else 'Q' end if,
stdIO::write(Field)
end foreach,
stdIO::nl()
end foreach,
stdIO::write(' '),
foreach X = std::fromTo(0, boardSize - 1) do
stdIO::write(string::getCharFromValue(string::getCharValue('a') + X))
end foreach,
stdIO::nl(),
stdIO::nl().
class predicates
solve_nd : (positive QueenX, positive QueenY) nondeterm.
clauses
solve_nd(QueenX, QueenY) :-
btReversion::undoOnFailure_mt(), %internally insert a call to undoOnFailure_mt at each backtrack point
boardB:set(QueenX, QueenY, 1),
not(canCaptureHorizontal(0, QueenX, QueenY)),
not(canCaptureDiagonal1(0, QueenX, QueenY)),
not(canCaptureDiagonal2(0, QueenX, QueenY)),
if QueenX = boardSize - 1 then
solutionCount := solutionCount + 1,
show()
else
solve_nd(QueenX + 1, 0)
end if.
solve_nd(QueenX, QueenY) :-
QueenY < boardSize - 1,
solve_nd(QueenX, QueenY + 1).
class predicates
canCaptureHorizontal : (positive N, positive QueenX, positive QueenY) determ.
clauses
canCaptureHorizontal(N, QueenX, QueenY) :-
N < QueenX,
if boardB:get(N, QueenY) = 0 then
canCaptureHorizontal(N + 1, QueenX, QueenY)
end if.
class predicates
canCaptureDiagonal1 : (positive N, positive QueenX, positive QueenY) determ.
clauses
canCaptureDiagonal1(N, QueenX, QueenY) :-
N < QueenX,
N < QueenY,
N1 = N + 1,
if boardB:get(QueenX - N1, QueenY - N1) = 0 then
canCaptureDiagonal1(N1, QueenX, QueenY)
end if.
class predicates
canCaptureDiagonal2 : (positive N, positive QueenX, positive QueenY) determ.
clauses
canCaptureDiagonal2(N, QueenX, QueenY) :-
N < QueenX,
N1 = N + 1,
N1 < boardSize - QueenY,
if boardB:get(QueenX - N1, QueenY + N1) = 0 then
canCaptureDiagonal2(N1, QueenX, QueenY)
end if.
end implement main