Ozcar, the Mozart Debugger

• To set a static breakpoint, insert {Ozcar.breakpoint}
• To set/unset a dynamic breakpoint on the line where the curser is positioned in the source buffer:
• set: C-x <space>
• unset: C-u C-x <space>

Unfortunately, Ozcar doesn't run inside SearchAll or other meta-procedures.

Unify/3

Attempts to unify its first two arguments. Returns true or false depending on whether they unify.

local
proc {Unify X Y Z}
try X = Y Z = true
catch _ then Z = false
end
end
A B
in
if {Unify [A b a] [a B B]} then {Browse 1#A#B}
elseif {Unify [A b] [a B]} then {Browse 2#A#B}
end
end

IsMemberOnce

local
proc {Unify X Y Z}
try X = Y Z = true
catch _ then Z = false
end
end
proc {IsMemberOnce X Xs Z}
if {Unify Xs (Head | Tail)} then
if {Unify X Head} then Z = true
else {IsMemberOnce X Tail Z}
end
else Z = false
end
end
C D E
in
{Browse C#{IsMemberOnce C [a b]}}
D = b
{Browse D#{IsMemberOnce D [a b]}}
E = [a b]
{Browse E#{IsMemberOnce E [a b]}}
end

Digit

A very simple example of concurrent logic programming (CTM p 627).

local
fun {Digit}
choice 0 [] 1 [] 2 [] 3 [] 4 [] 5 [] 6 [] 7 [] 8 [] 9 end
end
in
{Browse {SearchAll  Digit }}
end

The palindrome problem

Find all 4-digit palindromic numbers (of the form ABBA) that are the product of two 2-digit palindromes (CTM pp 628 & 629). .

local
fun {Digit}
choice 0 [] 1 [] 2 [] 3 [] 4 [] 5 [] 6 [] 7 [] 8 [] 9 end
end

proc {Palindrome Ans}
X N1 N2 D1 D2 in
Ans = X#N1#N2

% Generate the numbers
D1 = {Digit}
N1 = 10*D1 + D1
D2 = {Digit}
N2 = 10*D2 + D2
(N1 =< N2) = true
X = N1 * N2

% Is X a 4-digit palindrome?
(X >= 1000) = true

% First and last digits must be the same.
(X div 1000) = X mod 10

% Middle two digits must be the same.
(X div 100) mod 10 = (X div 10) mod 10
end
in
{Browse {SearchAll Palindrome}}
end

IsMember

local
proc {IsMember X Xs}
H Tail in
Xs = H | Tail
choice H = X [] {IsMember X Tail} end
end
in
{Browse {SearchAll proc {\$ Y} {IsMember Y [1 2 3 4 5]} end}}
end

The miraculous append/3

Zs is the list consisting of Ys appended to Xs.

local
proc {Append Xs Ys Zs}
choice
Xs = nil Ys = Zs
[] X Xr in
Xs = X | Xr
Zs = X | {Append Xr Ys}
end
end
in
{Browse {SearchAll proc {\$ Ans} {Append [a b c] [e f g] Ans} end}}
{Browse {SearchAll
proc {\$ Ans} Xs Ys in
Ans = Xs#Ys
{Append Xs Ys [a b c e f g]} end}}
end