File: course.doc

package info (click to toggle)
swi-prolog-packages 5.0.1-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 50,688 kB
  • ctags: 25,904
  • sloc: ansic: 195,096; perl: 91,425; cpp: 7,660; sh: 3,046; makefile: 2,750; yacc: 843; awk: 14; sed: 12
file content (1530 lines) | stat: -rw-r--r-- 50,922 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
\newcounter{theexercise}
\setcounter{theexercise}{1}

\newenvironment{exercises}{%
 	\section{Exercises}
	\begin{enumerate}}{%
 	\end{enumerate}}

\newcommand{\exercise}[1]{%
	\item[Exercise \arabic{theexercise}]\hfil%
	\addtocounter{theexercise}{1} \\ #1}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Getting the Dialogue}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\section{Creating and Manipulating Objects}

XPCE is an object-oriented system and defines four predicates that
allows you to create, manipulate, query and destroy objects from
Prolog: new/2, send/[2-12], get/[3-13] and free/1:

\begin{code}
?- new(X, point(5, 6)).

X = @791307/point
\end{code}

Created an instance of class `point' at location (5,6).  In general,
The first argument of new/2 provides or is unified to the {\em object
reference}, which is a Prolog term of the functor @/1.  The second
argument is a ground Prolog term.  The function describes the class
from which an instance is to be created, while the arguments provide
initialisation arguments.

New/2 may also be used to create objects with a predefined object
reference:

\begin{code}
?- new(@s, size(100, 5)).

Yes
\end{code}

Created an instance of class size with width 100 and height 5.  We call
@s a `named' or `global' object reference.

\begin{code}
?- send(@791307, x, 7).

Yes
\end{code}

Send {\em Manipulates} objects.  In the example above, the X-coordinate
of the point is changed to 7.  The first argument of send is the
object-reference.  The second is the {\em selector} and the remaining
arguments (up to 10) provide arguments to the operation.

\begin{code}
?- get(@791307, distance, point(0,0), D).

D = 9
\end{code}

Get {\em requests} the object to return (compute) a value.  In this case
this is the (rounded) distance to the origin of the coordinate system.
The arguments to get/[3-13] are the same as for send/[2-12], but
get/[3-13] requires one additional argument for the return value.

Finally, the following call destroys the created object.

\begin{code}
?- free(@791307).

Yes
\end{code}


\section{Creating Windows is More Fun}

In the previous section we have seen the basic operations on objects.
In this section we will give some more examples to clarify object
manipulation.  In this section we will use windows and graphics.

\begin{code}
?- new(P, picture('Hello World')),
   send(P, display, text('Hello World'), point(20, 20)),
   send(P, open).

P = @682375
\end{code}

First created a picture (=graphics) window labeled `Hello World',
displays a text (graphical object representing text) on the picture at
location (20,20) from the top-left corner of the window and finally
opens this window on the display:

\postscriptfig[width=3in]{hello}{Screendump for the `Hello World' window}

\section{Architecture}

XPCE is a C-library written in an object-oriented fashion.%
 \footnote{It was developed before C++ was in focus.  We are
	   considering C++ but due to the totally different viewpoints
	   taken by XPCE (symbolic, dynamically typed) and C++ (strong
	   static typing) it is unclear whether any significant
	   advantage is to be expected.}
This library is completely dynamically typed: each data element is
passed the same way and the actual type may be queried at runtime if
necessary.  Also written in C is a meta-layer that describes the
functions implementing the methods and the C-structures realising the
storage.  The meta-layer is written in the same formalism as the rest of
the system and describes itself.  C-functions allow for invoking methods
(functions) in this library through the meta-layer.  This sub-system is
known as the message passing system or PCE virtual machine.  This
machine implements the 4 basic operations of XPCE: new(), send(), get()
and free().

The `host' language (Prolog in this document) drives the PCE virtual
machine instructions through the Prolog to C interface.

PCE predefines class `host' and the instance @prolog.  Messages send
to this object will call predicates in the Prolog environment:

\begin{code}
?- send(@prolog, format, 'Hello World~n', []).
Hello World
\end{code}

makes Prolog call PCE send() through its foreign interface.  In turn,
the message to the @prolog is mapped on the predicate format.  Note
however that both systems have their own data representation.  Try

\begin{code}
?- send(@prolog, member, A, [hello, world]).
\end{code}

PCE has nothing that resembles a logical variable and thus will complain
that `A' is an illegal argument.  Neither the following will work as
Prolog lists have no counterpart in XPCE:%
	\footnote{The empty list [] is an atom, and thus maybe passed!}

\begin{code}
?- send(@prolog, member, hello, [hello, world]).
\end{code}

And finally, Calls to PCE cannot be resatisfied:

\begin{code}
?- send(@prolog, repeat), fail.
No
\end{code}


Figure~\ref{fig:control} summarises the data and control flow
in the XPCE/Prolog system.

\postscriptfig[width=\textwidth]{control}{Data and Control flow in PCE/Prolog}

\section{The Manual Tools}		\label{sec:manualtools}

The manual tools are started using the Prolog predicate manpce/[0,1]%
	\footnote{Quintus: user_help/0.  To use manpce/1, load the
		  library(pce_manual).}
Just typing manpce creates a small window on your screen with a menu
bar.  The most useful options from this menu are:

\begin{description}
    \item[File/Demo Programs] starts a demo-starter which also provides
access to the sources of the demo's.
    \item[Browsers/Class Hierarchy] examines the inheritance hierarchy
of PCE classes.  Most classes are right below class object.  Useful
sub-trees are program_object (PCE's class en executable world),
recogniser (event handling) and visual (anything that can appear on
the screen.
    \item[Browsers/Class Browser] is the most commonly used tool.  It
displays attributes of a class.  Various searching options allow for
finding candidate methods or classes.  The {\bf Scope} option
needs explanation.  By default it is set to `own', making the tool
search only for things (re)defined on this class.  Using scope
`Super' will make the browser show inherited functionality too.  Using
scope `sub' is for searching the entire class hierarchy below the
current class.%
    \footnote{The current implementation does not show {\em delegated}
	      behaviour.}
    \item[Browsers/Global Objects] visualises all predefined (named) objects:
@pce, @prolog, @display, @arg1, @event, etc.
    \item[Browsers/Search]
Provides a {\sc wais} search facility for the entire hypercard system.
    \item[Browsers/Group OverView] provides an overview of functionally related
methods.  Typing in the window searches.
    \item[Tools/Visual Hierarchy] provides an overview of the consists
of hierarchy of GUI components.
    \item[Tools/Inspector] to analyse the structure of objects.
    \item[History] allows you to go back to previously visited cards.
\end{description}

Manpce/1 accepts a classname, in which case it switches the ClassBrowser
to this class.  It also accepts	a term of the form `class <-selector' or
`class ->selector', in which case it will pop up the documentation card
of the indicated card.  Try

\begin{code}
?- manpce((display ->inform)).
\end{code}


\begin{exercises}
\exercise{%
Start the PCE manual tools and find answers to the following questions:
\begin{enumerate}
    \item What is the super-class of class `device'?
    \item Find the description of class `tree'.  Which different layouts
	  are provided by class tree?
    \item Which attributes describe the appearance of a box?
    \item Which classes (re)define the ->report method?
\end{enumerate}
}

\exercise{%
Examine the structure of the inheritance path visualisation as shown in
the top-right window of the ClassBrowser using the VisualHierachy tool.
}

\exercise{%
Class device defines compound (`nested') graphical objects.  Define a
predicate make_text_box(?Ref, +Width, +Height, +String), which creates
a box with a centered text object.   Test your predicate using:

{\tt\obeyspaces
?- send(new(P, picture), open), \\
   make_text_box(B, 100, 50, 'Hi There'), \\
   send(P, display, B, point(50, 20)).
}
}

\exercise{%
Class tree and class node define primitives for creating a hierarchy
of graphical objects.  The method `directory <-directories' allow
you to query the Unix directory structure.  Write a predicate
show_directory_hierarchy(+{\em DirName}) with displays the Unix
directory hierarchy from the given root.

Some methods and classes you might want to use are: class picture,
class tree, class node, class directory and the methods `node->son',
`directory <-directories' and `directory <-directory'.
}

\end{exercises}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Programming Techniques}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Control Structure of Graphical Applications}

Interactive terminal operated applications often are implemented as
simple `Question-Answer' dialogues: the program provides a form, the
user answers the question(s) and the program continues its execution.
Graphical interfaces often allow the user to do much more than just
answering the latest question presented by the program.  This
flexibility complicates the design and implementation of graphical
interfaces.  Most interface libraries use an `event-driven'
control-structure.


\subsection{Event Driven Applications}

Using the event-driven control structure, the program creates the
UI objects and instructs the graphical library to start some operation
when the user operates the UI object.  The following example illustrates
this:

\begin{code}
?- send(button(hello, message(@prolog, format, 'Hi There~n')), open).

Yes
\end{code}

This query creates a button object and opens the button on your screen.
The button is instructed to call the Prolog predicate format/1 with
the given argument when it is pressed.  The query itself just returns
(to the Prolog toplevel).

Using this formalism, the overall structure of your application will be:

\begin{code}
initialise :-
	initialise_database,
	create_GUI_components.

call_back_when_GUI_xyz_is_operated(Context ...) :-
	change_application_database(Context ...),
	update_and_create_GUI_components.
\end{code}

This type of control structure is suitable for applications that define
operations on a database represented using the Prolog database or some
external persistent database (see also chapter~\ref{chap:data}.
Unfortunately `good' style Prolog programming often manipulates data
represented on the Prolog runtime stacks because destructive operations
on the Prolog database are dangerous and loose two important features of
Prolog: logical variables and backtracking.

The event-driven approach is commonly used by applications that present
and/or edit some external (persistent) database.  As long as name
conflicts in the Prolog program and the global PCE name spaces (classes
and named object references (e.g.\ @prolog, @main_window)) are avoided,
multiple applications may run simultaneously in the same XPCE/Prolog
process.  For example the PCE manual runs together with the various
PCE demo applications.


\subsection{Asking Questions: Modal windows}

Prolog applications that want to manipulate data represented on the Prolog
runtime stacks cannot use the event-driven approach presented above.
Unlike with event-driven applications, a single-threat Prolog system
can only run one task.  The overall structure of such an application
is:

\begin{code}
application :-
	initialise(Heap),
	create_GUI_components(Heap),
	process_events_until_computation_may_proceed,
	proceed(Heap),
	...
\end{code}

The `process_events_until_computation_may_proceed' is generally realised
using the methods `frame <-confirm' combined with `frame ->return'.
Suppose we have a diagnose system that presents a graphics
representation of the system to be diagnosed.  The application wants to
the the user's hypothesis for the faulty component.  The window has
implemented a selection mechanism, an ok button and a label to ask
the question.  The relevant program fragment could read:%
    \footnote{The variables are supposed to the instantiated to the
	      proper UI components.  The construct ``Diagram?selection''
	      denotes a PCE `obtainer'.  When the button is pressed,
	      PCE will send a message ->return to the frame.  The
	      argument to this message the return value of
	      `get(Diagram, selection, Selection)'.}

\begin{code}
	....
	send(Label, format, 'Select hypothesis and press "OK"'),
	send(OkButton, message,
	     message(Frame, return, Diagram?selection)),
	get(Frame, confirm, Hypothesis),
	....
\end{code}


\section{Executable Objects}

In the previous sections we have seen some simple examples of the
general notion of `PCE Executable Objects'.  Executable objects in
PCE are used for three purposes:

\begin{itemize}
    \tick{Define action associated with GUI component}
This is the oldest and most common usage.  A simple example is below:

\begin{code}
?- new(D, dialog('Hello')),
   send(D, append,
	button(hello, message(@prolog, format, 'Hello~n', []))),
   send(D, append,
	button(quit, message(D, destroy))),
   send(D, open).
\end{code}

    \tick{Code fragment argument as method parameter}
The behaviour of various methods may be refined using a code object that
is passed as an (optional) parameter.  For example, the method
`chain->sort' is defined to sort (by default) a chain of names
alphabetically.  When the chain contains other objects than names or
sorting has to be done on another criterium, a code object may be
used to compare pairs of objects.  Suppose `Chain' is a chain of
class objects which have to be sorted by name:

\begin{code}
	...
	send(Chain, sort, ?(@arg1?name, compare, @arg1?name)),
	...
\end{code}

`?' is the class-name of a PCE `obtainer'.  When executed, an obtainer
evaluates to the result of a PCE get-operation: @arg1?name%
    \footnote{Equivalent to ?(@arg1, name): `?'  is a Prolog infix
	      operator.}
evaluates to the return value of `get(@arg1, name, Name)'.

    \tick{Implement a method}
A method represents the mapping of a `selector' to an `action'.
The action is normally represented using a PCE executable object.
Define methods is discussed further in section~\ref{sec:classes}.
\end{itemize}


\subsection{Procedures and Functions}

Like send- and get-operations, PCE defines both procedures and
functions.  Procedures return success/failure after completion and
functions return a value (a PCE object or integer) or failure.
PCE defines the following procedures:

\begin{quote}
\begin{tabular}{ll}
\bf message	& Invoke a send-operation \\
\bf assign	& Variable assignment (see also `var') \\
\bf if		& Conditional branch \\
\bf and		& Sequence and logical connective \\
\bf or		& logical connective \\
\bf not		& logical connective \\
\bf while	& loop \\
\verb$==$	& Equivalence test \\
\verb$\==$	& Non-Equivalence test \\
\verb$>, =, =<, >, >=$ & Arithmetic tests \\
\end{tabular}
\end{quote}


and defines the following functions

\begin{quote}
\begin{tabular}{ll}
\bf ?		& Evaluates the result of get-operation \\
\bf progn	& Sequence returning value \\
\bf when	& Conditional function \\
\bf var		& Variable (returning <-_value) \\
\bf *, +, -, /	& Arithmetic operations \\
\end{tabular}
\end{quote}

A function is evaluated iff

\begin{enumerate}
    \item It is the receiver of a get- or send-operation {\bf and}
          the method is not defined on class function or a relevant
	  subclass.  These classes define very few methods for general
	  object manipulation, which normally start with an '_'
	  (underscore).
    \item It is passed as an argument to a method and the argument's
          type-test does not allow for functions.  This is true for
	  most arguments except for behaviour that requires a function.
    \item It appears as part of another code object.
\end{enumerate}


\section{Creating PCE Classes}		\label{sec:classes}

A PCE class defines common%
    \footnote{Note that object can define individual methods and
	      variables.}
storage details and behaviour of its instances (objects).  A PCE
class is an instance of class `class'.  Behaviour, variables and
other important properties of classes are all represented using
normal PCE objects.  These properties allow the Prolog programmer
to query and manipulate PCE's class world using the same primitives
as for normal object manipulation: send(), get(), new() and free().


\subsection{The Prolog Front End}

The XPCE/Prolog interface defines a dedicated syntax for defining
XPCE classes that have their method implemented in Prolog.%
    \footnote{The XPCE/CommonLisp interface defines a dedicated
	      syntax for defining XPCE classes and methods where
	      the implementation is realised by PCE executable
	      objects.  See \cite{PCE:lisp}}


The definition of an XPCE class from Prolog is bracketed by:

\begin{code}
:- pce_begin_class(ClassName, SuperClassName, [Comment]).

<variable and method definitions>

:- pce_end_class.
\end{code}

These two predicates manipulate Prolog's macro processing and Prolog's
operator table, which changes the basic syntax.

An (additional) instance variable for the class is defined using

\begin{code}
variable(Name, Type, Access, [Comment]).
\end{code}

Where `Name' is the name of the instance variable, `Type' defines the
type and `Access' the implicit side-effect-free methods:
{\tt\{none,get,send,both\}}.

The definition of a method is very similar to the definition of an
ordinary Prolog clause:

\begin{code}
name(Receiver, Arg1:Type1, ...) :->
	"Comment"::
	Normal Prolog Code.
\end{code}

Defines a send method for the current class.  `Receiver', `Arg1', ...
are Prolog variables that are at runtime bound to the corresponding
XPCE objects.  The body of the method is executed as any normal
Prolog clause body.  The definition of a get method is very similar:

\begin{code}
name(Receiver, Arg1:Type1, ..., ReturnValue:ReturnType) :->
	"Comment"::
	Normal Prolog Code.
\end{code}

The body is supposed to bind `ReturnValue' to the return value of the
method or fail.


\subsection{Called methods}

Some methods are called by the infra-structure of XPCE.  These methods
may be redefined to modify certain aspects of the class.  The most
commonly redefined methods are:

\begin{table}
\begin{tabular}{lp{5in}}
initialise	& Called when an instance of the class is created \\
unlink		& Called when an instance is destroyed \\
event		& Called when an event arrives on the (graphical) object \\
geometry	& Called when the size/position of a (graphical) object
		  is changed \\
\end{tabular}
\end{table}


\subsection{Examples}

\subsubsection{Defining a two-dimensional matrix}	\label{sec:2dvector}

The first example defines a class two-dimensional matrix of fixed size.
We want to be able to say:

\begin{code}
?- new(@matrix, matrix(3,3)).
?- send(@matrix, element, 2, 2, x).
?- send(@matrix, element, 1, 2, o).
\end{code}

We will implement the two-dimensional matrix as a subclass of the one
dimensional vector:

\begin{code}
:- pce_begin_class(matrix(width, height), vector, "Two-dimensional array").

variable(width, 	int,	get, "Width of the matrix").
variable(height, 	int,	get, "Height of the matrix").

initialise(M, Width:int, Height:int) :->
	"Create matrix fom width and and height"::
	send(M, send_super, initialise),
	send(M, slot, width, Width),
	send(M, slot, height, Height),
	Size is Width * Height,
	send(M, fill, @nil, 1, Size).

element(M, X:int, Y:int, Value:any) :->
	"Set element at X-Y to Value"::
	get(M, width, W),
	get(M, height, H),
	between(1, W, X),
	between(1, H, Y),
	Location is X + (Y * (W-1)),
	send(M, send_super, element, Location, Value).
:- pce_end_class.
\end{code}


\subsubsection{Defining a graphical matrix (table)}

In the second example, we will define a graphical matrix of textual
values and similar access functions to set/get the (string) values
for the cells.   We will use class device as a starting point.  Class
device defines a compound graphical object.

\begin{code}
:- pce_begin_class(text_table(width, height), device,
		   "Two-dimensional table").

initialise(T, W:int, H:int, CellWidth:[int], CellHeight:[int]) :->
	"Create from Width, Height and cell-size"::
	send(T, send_super, initialise),
	default(CellWidth, 80, CW),
	default(CellHeight, 20, CH),
	Pen = 1,
	between(1, W, X),
	    between(1, H, Y),
		GX is (X-1) * (CW-Pen),
		GY is (Y-1) * (CH-Pen),
		send(T, display, new(B, box(CW, CH)), point(GX, GY)),
		send(B, pen, Pen),
		new(Txt, text('', center)),
	        xy_name(X, Y, XYName),
		send(Txt, name, XYName),
		send(Txt, center, point(GX + CW/2, GY + CH/2)),
 		send(T, display, Txt),
	fail ; true.


element(T, X:int, Y:int, Value:char_array) :->
	"Set text of cell at X-Y"::
	xy_name(X, Y, XYName),
	get(T, member, XYName, Text),
	send(Text, string, Value).

xy_name(X, Y, Name) :-
	get(string('%d,%d', X, Y), value, Name).
:- pce_end_class.
\end{code}


\begin{exercises}
\exercise{%
Extend class matrix with a get-method <-element.  See what happens if
you define the return-type incorrect (for example as `int').
}

\exercise{%
We would like to {\em visualise} a matrix using a text_table object,
such that changes to the matrix are reflected on the text_table and
modifications of the text_table are reflected in the matrix.

XPCE does not provide a built-in model/controller architecture such as
SmallTalk.  There are various ways to relate objects to each other:
object-level attributes (see `object <->attribute'), instance-variables
and finally `hyper-links'.  See class hyper.

Try to realise the mapping using hyper objects.  See class hyper and
`object ->send_hyper'.  What are the (dis)advantages of all these
techniques?
}

\exercise{%
Advanced usage!  Suppose the matrix is used in heavy computations and
modified often.  This would imply passing through the mechanism
described above many times.  The display is not updated for each
intermediate state (unless you explicitly request this using `graphical
->flush').

To avoid part of the computation as well, you can use the mechanism
described by `graphical ->request_compute' and `graphical ->compute'.

Try to implement this interface.
}
\end{exercises}


\section{Types}

XPCE is an untyped language like Prolog.  This allows the system
to define container classes such as class chain, vector, hash_table
etc.\ in a comfortable fashion.  Unlike Prolog however, XPCE {\bf
allows} you to declare types.  Types are used for four purposes:

\begin{itemize}
    \tick{Documentation}
Given the name, argument-names and argument-types for each method
generally suffices to get a strong clue on what it does.
    \tick{Run-time trapping of errors}
The earlier errors are trapped, the easier it is to locate the
errornous statement in your source!
    \tick{Run-time conversion}
Each type defines a validation method and a conversion method.
If the first fails, the second is tried to convert the input value
to the requested type.  For example if the expected argument is
of type `int' and you provide the string ``554'' it will gracefully
convert ``554'' to the integer 554 and pass this value to the
implementation of the method.
    \tick{Ensuring some level of consistency in the data}
The predicate checkpce/0 collects all instances and verifies that
each instance-variable is consistent with the type-declaration.
\end{itemize}


\subsection{Types are not (only) classes}

Types are first-class objects that defined {\em validation} and {\em
conversion}.  Type objects are seldomly defined using
\mbox{new(X,~type(...))}, but normally by conversion of a
type-description to a type object.  Here is a brief summary of the
syntax used by `type <-convert':


\begin{tabular}{lp{4in}}
\tt Name=Type		&Argument named `Name' of type `Type' \\
\tt Type ...		&Zero or more of these arguments.
			 Used in variable-arguments methods. \\
\verb$Type1|Type2$	&Disjunction (either of the types) \\
\tt Type*		&The type or the constant @nil \\
\tt [Type]		&The type or @default (optional argument) \\
\tt \{Name1,Name2\}	&One of these names \\
\tt int			&An integer (the only non-object datum) \\
\tt 3..5		&An integer 3 $\leq$ value $\leq$ 5 \\
\tt 3.2..5.6		&A real (float) in this range \\
\tt 3..			&An integer $\geq$ 3 \\
\tt ..3			&An integer $\leq$ 3 \\
\tt ClassName		&Any instance of this class (or sub-class) \\
\tt alien:char *	&Alien (C) data.  In this case a char *
\end{tabular}


\subsection{Programming conversion}

The reserved get-method <-convert has the task to convert an incomming
object to an instance of the specified class.


\begin{exercises}

\exercise{%
If an argument is specified as type `bool', what values are acceptable
as input.
}

\exercise{%
Advanced usage: A very common usage for conversion is a class with
uniquely named reusable objects.  Try to define such a class.  You will
have to define the methods ->initialise, <-lookup and <-convert.  }

\end{exercises}



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Tracing and Debugging}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

This chapter provides a brief overview of the tracer.  Besides the
tracer, the VisualHierachy and Inspector tools are very useful
tools for locating problems with your application.  See
section~\ref{sec:manualtools}.


\section{Tracing PCE Methods and Executable Objects}

XPCE offers tracing capabilities that are similar to those found in
many Prolog and Lisp environments.  The XPCE tracer is defined at
the level of class program_object.  Executable objects (messages,
etc.), and methods are the most important subclasses of class
program_object.   Execution of program_objects can be monitored at
three `ports':

\begin{itemize}
    \tick{The call port}
Entry point of executing the object.
    \tick{The exit port}
The object executed successfully.
    \tick{The fail port}
Execution of the object failed.
\end{itemize}

On each port, the user can specify a {\bf trace-} point or a {\bf
break-} point.  A trace-point will cause a message printed when the
port is `passed'.  A break-point will do the same and start the
interactive tracer (similar to a {\it spy-} point in Prolog.

The Prolog predicates ({\tt no})tracepce/1 and ({\tt no})breakpce/1%
	\footnote{The XPCE debugging predicates are defined in the
		  library pce_debug.  For Prolog systems lacking
		  autoload you need to do
		  {\tt ?- [library(pce_debug)].}}
provide a friendly interface for setting trace- and break-points on
methods.  Example:

\begin{code}
?- tracepce((point->x)).
Trace variable: point <->x

?- new(P, point), send(P, x, 20).
PCE:  2 enter: V @892203/point <->x: 20
PCE:  2 exit: V @892203/point <->x: 20

P = @892203/point 
\end{code}

Both tracepce/1 and breakpce/1 accept a specification of the form
$<$Class$>$ {\tt ->, <- or -}$<$Selector$>$.

\begin{code}
?- tracepce((box->device)).

?- send(new(@p, picture), open).
?- send(@p, display, new(@b, box(20,20))).
\end{code}


\subsection{Trapping situations: conditional breaks}

Suppose a graphical is at some point erased from the screen while you
do not expect this to happen.  How do you find what is causing the
graphical to disappear and from where this action is called?  If your
program is small, or at least you can easily narrow down the possible
area in your code where the undesired behaviour happens, just using
the Prolog tracer will generally suffice to find the offending call.

What if your program is big, you don't know the program to well and
you have no clue?  You will have to work with conditional trace- and
breakpoints to get a clue.  If you know the reference of the offending
object (lets assume @284737), you can spy all send-operations invoked
using:

\begin{code}
?- send(@vmi_send, trace, @on, full, @receiver == @284737).
\end{code}

If---for example---you finally discovered that the object is sent
the message ->device: @nil, you can trap the tracer using:

\begin{code}
?- send(@vmi_send, break, @on, call, and(@receiver == @284737,
					 @selector == device)).
\end{code}


\begin{exercises}
\exercise{%
Consider PceDraw.  Use the XPCE tracer to find out what happens to
an object if the {\em Cut} operation is activated.
}
\end{exercises}



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Dialogue Windows in Depth}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Modal Dialogue Windows (Prompters)}

A common use is to query or inform the user during an ongoing task. The
task is blocked until the user presses some button. For example, the
user selected `Quit' and you want to give the user the opportunity to
save before doing so or cancel the quit all the way.

{\em Model} dialog windows are the answer to the problem.  In XPCE,
Windows by themselves are not {\em modal}, but any window may be
operated in a {\em modal} fashion using the method `frame <-confirm'.

This method behaves as `frame->open' and next starts an
event-dispatching subloop until `frame ->return' is activated.  So,
our quit operation will look like this:

\begin{code}
quit :-
	new(D, dialog('Quit my lovely application?')),
	(   application_is_modified
	->  send(D, append,
		 button(save_and_quit,
			message(D, return, save_and_quit)))
	;   true
	),
	send(D, append, button(quit, message(D, return, quit))),
	send(D, append, button(cancel, message(D, return, cancel))),

	get(D, confirm, Action),
	send(D, destroy),
	(   Action == save_and_quit
	->  save_application
	;   Action == quit
	->  true
	),
	send(@pce, die).
\end{code}


\section{Entering Values}

Operations often require multiple values and dialog windows are a 
common way to specify the values of an operation.  Actually executing
the operation is normally associated with a button.  Below is an
example of a dialog for this type of operations.

\begin{code}
create_window :-
	new(D, dialog('Create a new window')),
	send(D, append, new(Label, text_item(label, 'Untitled'))),
	send(D, append, new(Class, menu(class, choice))),
	send_list(Class, append,
		  [ class(window),
		    class(picture),
		    class(dialog),
		    class(browser),
		    class(view)
		  ]),
	send(D, append,
	     new(Width, slider(width, 100, 1000, 400))),
	send(D, append,
	     new(Height, slider(height, 100, 1000, 200))),
	send(D, append,
	     button(create,
		    message(@prolog, create_window,
			    Class?selection,
			    Label?selection,
			    Width?selection,
			    Height?selection))),
	send(D, append,
	     button(cancel, message(D, destroy))),
	send(D, open).


create_window(Class, Label, Width, Height) :-
	get(Class, instance, Label, Window),
	send(Window?frame, set, @default, @default, Width, Height),
	send(Window, open).
\end{code}

Note that a menu accepts the method ->append: menu_item.  Class
menu_item defines a type-conversion converting any value to a
new menu_item using the value as `menu_item <->value'.  The visible
labels of the menu_items are generated automatically (see `menu_item
<-default_label').

The action associated with the button is a message invoking the Prolog
predicate create_window/4.  Four obtainers collect the values to be
passed.


\section{Editing Attributes of Existing Entities}

All dialog items that may be used to edit attributes (i.e.\ represent
some value) define a <->default value and the methods ->restore and
->apply.  <->default specifies an XPCE {\em function} object or plain
value.  On ->restore, the <-selection is restored to the <-default or
the result of evaluating the <-default function.  ->apply will execute
<-message with the current <-selection if the <-selection has been
changed by the user.

Class dialog defines the methods ->restore and ->apply, which
will invoke these methods on all items in the dialog that understand
them.  This schema is intended to define {\em attribute} editors
comfortably.

Below we define a dialog-window to edit some appearance values of a
box object.

\begin{code}
edit_box(Box) :-
	new(D, dialog(string('Edit box %N', Box))),
	send(D, append,
	     text_item(name, Box?name, message(Box, name, @arg1))),
	send(D, append,
	     new(S, slider(pen, 0, 10, Box?pen, message(Box, pen, @arg1)))),
	send(S, width, 50),
	send(D, append, button(apply)),
	send(D, append, button(restore)),
	send(D, append, button(cancel, message(D, destroy))),
	send(D, default_button, apply),
	send(D, open).
\end{code}


\section{Status, Progress and Error Reporting}

XPCE defines a standard protocol for reporting progress, errors, 
status, etc.  This protocol is implemented by two methods: the
send-method ->report and the get-method <-report_to.  The aim
is to provide the application programmer with a mechanism that
allows for reporting things to the user without having to know
the context of the objects involved.

\subsection{Generating reports}

For example, you define a predicate my_move that moves a graphical
to some location, but not all locations are valid.  You can simply
define this using:

\begin{code}
my_move(Gr, Point) :-
	(   valid_position(Gr, Point)
	->  send(Gr, move, Point)
	;   send(Gr, report, warning,
		 'Cannot move %N to %N', Gr, Point)
	).
\end{code}

The first argument of ->report is the type of report.  The reporting
mechanism uses this information to decide what to do with the report.
The types are: {\em status}, {\em warning}, {\em error}, {\em inform},
{\em progress} and {\em done}. 

\subsection{Handling reports}

A default report handling mechanism is defined that will try to
report in a {\em label} object called {\em reporter} in a dialog
window in the frame from where the command was issued.  If no such
label can be found important (error, inform) reports are reported
using a confirmer on the display.  Less serious (warning) are reported
using the ->alert mechanism (->bell, ->flash) and others are ignored.

Most applications therefore can just handle all reports by ensuring the
frame has a dialog window with a label called {\em reporter} in it.
In specific cases, redefining ->report or <-report_to can improve
error reporting.

\begin{exercises}

\exercise{%
Define a dialog based application that allows you to inspect the
properties of Prolog predicates.  Use predicate_property/2 and
source_file/2.  The dialog should have appropriate fields for
the file the predicate is defined in, whether it is dynamic
or not, multiple, built-in, etc.

Use a browser to display all available predicates.  Double-clicking
on an predicate in the browser should show the predicate in the
dialog.
}


\end{exercises}

\section{Custom Dialog-Items}

As from XPCE version 4.7 (ProWindow 1.1), graphics and dialog_items are
completely integrated.  This implies that custom dialog-items can be
constructed using general graphics as well as other dialog-items.

Dialog-items should respond in a well-defined manner to a number of
messages and have standard initialisation arguments.  These methods
are:

\begin{description}
\sendmethod{item}{initialise}{Name:name, Default:[any], Message:[code]*}
    Items are normally created from their {\em Name}, which is processed
    by `char_array <-label_name' to produce a capitalised visible label,
    the {\em Default} value and a message to execute on ->apply or
    operation of the item.
\sendmethod{item}{selection}{Value:any}
    Sets the selection.  After this, <-modified is supposed to return
    @off.
\getmethod{item}{selection}{Value:any}
    Return the current selection.
\sendmethod{item}{default}{Value:any}
    Sets the {\em default} value and the ->selection.  If ->restore
    is called after the user modified the item and before it is
    ->apply'd, the <-selection should be restored to the <-default.
    Normally called by ->initialise.  Normally implemented by setting
    the -default slot and calling ->restore.
\sendmethod{item}{restore}{}
    Normally simply invokes ->selection with <-default.
\sendmethod{item}{apply}{Force:[bool]}
    If <-modified returns @on or Force equals @on, forward the
    <-selection over @arg1 of the <-message.
\end{description}

The XPCE library (`@pce <-home'/prolog/library) contain various examples
of custom dialog items.	 See for example pce_font_item.pl (consists of
three cycle-menus for specifying a PCE font), pce_style_item.pl (enter
a style (font, colour, underline, etc.) for an editor-fragment).  The
dialog editor contains various examples as well.

\begin{exercises}
\exercise{%
Study the pce_font_item.pl file.  Use the font_item to control the
font of a simple text object.  Analyse the structure of the application
using the Visual Hierarchy tool.
}
\end{exercises}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Graphics}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

In this chapter we will build a little direct-manipulation graphical
editor.  The application consists of a graphical editor that allows the
use to define entities and their interrelations involved.


\section{Graphical Devices}

A graphical device (class device) defines a compound graphical object
with it's own local coordinate system.  Graphical devices may be nested.

Graphical devices are usually subclassed to define application-specific
visual representations.  As a first step towards our graphical
application, we will define a box with centered text and a possibly grey
background.

\begin{code}
:- pce_begin_class(text_box, device, "Box with centered text").

resource(size,		size,	'size(100, 50)',	"Default size").
resource(label_font,	font,	'@helvetica_bold_12',	"Font for text").

initialise(TB, Label:[name]) :->
	"Create a box with centered editable text"::
	send(TB, send_super, initialise),
	get(TB, resource_value, size, size(W, H)),
	get(TB, resource_value, label_font, Font),
	send(TB, display, box(W, H)),
	send(TB, display, new(T, text(Label, center, Font))),
	send(T, transparent, @off),
	send(TB, recenter).


recenter(TB) :->
	"Center text in box"::
	get(TB, member, box, Box),
	get(TB, member, text, Text),
	send(Text, center, Box?center).


geometry(TB, X:[int], Y:[int], W:[int], H:[int]) :->
	"Handle geometry-changes"::
	get(TB, member, box, Box),
	send(Box, set, 0, 0, W, H),
	send(TB, recenter),
	send(TB, send_super, geometry, X, Y).


fill_pattern(TB, Pattern:image*) :->
	"Specify fill-pattern of the box"::
	get(TB, member, box, Box),
	send(Box, fill_pattern, Pattern).
fill_pattern(TB, Pattern:image*) :<-
	"Read fill-pattern of the box"::
	get(TB, member, box, Box),
	get(Box, fill_pattern, Pattern).


string(TB, String:char_array) :->
	"Specify string of the text"::
	get(TB, member, text, Text),
	send(Text, string, String).
string(TB, String:char_array) :<-
	"Read string of the text"::
	get(TB, member, text, Text),
	get(Text, string, String).

:- pce_end_class.
\end{code}


\section{Making Graphicals Sensitive}		\label{sec:sensitive}

\subsection{Adding popup menus to graphicals}

In this section we will use the text_box defined in the previous section
to define a graphical editor that allows you to create a graph of with
text-boxes as nodes.  In the first step we will define window that
allows us to add new text-boxes to it using a background popup.  We
will prompt for the text to be put in the box.

\begin{code}
:- use_module(library(pce_prompter)).

make_graph_editor(E) :-
	new(E, picture('Graph Editor')),
	send(E, popup, new(P, popup(options))),
	send_list(P, append, 
		  [ menu_item(add_new_box,
			      message(@prolog, add_new_box,
				      E, E?focus_event?position)),
		    menu_item(clear,
			      and(message(@display, confirm,
					  'Clear entire drawing?'),
				  message(E, clear)))
		  ]),
	send(E, open).


add_new_box(E, Pos) :-
	prompter('Name of box',
		 [ name:name = Name
	         ]),
	send(E, display, text_box(Name), Pos).
\end{code}


\subsection{Using gestures}


A gesture is an object that is designed to parse mouse-button event
sequences into meaningful actions.  XPCE predefines gestures for
clicking, moving, resizing, linking and drag-drop of graphical objects.

All gesture classes are designed to be subclassed for more application
specific handling of button-events.

There are two ways to connect a gesture to a graphical object.  The
first is `graphical ->recogniser' which makes the gesture work for
a single graphical object.  The alternative is to define an ->event
method for the graphical.  Below we will use this to extend our
text-box class with the possibility to move and resize the boxes.%
    \footnote{In this example we define the class text_box in small
	      parts that can be loaded on top of each other.  We
	      use {\tt :- pce_extend_class(+Class).} to continue
	      the class-definition.}

\begin{code}
:- pce_extend_class(text_box).

:- pce_global(@text_box_recogniser,
	      make_text_box_recogniser).

make_text_box_recogniser(R) :-
	new(R, handler_group(new(resize_gesture),
			     new(move_gesture),
			     popup_gesture(new(P, popup(options))))),
	TB = @arg1,
	send_list(P, append,
		  [ menu_item(rename,
			      message(TB, rename),
			      end_group := @on),
		    menu_item(delete,
			      message(TB, free))
		  ]).
	    

event(TB, Ev:event) :->
	(   send(TB, send_super, event, Ev)
	->  true
	;   send(@text_box_recogniser, event, Ev)
	).


rename(TB) :->
	"Prompt for new name"::
	prompter('Rename text box',
	         [ name:name = Name/TB?string
	         ]),
	send(TB, string, Name).

:- pce_end_class.
\end{code}


\section{Graphs: Using Connections} \label{sec:connect}

A connection is a line connecting two graphical objects.   A connection
has typed end-points that can attach to a {\em handle} of the same
type.  If multiple such handles exist, the system will attach to the
`best' one using some simple heuristics.

Below is the code fragment that allows you to link up graphicals by
dragging from the one to the other with the left-button held down.

\begin{code}
:- pce_extend_class(text_box).

handle(0, h/2,	link,	west).
handle(w, h/2,	link,	east).
handle(w/2, 0,	link,	north).
handle(w/2, h,	link,	south).

:- pce_global(@link_recogniser, new(connect_gesture)).

event(TB, Ev:event) :->
	(   send(TB, send_super, event, Ev)
	;   send(@text_box_recogniser, event, Ev)
	;   send(@link_recogniser, event, Ev)
	).

:- pce_end_class.
\end{code}


\section{Reading the Diagram}

XPCE has been designed to be able to create drawings that can be
interpreted.  This design is exemplified by the use of connections.  If
the drawing had been built from just lines, boxes and text it would have
been difficult to convert the drawing into a Prolog representation of
a graph.  Connections explicitly relate {\em graphical object} instead
of positions.

Below is a Prolog fragment that generates a Prolog fact-list from the
graph.

\begin{code}
assert_graph(E, Predicate) :-
	functor(Term, Predicate, 2),
	retractall(Term),
	send(E?graphicals, for_all,
	     if(message(@arg1, instance_of, connection),
		message(@prolog, assert_link,
			Predicate,
			@arg1?from?string?value,
			@arg1?to?string?value))).

assert_link(Predicate, From, To) :-
	Term =.. [Predicate, From, To],
	assert(Term).
\end{code}


\begin{exercises}
\exercise{%
Extend the graph-editor's frame with a dialog window that allows for
saving the graph to the Prolog database.
}
\exercise{%
The example in section~\ref{sec:connect} uses a generic connect gesture
and a generic connection.  Make a refinement of class connect_gesture
that creates instances of a class arc_connection.  Define class
arc_connection as a subclass of class connection that has a popup
attached which allows the user to delete the connection.
}
\exercise{%
Write a predicate to create a graph from a list of Prolog facts defining
the graph.  Add a possibility to load a graph to the dialog window.
}
\exercise{%
Experiment with the `graphical ->layout' method to create some layout
for the graph-elements created in the above exercise
}
\end{exercises}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% Process interface
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\input process.tex

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% Using XPCE as a database
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Representation and Storing Application Data}

There are various alternatives for representing application data in
XPCE/Prolog.  The most obvious choice is to use Prolog.  There
are some cases where XPCE is an alternative worth considering:%
	\footnote{
Using XPCE for storage of application-data has been used in three
Esprit-funded projects for the development of knowledge acquisition
tools: `Shelley' (storage only), The `Common Kads WorkBench' (using XPCE
for OO control structure) and `KEW' (Common Lips, Using XPCE for
storage only).  In the `Games' project XPCE user-defined classes
are only used for specialising the UI library.  CLOS is used for
storing application data.

Representing `knowledge' in XPCE to be used for reasoning in Prolog or
Lisp is difficult due to the lack of `natural' access to the knowledge
base.  Representing text and drawings in XPCE works well.}


\begin{itemize}
    \tick{Store data that is difficult to represent in Prolog}
The most typical example are hyper-text and graphics.  XPCE has
natural data-types for representing this as well as a save and
load facilities to communicate with files.
    \tick{Manipulations that are hard in Prolog}
XPCE has a completely different architecture than Prolog: its
basic control-structure is message passing and it's data-elements
are global and use destructive assignment.  These properties can
make it a good alternative for storing data in the recorded or
clause database of Prolog.
    \tick{You want to write a pure OO system}
Not only can you model your interface, but also the {\em application}
as a set of XPCE classes.  This provides you with a purely object
oriented architecture where XPCE is responsible for storage and message
passing and Prolog is responsible for implementing the methods.
\end{itemize}


\section{Data Representation Building Blocks}	\label{chap:data}

In this section we will discuss the building-blocks for
data-representation using XPCE.  We start with the data {\em organising}
classes:

\begin{itemize}
    \tick{chain}
A chain is a single-linked list.  Class chain defines various
set-oriented operations and iteration primitives.
    \tick{vector}
A vector is a dynamically expanding one-dimensional array.
Multi-dimensional arrays may be represented as vectors holding
vectors or using a large one-dimensional array and redefine
the access methods.  See also section~\ref{sec:2dvector}.
    \tick{hash_table}
A hash-table maps an arbitrary key on an arbitrary value.  Class
hash_table defines various methods for finding and iteration over
the associations stored in the table.  Class chain_table may be
considered to associate a single key with multiple values.
\end{itemize}

For the representation of frames and relations, XPCE offers the
following building-blocks:

\begin{itemize}
    \tick{sheet}
A sheet is a dynamic attribute-value set.  Cf. a property list in
Lisp.
    \tick{Refining class object}
A common way to define storage primitives is by modeling them
as subclasses of class object.  This way of modeling data allows
you to exploit the typing primitives of XPCE.  Modeling as classes
rather than using dynamic sheets also minimises storage overhead.
    \tick{hyper}
A hyper is a relation between two objects.  The classes hyper and 
objects provide methods to define the semantics of hypers and to
manipulate and exploit them in various ways.

A hyper is a simple and safe way to represent a relation between
two objects than cannot rely on their mutual existence.
\end{itemize}


\section{A Simple Database}

In this section we will define a simple family database.%
    \footnote{Unfortunately we cannot use class data for representing
	      dates as the current implementation only ranges from
	      the Unix epoch (Jan 1 1970 to somewhere in the 22-nth
	      century).}
This example used hyper-objects to express marriage and child relations.
The advantage of hyper-objects is that they will automatically be
destroyed if one of the related objects is destroyed and they may
be created and queried from both sides.


\begin{code}
:- pce_begin_class(person, object, "Person super-class").

variable(name,		name,	both,	"Name of the person").
variable(date_of_birth, name,	both,	"Textual description of date").

initialise(P, Name:name, BornAt:name) :->
	send(P, send_super, initialise),
	send(P, name, Name),
	send(P, date_of_birth, BornAt).

father(P, M:male) :<-
	"Get my father"::
	get(P, hypered, father, M).

mother(P, M:female) :<-
	"Get my mother"::
	get(P, hypered, mother, M).

sons(P, Sons:chain) :<-
	"Get my sons"::
	get(P, all_hypers, Hypers),
	new(Sons, chain),
	send(Hypers, for_all,
	     if(@arg1?forward_name == son,
		message(Sons, append, @arg1?to))).

daughters(P, Daughters:chain) :<-
	"Get my daughters"::
	get(P, all_hypers, Hypers),
	new(Daughters, chain),
	send(Hypers, for_all,
	     if(@arg1?forward_name == daughter,
		message(Daughters, append, @arg1?to))).

:- pce_end_class.


:- pce_begin_class(female, person, "Female person").

mary(F, Man:male) :->
	"Marry with me"::
	(   get(F, husband, Man)
	->  send(F, report, error, '%N is already married to %N', F, Man),
	    fail
	;   new(_, hyper(F, Man, man, woman))
	).

husband(F, Man:male) :<-
	"To whom am I married?"::
	get(F, hypered, man, Man).

deliver(F, M:male, Name:name, Date:name, Sex:{male,female}, Child:person) :<-
	"Deliver a child"::
	(   Sex == male
	->  new(Child, male(Name, Date)),
	    new(_, hyper(F, Child, son, mother)),
	    new(_, hyper(M, Child, son, father))
	;   new(Child, female(Name, Date)),
	    new(_, hyper(F, Child, daughter, mother)),
	    new(_, hyper(M, Child, daughter, father))
	).

:- pce_end_class.


:- pce_begin_class(male, person, "Male person").

mary(M, F:female) :->
	"Marry with me"::
	send(F, mary, M).

wife(M, Female:female) :<-
	"To whom am I married?"::
	get(M, hypered, woman, Female).

:- pce_end_class.
\end{code}

\begin{exercises}

\exercise{%
Load the file family.pl containing the example above and enter a simple
database by hand.  Inspect the data-representation using the inspector
and online manual tools.
}

\exercise{%
Design and implement a simple graphical editor for entering a database.
What visualisation will you choose?  What UI technique will you use
for marriage and born children?
}

\exercise{%
The current implementation does not define an object that reflects the
entire database.  Define and maintain a hash-table that maps names onto
person entries.  You can redefine destruction of an object by redefining
the ->unlink method.
}
\end{exercises}