appendix a: a quick tour of turbo prolog what is tu~o prolog?978-3-540-46840-0/1.pdf · appendix a:...

105
APPENDIX A: A QUICK TOUR OF TURBO PROLOG WHAT IS TU~O PROLOG? PROLOG is an acronym for programming in logic. It was created in 1972 by the Faculty of Sciences, Luminy, in Marseilles, France. Prolog as described in Clocksin and Mellish' book, "Programming in Prolog', which is generally known as C&M Prolog, is widely accepted as the standard version of Prolog. TURBO Prolog, created by Bor!and Inc., is an IBM PC implementation of Prolog. This creation is a fast running version of Prolog which is both a subset and a superset of C&M Prologo The key features of this implementation of Prolog are described in this Appendix° PROGRAMMING IN PROLOG Programming in Prolog consists of the following: - Declaring some facts about objects and their relationships, - Defining some rules about these and their relationships, and - Asking questions (in the form of "goals") about these objects and their relationships. objects The notions of facts, rules and goals may be stated as follows.

Upload: phungnhan

Post on 25-Jun-2018

213 views

Category:

Documents


0 download

TRANSCRIPT

APPENDIX A: A QUICK TOUR OF TURBO PROLOG

WHAT IS TU~O PROLOG?

PROLOG is an acronym for programming in logic. It was created in

1972 by the Faculty of Sciences, Luminy, in Marseilles, France.

Prolog as described in Clocksin and Mellish' book, "Programming

in Prolog', which is generally known as C&M Prolog, is widely

accepted as the standard version of Prolog. TURBO Prolog,

created by Bor!and Inc., is an IBM PC implementation of Prolog.

This creation is a fast running version of Prolog which is both a

subset and a superset of C&M Prologo The key features of this

implementation of Prolog are described in this Appendix°

PROGRAMMING IN PROLOG

Programming in Prolog consists of the following:

- Declaring some facts about objects and their

relationships,

- Defining some rules about these and their

relationships, and

- Asking questions (in the form of "goals") about these

objects and their relationships.

objects

The notions of facts, rules and goals may be stated as follows.

FACTS

83

Facts define relationships among objects. For example, a

fact may be stated as

teaches(smith, math)

which means that there is a relationship "teaches"

between objects "smith" and "math".

The order of objects (smith, math) is important in

stating a fact for the correct interpretation of that

fact.

The name of a fact is called a predicate and the objects

involved in the predicate are called arguments. In the

above example, "teaches" is a predicate and "smith" and

"math" are the arguments.

A collection of facts is called a database. A typical

Prolog database is shown below.

teaches(smith,math)

teaches(schriber,electronics)

teaches(prabhakar,prolog)

teaches(barua,unix)

teaches(smith,lisp)

Figure AI: A TYPICAL PROLOG DATABASE

GOALS

A goal has the same form as a fact. Whenever a goal is posed,

84

Prolog searches through its database to check if the goal is true

or false. This is done as follows. Two facts match if their

predicates as well as the corresponding arguments are identical.

If a match is found, Prolog comes back with the answer "true".

Otherwise it returns "false". For example, in reference to the

database of Figure AI, one may ask: teaches(smith,math).

Prolog will respond "true".

RULES

Rules may be compared to IF-THEN statements of conventional

programming

generalized

relationships.

the following.

languages. In Prolog terminology, rules are

statements about different objects and their

For example, the relationship "taught" may imply

Smith has taught anyone whose department is math and who has

credited OR. This relationship may be generalized into a rule:

Smith has taught X, where department of X is

math and X has credited OR.

This generalized rule may be written in Prolog as

taught(smith~x):- dept(x,math), credits(x,or)

One may easily note that the above rule has two parts: the head

taught(smithtx) and the body dept(x,math), credits(x,or).

The comma between goals dept and credits denotes the conjunction.

The comma implies that both goals must be satisfied for the

85

overall goal to succeed (i.e. be true). In general, the body of

a rule will be a conjunction of subgoals. The :- notation

implies that the left hand side is true if the right hand side is

true.

CLAUSES

The difference between a fact and a rule is that a fact does not

have subgoals. A "clause" in Prolog is a general term for a fact

or a rule. In the example of Figure AI, "taught" and "dept" are

both clauses.

VARIABLES

Variables allow us to pose generalized goals. For example, if we

wish to find which courses are taught by Smith, then instead of

taking each possible subject and trying it to match it with the

facts in the database, a generalized goal may be posed as

teaches(smith,X)

Note here the use of upper case X, which denotes a variable. On

encountering this goal Prolog will search its database and will

give a list of all "X" values in the database that satisfy this

goal, as follows.

X = math

X = lisp

86

At any time variables may be "instantiated" (bound to a certain

value, e.g. statistics) or "uninstantiated" (not bound to any

particular values)o

BACKTRACKING

In Prolog~ each goal keeps its own "place marker" in the

database° For example, in attempting to check the following goal

(to be true or false)

teaches(smith,X), credits(barua, X)

Prolog starts with an attempt to satisfy the first (sub)goal. If

this first goal is in the database, Prolog will mark the place of

this match in the database and then try to match the second goal

from the start of the database. If the second goal fails, Prolog

will go back to the place of last instantiation of X, i.e. the

place marker of the first goal and start searching through the

remainder of the database for another match.

If another match to the first goal is found, Prolog will attempt

to satisfy the second goal again with this second instantiated

value for X, from the start of the database (see Figure A2).

Thus in a chain of goals, if any one goal fails, Prolog

backtracks to the previous goal and tries to prove it again with

another variable binding (instantiation). Prolog moves

relentlessly forward and backward through the conditions, trying

every available binding in an attempt to get the goal to succeed

in as many ways as possible. The solution is displayed as a list.

87

IM ARKER = START OF DATABASE

TRY TO SATISFY THE LEFT-MOST GOAL FROM MARKER DOWN

!

PUT A MARKER AT SATISFIED GOAL. I INSTANTIATE APPROPRIATE VARS (X) I !

REMOVE THE FIRST GOAL FROM THE CONJUNCTION. RECURS

WITH REDUCED LIST.

NON-INSTANTIATE VARIABLES AT THIS GOAL. RESTART FROM PLACE MARKER

..... ~ y

N /~IS THERE A ~ N

Figure A2: BACKTRACKING MECHANISM IN PROLOG

CONTROL OF BACKTRACKING USING "CUT"

The primary purpose of "cut" is to prevent or stop backtracking

based on a specified condition. The cut predicate is specified

as an exclamation mark (!). It has no arguments and it always

succeeds. One it succeeds, two things happen:

1.

2.

88

There can be no backtracking on the goals towards the left

of the cut°

If there are other definitions of the predicate, other than

the current one, these are not tried.

For example~ consider a predicate "division" whose purpose is to

determine the grade for a student based on his percentage marks.

The clauses may be written as

grade(PERCENTAGE MARKS,GRADE):- PERCENTAGE MARKS>75, GRADE="A",!.

grade(PERCENTAGE MARKS,GRADE):- PERCENTAGE MARKS>60, GRADE="B",!.

grade(PERCENTAGE MARKS,GRADE):- PERCENTAGE MARKS>50, GRADE="C",!.

grade ( PERCENTAGE MARKS, GRADE ) : - GRADE=" F".

If this predicate is tried (ignoring the cut) with

PERCENTAGE MARKS=80, all the four rules will succeed and Prolog

will give four answers. But this is not desired. When a cut is

placed in the first rule, the moment that rule is satisfied (i.e.

PERCENTAGE MARKS>75) no further definitions are tried.

This is one way of using the cut~ There are many other ways in

which a cut may be used to control backtracking in Prolog.

DATA TYPES IN TURBO PROLOG

The basic data type in Prolog is a "term".

the different types which a term can take.

Figure A3 identifies

89

TERM

I VARIABLES

X,COURSE

I OBJECTS

I NON-VARIABLES

i i

LISTS

i OTHERS

I !

STRUCTURES

[a,b,c,d], [1,345,12]

f I ! .... I !

SYMBOL STRING INTEGER REAL CHAR FILE

address(street, city,zip)

barua, "hello" i, 45 23.89 "a", xoutput, smith "smith" "A" facts

Figure A3: BASIC DATA TYPES IN TURBO-PROLOG

LISTS

A list is an ordered sequence of terms. The components of a list

should be of the same data type. Examples of valid lists are

name, numbers, etc., where

name=[smith,barua,codd] numbers=If,2,25]

A list can be written in several alternate ways, by showing its

head and tail. For example, for list "name" one may have

equivalent lists:

name=[smith,barua,codd] name=[smith¶[[barua,codd]] name=[smith¶[[barua~f[codd]]]

90

One may freely use the above equivalent notations to build

predicates for basic list manipulations such as intersection,

union, membership functions~ etc.

BUILT-IN PREDICATES

TURBO Prolog contains a variety of built-in predicates. These

standard predicates support a variety of repeatedly used tasks

and functionsr such as controls data input and output, screen

handling, type conversionsr etc.

DATABASES IN TURBO PROLOG

As mentioned earlier, a Prolog program is a database; Prolog

acts as a very powerful query language that can handle the

contents of this database. For instance, Prolog permits the

selection of facts from a database. The program, however, is a

static database. This implies that the database does not change

with time. Once a Prolog program has been compiled, the

knowledge in this database is frozen.

Prolog also has a dynamic database in which facts related to the

current problem being solved are stored. This dynamic database

is stored in memory along with the static database. The dynamic

database can be saved to disk using the save predicate and read

back using the consult predicate.

91

THE GENERAL STRUCTURE OF A TURBO PROLOG PROGRAM

The four sections in a TURBO Prolog program are as follows:

DOMAINS

data type declarations

DATABASE

predicates of dynamic database should be defined here

PREDICATES

every predicate must be declared in this section

CLAUSES

contain facts and rules

TURBO PROLOG PROGRAMMING ENVIRONMENT

TURBO Prolog has a user friendly environment with bouncing bar

menus. This is an interactive support that makes program

development fast. A display shows the environment screen.

Various menu options are as follows:

RUN

COMPILE

EDIT

OPTIONS

FILES

SETUP

QUIT

For running a program

For compiling a program

To enter the editor

To select compiler options (produce OBJ/EXE files)

File operations such as copy, rename, delete, etc.

To change window sizes, colors, directories, etc.

To quit the programming environment.

92

In the display, the editor window shows a predicate that will

check the membership of an element in a list. When it is run

(after compilation~ as shown in the message window), the dialog

window is activated. Goals may now be posed and solutions

obtained as shown. The trace window would show a step by step

progress of execution if desired.

APPENDIX B: CHRONICLE OF A TYPICAL DATABASE DESIGN SESSION WITH THE SYSTEM

SCREEN 1

PRELIMINARIES

are similar to paper files that data is stored on magnetic I media rather than on paper, j

In a database the different pieces of related information are grouped at one place. For example, a database may contain :

Roll No Name Class Home Town 8678 Kasturi M.Tech. Madras 8760 Vijay B.Tech. Delhi

The individual data items in a database (Roll No, Name, etc.) are called attributes.

Press any key to continue ......

SCREEN 2

PRELIMINARIES

are similar to paper files that data is stored on magnetic I media rather than on paper. I

Soon, You will be asked some questions regarding the attributes (i.e. data items) that will appear in your database.

You should answer these questions thinking as if you are building ordinary paper files for storing data.

Press any key to continue ......

94

SCREEN 3

-Attributes [data items to be stored ]

As you start the process of building your database you may already have a good idea about the data files you would like to have.

For example, for a inventory manage- ment database, you might have :

- a master file of parts - a master file of vendors

DIALOC Can you already foresee the data files you will need (Y/N) ?N

SCREEN 4

Attributes-

I data items to be stored mechno skll_no skll_cat mech_name

-ATTRIBUTES IN FILE:

DIALOC > Input the attributes you wish to store

Give one attribute per line ... At end press Return

> MECH_NO > SKLL_NO > SKLL_CAT > MECH_NAME > MECB_AG~

95

SCREEN 5

i -Attributes . . . . I data items to be stored

EXAMPLE OF GROUPS

In a STUDENT database with attributes :

Name, Rollno, Class, Street, City, Zip

we might have the following logical groups:

GROUP I: Name, Rollno, Class GROUP 2: Street, City, Zip

mech_no skll_no skll_cat mech_name mechage shop_no city supv prof

• ATTRIBUTES IN FILE: ..............

' DIALOG ,, I> - If you can now 'group" the above

attributes in some logical way, that would reduce the number of questions you will need to answer in this dialog (see example)

Press any key to continue ...

l "d Attributes--~ ata items to be stored

SCREEN 6

mech_no skll_no skll_cat mech_name meeh_age shopno city supv prof

--'ATTRIBUTES IN FILE: ....

l! DIALOG ......

> Can you see any such attribute groups (Y/N)?Y

> Please type the group name > MECHANIC

96

SCREEN 7

Attributes data items to be stored

mechanic mechno ~mechname mechage shopno

skllno skllcat city supv prof

ATTRIBUTES IN FILE:

l

DIALOC ............ > For Group : mechanic > Enter one attribute per line ,..

When done, press Return > MECH_NO > MECH NAME > MECH_AGE > SHOPNO > SKLLNO

L Attributes t items to be stored

SCREEN 8

ATTRIBUTES IN FILE; shop mech age shop_no shop_no city skllno sUpV prof

skill skll_no skll_cat

mechanic meeh_no mechname

DIALOC > To begin with we will make one file

for each group.

Attributes which are not in any group will be put in a file named 'ungrouped'.

> Press any key to continue ....

97

SCREEN 9

i Attributes data items to be stored

--FILES ......... ! mechanic I skill shop 1

,ATTRIBUTES IN FILE: shop meeh_age shop_no shop_no city skll_no supv prof

skill skll_no skll_cat

mechanic mech_no mech_name

............. DIALOG ...... f> In these files, you might be able

to further group the attributes.

> Press any key to continue ....

Attributes I data, items to be stored

--FILES ................ mechanic skill shop

SCREEN i0

ATTRIBUTES IN FILE: mechanic prof skll_no shop_no mech_age seth_name mech_no

~DIALOG ....... > In File: mechanic > Can you see any such attribute

groups (Y/N)?N

98

SCREEN ii

Attributes- data items to be stored

--FILES

mechanic 1 skill shop

] supv I city

shopno

ATTRIBUTES IN FILE: shop

i!

DIALOC , NEXT STEP

I ED T THE DATA 1 PROCEED WITH DIALOG I

SCREEN 12

Attributes- data items to be stored

supv city shop_no

ATTRIBUTES IN FILE; shop

EXAMPLE OF KE~--

For a STUDENTS file~

ROLL NO NAME CLASS

8769 Kasturi M.Tech. 8734 Vijay B.Tech.

ROLL NO is unique for all the entries in this file.

Hence ROLL NO is a KEY.

-DIALOC > In every file/group there will

be an attribute or a group of attributes called:

KEY whose value is unique for all the entries in that file/group.

Press any key to continue ....

99

SCREEN 13

a ... Attributes. dat items to be stored

KEy - l attribute(s) that determine values of all attributes

FILES ...... I chanic ill op

i sUpv city shop_no

ATTRIBUTES IN FILE: shop .....

DIALOC > In general, there may be more than

one key in a file (or a group).

> Press any key to continue ....

SCREEN 14

Attributes-,, ,data items to be stored

KEY ' attribute(s) that determine values of all attributes

--FILES ~mechanic iskill ~shop

KEYS

ipro f ATTRIBUTES IN FILE; mechanic ...........

Iskll_no shop_no imech_age mech_name mech_no

I DIALOC > Now for file: mechanic > Enter the attributes that form a key,

Enter one attribute per line, I When done, press return .> MECH_NO I > SKLL_N I > Undeclared/Mis-spelt attribute I > SKLL_NO

--L

100

Attributes

i data items to be stored

KEY. I attribute(s) that determine values of all attributes

--FILES--- mechanic skill shop

~ K E Y S FILE: mechanic skll_no,mechno.

SCREEN 15

...... ATTRIBUTES IN FILE: mechanic-- prof skllno shopno mechage mech_name mech_no

• DIALOC ........ { When done, press return i> MECH_NO I} SKLL_N

Undeclared/Mis-spelt attribute SKLL_NO

I > > Any more attributes in the key (Y/N)? > Are there any more keys (Y/N) ?N

SCREEN 16

--KEY ATTRIBUTES---- NON KEY ATTRIBUTES

--FILES 7 mechanic skill

i

.DIALOC .. > Locate the window titled KEY ATTRIBUTES

on the screen (upper left corner) and Also the NON KEY ATTRIBUTES window (up) Proceed now keeping these two windows in mind.

> Press any key to continue ....

101

SCREEN 17

~ FILES chanic ill op ....

--KEY ATTRIBUTE~- NON KEY ATTRIBUTES

.DIALOC > Normally key attributes will determine

the values of non-key attributes.

However, there may be exceptions.

> Press any key to continue ....

~ FILES chanic ill op

SCREEN 18

• {--KEY ATTRIBUTES--]- !prof shop_no mech_age mech_name

NON KEY ATTRIBUTES ...........

DIALOG ...... > In above windows do you see any key

attribute whose value depends on some of the non-key attributes (Y/N)? N

102

SCREEN 19

NON KEY ATTRIBUTES

--'Multi valued attributes' EXAMPLE :

ROLL NO COURSES TAKEN 8785 IMET02,CSSOI,IME624 8766 IMES02,IME624,ME851 8767 IME602,IME673,IME621 8769 HSS730,EE450

Here, COURSE TAKEN can be seen to take several values for any given value of the key, ROLL NO.

~DIALOC > Now we need to know which among the

attributes listed can take several values for any given value of the key (see example).

> Press any key to continue ....

SCREEN 20

-~Keys---------7- [ skll no,mech no. ~ |prof

1 |shop_no |mech_age

~ ~ I I mech-name

--'Multi valued attributes' EXAMPLE :

• NON KEY ATTRIBUTES

ROLL NO COURSES TAKEN 8765 IME602,CS601,IME624 8766 IME602,IME624,ME651 8787 IME602,IME873,IME821 8769 HSS730,EE450

Here, COURSE TAKEN can be seen to take several values for any given value of the key, ROLL NO.

DIALOC > Is there any attribute above which can

take several values for a single value of the key (Y/N)? N

103

SCREEN 21

shop_n---------~ Keys

Example of part key ....

Roll No Name Course Grade

1267 ATUL CADS A 1267 ATUL DPS B 1267 ATUL OR C 1270 JOY CADS C 1270 JOY DPS B

Key is (Roll No, Course) Name depends on only a part of the key, i.e. Roll No.

-I supv city

NON KEY ATTRIBUTES

DIALO(}.. > Here we want to see if there are

some attributes which depend on only a part of the key (see example).

> Press any key to continue ...

I ;or Key Ys ......

skll no,mech no.

Example of part ke~..

Roll No Name Course Grade

1267 ATUL CADS A 1267 ATUL DPS B 1267 ATUL OR C 1270 JOY CADS C 1270 JOY DPS B

Key is (Roll No, Course) Name depends on only a part of the key, i.e. Roll No.

SCREEN 22

I prof shopno mechage mech_name

NON KEY ATTRIBUTES

.... DIALOG > For the Key shown in KEYS window:

Is there any attribute which is affected by only a part of the key (Y/N)?Y

104

SCREEN 23

~ K E Y S - - For Key : skl l_no, mech_no.

. --Example of part key- . .

Roll No Name Course Grade

1267 ATUL CADS A 1267 ATUL DPS B 1267 ATUL OR C 1270 JOY CADS C 1270 JOY DPS B

Key is (Roll No, Course) Name depends on only a part of the key, i.e. Roll No.

prof shop_no mech_age mechname

NON KEY ATTRIBUTES

DIALOG .......

Is there any attribute which is affected by only a part of the key (Y/N)?Y > Please enter the part key attributes

one by one. When done, press Return > MECH_NO >

> Any more attributes in part key (Y/N)?N

SCREEN 24

......... l - - -

skli no,mech no.~

~. ............. Example of part key

l I Roll No Name Course Grade

1267 ATUL CADS A 1267 ATUL DPS B 1267 ATUL OR C 1270 JOY CADS C 1270 JOY DPS B

Key is (Roll No, Course) Name depends on only a part of the key, i.e. Roll No.

prof shop_no mech_age mech_name

NON KEY ATTRIBUTES..

DIALOG .................. > Please enter the part key attributes i one by one. When done, press Return '> MECHNO ~>

'> Any more attributes in part key (Y/N)?N i> Please type the affected attribute '> MECH NAME > Any more such attributes (Y/N)?Y

105

SCREEN 25

NORMALIZING ........................ > Retracting FD: ['~mech_no"] -> ["mech_name"] > Closure of LHS: ["mech_no","mech_age'~,"shop no","city","supv "] > Does not contain RHS, Asserting again > Retracting FD: ['shop_no"] -> ["city"] > Closure of LHS: ["shop no","supv"] > Does not contain RHS, Asserting again > Retracting FD: ["shop_no"] -> ["supv"] > Closure of LHS: ["shop no","city"] > Does not contain RHS, Asserting again > Retracting FD: ["skll_no"] -> ["skll_cat"] > Closure of LHS: ["skll_no"] > Does not contain RHS, Asserting again > Retracting FD: ["skll_no","mech_no"] -> ["prof"] > Closure of LHS: ["skll no","mech_no","skll_cat","mech name","mech age","shop _no","supv","city"] ~> Does not contain RHS, Asserting again > Redundant F.D's eliminated

!> Loss-less Join guaranteed > Eliminating redundant relations > 3rd NF obtained > Press any key to continue ....

SCREEN 26

.NORMALIZINC > 3rd NF obtained > Press any key to continue .... > Decomposing into BCNF the relation : skll_no,mech_no,prof. > Finding Projections > Decomposed relation: skll no,mech no,prof.

> Decomposing into BCNF the relation : skllno,skll_cat. > Finding Projections > Decomposed relation: skll_no,skll_cat.

> Decomposing into BCNF the relation : shop no,supv,city. > Finding Projections > Decomposed relation: shop_no,supv,city.

> Decomposing into BCNF the relation : mech_no,mech_name,mech_age,shop_no. > Finding Projections > Decomposed relation: mech_no,mechname,mechage,shop_no.

> Checking for dependency preservation > Final filing scheme will be written to a file - 'OUTPUT',

which can be printed using 'TYPE' command

> Press any key to continue ....

106

SCREEN 27

OUTPUT Notes

RELATION SCHEME IN FOURTH NORMAL FORM

ATTRIBUTES IN THE RELATION: mech_no, mech_name, mech_age, shop_no.

KEYS: mech_no,

ATTRIBUTES IN THE RELATION: shop no, supv, city.

KEYS: shop_no.

--Scroll PgUp-PgDn-Page Fi-Print page F2-Prin% all

SCREEN 28

OUTPUT Notes

ATTRIBUTES IN THE RELATION: skll_no, skll cat.

KEYS: skll_no.

ATTRIBUTES IN THE RELATION: skll no, mech no, prof.

KEYS: skll_no, mech_no.

--Scroll PgUp-PgDn-Page FI-Print page F2-Print all

APPENDIX C

TURBO PROLOG PROGRAM LISTING

There are two types of ~ i l es in t h i s sof tware:

i ) F i l e s w i th extensions " . t x t ' i i ) F i l e s wi th extension ' . p r o '

' . t x t " F i l e s

These F i l es contain t ex t (such as d e f i n i t i o n s , examples, e t c . ) which is to be d isp layed during the d i a l o g .

There are 13 '.txt' Files. These are listed below:

INSIGNIA TXT TITLE TXT SCREENIA TXT SCREENIB TXT SCREENIC TXT OPEN_SCR TXT SCREEN2A TXT SCREEN~B TXT SCREEN2C TXT KEYS_DEF TXT KEYS_EG TXT MVD_EG TXT PARTFD TXT

The l i s t i n g 0¢ these F i l es is embedded in the l i s t i n g of ' . p r o ' F i l e s . E a c h F i l e appears at the place where i t is ca l l ed by the TURBO-PROLOG cede,

'.pro' Files

These ¢ i l e s conta in the TURBO PROLOG code,

There are 6 '.pro' Files, These are listed below:

UTILITY.PRO Contains utility predicates For opera t ions , such as: union, sub t rac t i on , e tc .

standard l i s~ i n t e r s e c t i o n ,

SCREENS.PRO Contains predicates For performing standard screen Funct ions, such as: d i s p l a y of l i s t s , d i sp lay of attributes, etc.,

108

INPFILE,PRO

FDS.PRO

UI.PRO

Predicates in t h i s sec t ion l e t the user input the data- i tems he wants to s tore in the database to be designed,

Predicates in t h i s sec t ion conduct tha t part of the dialog which infers the functional dependencies From the user.

Main program For the user i n t e r f a c e . Master con t ro l o~ the d ia log resides w i th the predicates in t h i s F i l e .

NORM.PRO Predicates in this tile implement the no rma l i za t i on a lgo r i t hms .

STEPS FOR COMPILING THE PROGRAM:

i . Check t ha t a l l ~,pro" and ' , t x t ' ~ i l es as l i s t e d above are in the same d i r e c t o r y ,

2, Enter the TURBO-PROLOG environment (vers ion 1.00). Set the defaul~ d i r e c t o r i e s same as the d i r e c t o r y in which a l l your ' . p r o ' and ' , t x t ' ~ i l e s are s tored,

3. Load the F i l e : UI.PRO and compile using 'OBJ' op t ion (For details refer pp, 202 oF reference [ 2 & 3 .

4. Load the t i l e : NORM.PRO and compile using 'OBJ' op t ion .

5, Create a small ' . B A T ' t i l e named 'NORMEX,BAT' w i th Fo l lowing DOS commands:

echo oFF ui norm echo on

6. Quit the TURBO-PROLOG environment,

7. Ensure that TURBO-PROLOG libraries :

PROLOG.DBJ !NIT.OBJ

are in the same directory in which the ',OBJ' ~iles generated in step 3 & 4 are placed. Also the MS-DOS l i n k e r 'LINR,COM' and a batch t i l e PL!NK.BAT (which comes wi th TURBO-PROLOG) should be in the same d i r e c t o r y

8. Link the compiled modules using the commands:

piink ui plink normex

This should crea~e two Files : ~i,exe and norm,exe,

9. You can run the program by typ ing 'norme×' on the t e r m i n a l .

109

STEPS FOR MAKING CHANGES IN THE PROGRAM:

i . Depending on the nature o~ the change, and using the desc r i p t i on o~ ' . p r o ' ~ i l es given above, t race the ~ i l e in which the concerned pred icate is l i k e l y ~o appear.

~. Using the 'comments' given in ~hat ~ i l e (o~ step I ) t race the sec t ion o~ i n t e r e s t .

3. Trace the execut ion , s t a r t i n g ~rom the top l e v e l pred icate and reach the po in t o¢ your i n t e r e s t . Now you can make the changes you des i re .

/~ LISTING OF VARIOUS FILES . /

/ * Each ' . p ro ' ~i le has various sections, each section beginning ~/ /~ with predicate declarations. Following have been specified ~or ~/ /~ each o? section: #/

/~ Purpose ~ / /~ Top-level Predicate ~/ / * ~/ /~ Screen Numbers ~/

I* ~i

Purpose/Role o~ the section The predicate which controls the ~low o~ execution in that section Screen Numbers (o~ Appendix B) to which this section corresponds

110

/ * F I L E : U I . P R O * / /* ./ /* Main program for the user */ / * in~erface. Master cont ro l of * / / * the d ia log resides wi th the * / / * predicates in th i s f i l e , * / I. ./

code=B000 DOMAINS

list=symbol* {ile=output

DATABASE

entity_strong<symbol) attribute_es(symbol,symbol) all_files(list) nfiles(integer) entity_weak(symbol,symbol) attribute_ew(symbol,symbol,symbol> key_es{list,list) key_ew(list,list,list) ~d(list~list) ~dmin(list~list> m v d ( l i s ~ , l i s t ) fdj(list,list) pj(list~list) attributes(list) key(list) user(string) schema_nf3(list) schema bcnf<list) dep_preserved(string)

include include include include

" u ~ i l i t y ~ pro" ~screens.pro" "i~ds. pro" " i n p ~ i l e , pro"

111

/ ~ ~ ~ ~ ~ ~ ~ ~ * ~ * ~ ~ /

/~ PURPOSE: ~IVES THE USER AN OPTION TO REVISE ~/ /~ OLD DESIGN ~/

/~ TOP LEVEL PREDICATE: inputdata ~here~ ~/

/~ SCREEN NUMBERS: No corresponding screen numbers in ~/ /~ Appendix B ~/

PREDICATES

inputdata_wherel inputdata_where2 inputdata where save~ds

CLAUSES

save~ds:- clearwindow, w r i t e ( " > Saving the dialogue in ~ i l e : " ) , user(X), write(X),nl,nl, write("> Please wait .... "),nl,nl, save<X), w r i t e ( " > Saving Complete, " ) , n l , n l , w r i t e ( " Press a key to continue . . . . " ) , r e a d c h a r ( ) , clearwindow.

inputdata where:- makewindow(6,2,11,"DIALOG",14,2,10,70), w r i t e ( " > Give a name For the database you want to design: " ) , readln(FILE1), not(FILE1="")~ asserta<user(FILEl)>, clearwindow, w r i t e ( " > The data requirements you input during th i s d i a l o g " ) , n l , w r i t e ( " w i l l be stored. This w i l l a l low you to revise t h e " ) , n l , w r i t e ( " design on some l a t e r date, i~ the need a r i s e s . " ) , n l , n l , w r i t e ( " > Press any key to continue . . . . " ) , r e a d c h a r ( ) , removewindow, screen2, inputda~a, !.

inputdata_where:- removewindow, inputdata where.

112

inputdata where2:- wr i te ( "> Enter the old design name : ~), readln(X), consult(X), !, asserta(user(X)), removewindow, makewindow(4,0,O,"",7,1,3,3), makewindow(5,52,7,"ATTRIBUTES",O,34,14,45), makewindow(3,2,11,"DIALOG",i5,35,10,45), display ~iles, shi~twindow(3), nextstep=

inputdata_where2:- wr i te ( "> No such design name e x i s t s " ) , n l , n l ~ wr i te ( "> Do you want to input again (Y/N)? " ) , readln(ANS)~ upper_lower("Y",ANS),nl ,nl , !, inpu~data where,.

inputdata where2:- removewindow, inputdata where.

inputdata where1:- makewindow(6,2,11,"DIALOG",14,2,10,70), clearwindow, wr i te ( "> Do you wish to revise an old design readln(ANS), u p p e r l o w e r ( " Y " , A N S ) , n i , n l , inputdata_where~, !.

inputdata_whe~e1:- removewindow, inputdata where.

(Y/N) ? " ) ,

113

I . e l /~ PURPOSE: MASTER CONTROL OF THE DIALOG * /

/~ go e/

I~ 1-26 e l /~ . I

TOP LEVEL PREDICATE

SCREEN NUMBERS:

PREDICATES main_control go s t a r t

CLAUSES

main_con t ro l : - s tar t~ i n t r oduc t i on , inputdata_wherel , save#ds, keys, nex t s tep , ~ds, save( "p ipe" ) .

s t a r t : -

goal

a s s e r t a ( a l l _ ~ i l e s ( [ 3 ) ) , asse r ta (nF i l es (O) ) .

main con t ro l .

go.

114

/~ FILE : NORM.PRO ~/

/~ The predicates in this ~ i le ~/ /~ implement various normalization ~/ /~ algorithms, ~/

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

code=6000 DOMAINS

list=symbol~ Pile=output

DATABASE

entity_strong(symbol) a t t r i bu te es(symbol,symbol) a l l _ ~ i ! e s ( l i s t ) n~i les( integer) entityweak(symbol,symbol) attribute_ew(symbol,symbol,symbol) key_es ( l i s t , l i s t ) key e w ( l i s t , l i s t , l i s t ) ~ d < l i s t , l i s t ) f d m i n ( l i s t , l i s t ) mvd< l i s t , l i s t ) Cdj(list,list) pj(list,list) attributes(list) key(list) user(string) schema n~3(list) schema_bcnf<list) dep_preserved(string)

include " u t i l i t y . p r o " include "displays. pro"

115

I ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ I

/~ PURPOSE: TO FIND THE CLOSURE OF A SET ~/ /~ OF ATTRIBUTES ~/

/~ TOP LEVEL PREDICATE closure ~/

PREDICATES

c l o s u r e ( s t r i n g , l i s t , l i s t ) g e t F d ( s t r i n g , l i s t , l i s t )

CLAUSES

/~ c l o s u r e ( s t r i n g , l i s t i , l i s t 2 ) ~/ /~ Computes closure ( l i s t l ) o@ a t t r i b u t e s ( l i s t 2 ) /~ w . r . t . ~ .d 's denoted by s t r i n g ,

closure(S,A,APLUS):- get@d(S,LHS,RHS), subset(LHS,A), not (subset (RHS,A)), union(TEMP,A,RHS), closure(S,TEMP,APLUS), !.

closure(_,A,APLUS):- !,

APLUS=A.

/~ g e t f d ( l i s t i , l i s t 2 ) ~/ /~ Picks up one fd From the l i s t

getfd("F",LHS,RHS):- fd(LHS,RHS).

getfd("F",LHS,RHS):- Fdmin(LHS,RHS).

getfd("P",LHS,RHS):- pj(LHS,RHS).

of f , d ' s

116

/ * ./

I * PURPOSE: TO COMPUTE THE MINIMAL COVER OF * / / * A SET OF FUNCTIONAL DEPENDENCIES * / / * . / / * TOP LEVEL PREDICATE: minimum cover * /

/ * . / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

PREDICATES

reducefds reduce lhs l r e d u c e l h s 2 ( l i s t , l i s t , l i s t ) minimumcover

CLAUSES

/ * E l im ina tes redundant ~ .d ' s * /

reduce@ds:- w r i t e ( " > E l i m i n a t i n g Redundant F . D . ' s " ) , n l , ~ a i l .

reducefds~- ~d(LHS,RHS), no t (~d j (LHS,_ ) ) , retract(~d(LHS,RHS)), w r i t e ( " > Re t rac t ing FD: ",LHS~" -> " ,RHS),n l , closure("F",LHS,LHSPLUS), w r i t e ( " > Closure o£ LHS: ",LHSPLUS),nl, not (subset(RHS,LHSPLUS)), w r i t e ( " > Does not conta in RHS, Asser t ing a g a i n " ) , n l , asserta(~dmin(LHS,RHS)), ~ a i l .

reduce~ds:- r e t r a c t ( { d m i n ( X , Y ) ) , a s s e r t a ( f d ( X , Y ) ) , ~ a i l .

reduce@ds:- w r i t e< "> Redundant F.D's e l i m i n a t e d " ) , nl,nl.

/ * Minimise the number oF a t t r i b u t e s on Le~t Hand Side * /

reduce lhs1 : - ~d(LHS,RHS)~ w r i t e ( " > FD: ",LHS," -> " ,RHS),n l , ~educelhs~(LHS,RHS,REDLHS), not(eQuaI(LHS,REDLHS)), ~etract(~d(LHS,RHS)), asserta(~d(REDLHS,RHS)), ~ a i l .

117

reducelhs1:- !, wr i te ( "> LHS n l , n l .

minimised"),

reducelhs~(LHS,RHS,REDLHS):- member(ELEM,LHS), drop_elem(LHS,ELEM,LHSMI), closure("F",LHSMI,LHSMIPLUS), subset(RHS,LHSMIPLUS), !, reducelhs2(LHSMI,RHS,REDLHS).

reducelhs2(REDLHS,_,REDLHS).

minimum_cover:- reducelhsl, reduce#ds.

118

/ * PURPOSE: TO PROJECT A SET OF FD'S ON TO * / I * A SET OF ATTRIBUTES * / / * * /

/ * TOP LEVEL PREDICATE: p j l * / / * ~I I * . /

PREDICATES

pji(list) pj2(symbol)

CLAUSES

pj 1(_) :- re%rac~(pj (_~_)) {ail.

pj1(_):- ?d(X,Y), asser%a(pj(X,Y))~ #ail.

pjl(SET):- at%ributes(L}, member(E,L), not (member(E,SET)), pj2(E), Call.

pj I(_) .

pj~(E):- pj(LHSI,EE3)~ pj(LHS2,RHS2), member(E,LHS2), drop_elem(LHS2,E,TEMP), union(NEWLHS,TEMP,LHSI), asserta(pj(NEWLHS,RHS2)), #all.

pj2(E): - pj(LHS,RHS)~ member(E,LHS), retract(pj(LHS,RHS)), f a i l ,

p j2(E): - pj(LHS,RHS)~ member(E,RHS)~ retract(pj(LHS,RHS)), ~a i l .

pj2( ).

119

/4 PURPOSE: TO DETERMINE ALL THE KEYS OF A ~/ /~ RELATION ~/

/~ TOP LEVEL PREDICATE: t indal lkeys ~/

PREDICATES

CLAUSES

~ i n d k e y ( l i s t , l i s t ) ~indallkeys knownkey(list) ~indnewkey(list)

t indkey(_ ,_) : - retract(key(_>), t a i l .

~indkey(REL,KEY):- mvd(X,Y>, union(REL,X,Y), KEY=REL, asserta(key(KEY)), !.

findkey(REL,KEY):- reducelhs2(REL,REL,KEY), assertz(key(KEY)).

knownkey(K):- key(St, subset(K,S), !.

tindnewkey(K):- pj(LHS,RHS), minus(RHS,K,Z), union(S,LHS,Z), not (knownkey(S)>, asserta(key(S)), tindnewkey(S).

t i nda l l keys : - key(K>, tindnewkey(K), t a i l .

t inda l lkeys.

120

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

/~ PURPOSE: TO OBTAIN THE THIRD NORMAL FORM ~/ /~ USING BERNSTEIN'S ALGORITHM ~/

/~ TOP LEVEL PREDICATE: n~3 ~/

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

PREDICATES

combineFds makerel n£3 eiem conta inedins eqvkeys c o l l e c t a l l e q v ( l i s t , l i s t , l i s t ) col lectal leqv1(l ist , l ist , l ist) ; o l l e c t a l l e q v 2 ( l i s t , l i s t , l i s t ) a l r e a d y e x i s t s ( l i s t )

CLAUSES

combine£ds:- £d(LHSI,RHSI), w r i t e ( " > FD: " ,LHSI , " ~d(LHS2,RHS2)~ equaI(LHSI,LHS2), not(equal(RHSI,RHS~)), w r i t e ( " > FD: ",LHS2, " -> union(RHS,RHS1,RHS2), r e t r a c t ( F d ( L H S I , R H S l ) ) , r e t r a c t ( ~ d ( L H S 2 , R H S 2 ) ) , w r i t e ( " > Combining to w r i t e ( " > FD: ",LHS1, " asser ta( fd(LHSI,RHS)) , !, combine~ds.

=> " ,RHSI ) ,n l ,

" ,RHS2),n l ,

: " ) , n l , -> " , R H S ) , n l , n l ,

combineCdso

collectalleqv(LHS,A,R):- collectalleqv1(LHS,A,R1), collectalleqv2(LHS,RI,R).

121

colIectalIeqv2(LHS,A,R):- £d(LHS,RHS), union(ZI,LHS,RHS)~ union(R1,ZI,A)~ not(equal(R1,A)), !, collectalleqv(LHS,R1,R).

collectalleqv~(_,A,A).

collectalleqvl(LHS1,A,R):- ~dj(LHS1,LHS2), retract(~dj(LHSI,LHS2)), retract(~dj(LHS2~LHSq)), !, collectalleqv1(LHSI,A,R1), collectalleqv2(LHS2,R1,R).

collectalleqv1(_,A,A).

alreadye×ists(R):- schema_n~3(Z)~ equal(R,Z), !.

makerel | -

~dj(LHS1,LHS~), retract(~dj(LHSI,LHS2)), retract(?dj(LHS2,LHS1)), collectalleqv(LHSl,E3,R1), collectalleqv(LHS2,R1,R2), asserta(schema_n~3(R2)), #ail.

makerel:- ~d(LHS,_), collectalleqv2(LHS,[3,R), not (alreadyexists(R)), asserta(schema_n~3(R)), ?ai l .

makerel:- elem containedins, ?ai l .

makerel:- retract(schema_n?3(E3))~ ~ail.

makerel:- mvd(X,Y), union(Z,X,Y), asserta(schema_n~3(Z)), ~ail.

122

makerel.

elem_containedins:- schema_n~3(Zi), schema_n~3(Z2), subset(Z2,Z1), not (subset(ZI,Z2)), retract(schema nf3(Z2)), ~ail.

elem_containedins:- !.

eqvkeys:- fd(LHSi,_), #d(LHS2,_), not (equal (LHSI,LHS2)), closure("F",LHSi,LHSIP), closure("F",LHS2,LHS2P), subset(LHS2,LHSIP), subBet(LHSIP,LHS2P), not (~dj(LHSI,LHS2)), writelist_hz(LHS1)~ wri te(" and ") , writelist_hz(LHS2), write(" are equivalent keys."),nl, asserta(~dj(LHSI,LHS2)), asserta(#dj(LHS2,LHS1)), ?ail.

eqvkeys.

n~3:- consult("pipe"), #indall(X,attribute_es(_,X),L'|), {indall(Y,at%ribute_ew( .... Y),L~), union(L,LI,L2>, aseerta(attributes(L)), {all.

n~3:- write("> Finding minimum cover"),nl, minimum_cover, #all.

n£3:- write("> Finding equivalent keys"),nl, eqvkeys, write("> Finding cover ~or the second minimum_cover, {all.

n{3:- makerel, ~ail.

time")~nl,

123

n f 3 : -

nF3:-

nF3:-

a t t r i b u t e s ( L ) , Findkey(L,R), asserta(schema_n~3(R)), w r i t e ( " > Loss-less j o i n F a i l ,

guarant eed" ), n i ,

w r i t e ( " > E l im ina t ing elem_containedins, Fa i l ,

redundant r e l a t i o n s " ) , n l ,

w r i t e ( " > 3rd NF obta ined" ) , n l , w r i t e ( " > Press any key to continue readchar(_), !.

. . . . ") , n l ,

124

/ ~ PURPOSE: TO CHECK FOR THE PRESERVATION OF ~ / / ~ DEPENDENCIES ~ /

/ ~ TOP LEVEL PREDICATE: # d l o s ~ l ~ /

PREDICATES

~dlostl ~dlost2(lis~,list) isitlost(list,list,list)

CLAUSES

~dlost1:- wr i te ( "> Checking For dependency asser~a(dep_preserved("YES")), ~d(X,Y), ¢dlost2(X,Z)~ isitlost(X,Y,Z), ~ail.

preservation"),nl,

~dlost l .

Fdlost2(X,Z)~- schema bcnF(R), intersect(X,R,XlR), c l o s u r e ( " F " , X I R , X I R P L U S > , intersect(XIRPLUS,R,ADD), union(ZTEMP,ADD,X>, not (equal(ZTEMP,X)), !, Fdlost2(ZTEMP,Z).

?dlost2(X,X)~

isitlost(_,Y,Z):- subset(Y,Z>~ !.

i s i t l o s t ( X , Y , _ ) ~ - retract(dep_preserved(_)), asserta(dep_preserved("NO")), wr i te(X) , write( . . . . . >> " ) , write(Y),nl,

125

/~ PURPOSE: TO OBTAIN BOYCE-CODD NORMAL FORM ~/

/~ TOP LEVEL PREDICATE: bcn~top ~/

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

PREDICATES

bcn~top bcn~(l ist)

CLAUSES

bcn~(REL):- wr i te("> Finding Pro3ections"),NL, p j i ( R E L ) , ~indkey(REL, ), ~indallkeys, ~a i l .

bcn£ (REL) : - p j ( X , Y ) , closure("P",X,XPLUS), no t (subse t (REL ,XPLUS) ) , !, w r i t e ( " > BCNF v i o l a t e d , Decomposing the r e l a t i o n " ) , n l , union(Z,X,Y), asserta(schema_bcn~(Z)), wr i te("> Decomposed re la t ion : ") , w r i te l i s t_hz (Z) ,n l , minus(NEWREL,REL,Y), bcn~(NEWREL).

bcn£(REL):- wr i te("> Decomposed re la t ion: ") , wr i te l ist_hz(REL),nl , asserta(schema bcn£(REL)).

bcn£top:- schema_n£3(REL), wr i te("> Decomposing w r i t e l i s t hz(REL), bcn£(REL), £a i l .

into BCNF the re la t ion : ") ,

b c n F t o p : - F d l o s ¢ l , ! .

126

1 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ t

/~ PURPOSE: PRINTING OF OUTPUTS ~/

/~ TOP LEVEL PREDICATE: w r i t e r e l ~/

PREDICATES writerel(string) writerela(list) writekeys

CLAUSES

wri~ekeys~- write('KEYS~ ">~nl, ~ail.

writekeys:- key(K), writelist_in~ile(output,K), Cail~

writekeys:- n l , n l , n l o

wri~erela(X)~- pit(X), Findkey(X, )~ ~indallkeys, write("ATTRIBUTES IN THE RELATION:"),nl, w r i t e l i s t _ i n ~ i l e ( e u t p u t , X ) , n l , writekeys.

writerel('BCNF"):- schema_bcnF(R), writerela(R), Cail.

writere I("NFS"):- schema_nf3(R), writerela(R), ~ail.

writerel(_),

127

************************************************************************

I* . I / * PURPOSE: MASTER CONTROL OF NORMALIZATION * / I* .I / * TOP LEVEL PREDICATE: normal ize , / I* .I I* . / ************************************************************************

PREDICATES normal ize p r i n t_ou tpu t

CLAUSES

p r i n t _ o u t p u t : - w r i t e ( " > F ina l ~ i l i n g scheme w i l l be w r i t t e n to a ~ i l e -

'OUTPUT',") ,n l , w r i t e ( " which can be p r i n ted using 'TYPE' command") ,n l ,n l , w r i t e ( " > Press any key to cont inue . . . . " ) . r e a d c h a r ( ) . openwrite(output,"OUTPUT"), w r i t e d e v i c e ( o u t p u t ) , n l , n l , n l , ~ail.

print_output:- dep_preserved("NO"), write(" RELATION SCHEME nl,nl, writerel("NF3"),nl,nl,nl,nl, tail.

IN THIRD NORMAL FORM"),NL,NL,

print_output:- write(" RELATION SCHEME nl,nl, writerel("BCNF"),nl,nl, tail.

IN FOURTH NORMAL FORM" ), NL, NL,

print_output:- dep_preserved("NO"), write("Data Dependencies Lost in the Decomposition"),nl, tdlostl, tail.

print_output:- close~ile(output), writedevice(screen), ~ail.

p r i n t _ o u t p u t : - $ i l e _ s t r ( " O U T P U T " , B ) , w r i t e ( B ) , nl,nl, write("} Press any key readchar(_).

to continue . . . . " ) ,NL ,

128

normalize:- make~indow(i,78,7,'NORMALIZING",O,O,25,80), n~3, bcn~top, ~ d l o s t i , print_output.

goal normalize~

129

/ * . /

/ * FILE : SCREENS.PRO * / / * . / / * Predicates in ~his ~ i l e perform some s~andard screen * / / * ~unc~ions, such as, d i s p l a y i n g l i s ~ s , d i s p l a y i n g f i l e * / / * names, d i sp l ay i ng a~t r ibu~es, e~c. * / / * . /

/ ~ ~ ~ ~ . ~ ~ ~ ~ ~ . ~ ~ /

/~ PURPOSE: TO DISPLAY OPENING SCREENS AND ~/ /~ INTRODUCE THE USER TO THE ~/ /~ PRELIMINARIES OF DATABASE DESIGN ~/

/~ TOP LEVEL PREDICATE i n t r o d u c t i o n ~/

/~ SCREEN NUMBERS I -4 ~/

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

PREDICATES

opening_screen screenl screen~ z o o m ( i n t e g e r , i n t e g e r , i n t e g e r , i n t e g e r ) w a i t ( i n t e g e r ) i n s i g n i a i n t r o d u c t i o n

CLAUSES

/~ FILE: OPEN SCR,TXT ~/

I ~ # ~ ~ ~ ~ ~ ~ ~ I

He l lo !

We are here to ass i s t you in developing a

F i l i n g Scheme

For your database.

Press any key to cont inue . . . .

opening_screen:- makewindow(~,116,0,"",7,15,15,50), F i l e _ s t r ( " o p e n _ s c r . t x t " , A ) , w r i t e ( A ) , £ i e l d _ a t t r ( 6 , 1 7 , 1 3 , 7 9 ) , readchar(_), removewindow,

!30

/~ FILE : UTILITY.PRO * /

/ * The predicates in th is ~i les ~/ /~ perform standard l i s t operations ~/ /~ such as, union, in tersect ion,etc. ~/

predicates member(symbol~list) subset(list,list~ union(iist,list,list) minus(list,list,list) equal(list~list) drop elem(list,symbol,list) nth elemENT(integer,list,integer~symbol)

clauses

/~ membeF(symbol,list) ~/ /~ checks the membership o~ symbol in the l i s t ~/

Member(X~ZX~ 3). Member<X,[_~Tail3>:-

Member(X,Tail).

/~ subset(list1,1ist2) ~/ /~ Checks ~o see whether list4 is a subset o~ list~ ~/

subset(Z3~ >~- !.

subset(ZHEAD~TAILA3,B):- !, member(HEAD,B),subset(TAILA,B).

drop e lem( l i s t l , symbo l , l i s t2 ) ~/ subtracts symbol From l i s t4 to give l is~2

drop elem(EELEM~REDLHS3,ELEM,REDLHS):- !.

drop_elem(EA~LHS3,ELEM,[AIREDLHS3):- drop elem(LHS,ELEM,REDLHS).

/~ union(!is~i,list2,1ist3 ~/ /~ Returns union (list4) oF two sets (list2 and list3) ~/

union(A,A,Z3):-!. union(A,E3,A):-!. union(EHEADA~TAILU],EHEADAITAILA],B):-

member(HEADA,B),

drop elem(B,HEADA,B4), union(TAILU,TAILA,BI).

union<[HEADA~TAILU3,EHEADA~TAILA],B):- !,union(TAILU,TAILA,B).

131

/ * m i n u s ( l i s t l , l i s t 2 , 1 i s t 3 ) * / / * Subtracts l i s t 3 from l i s t 2 to give l i s t l * /

minus(SET,SET,C3):- !.

minus(SETDIFF,SETA,ZHEADB~TAILB3):- drop_elem(SETA,HEADB,TEMP), minus(SETDIFF,TEMP,TAILB).

/ * e q u a l ( l i s t l , l i s t 2 ) * / / * Checks equal i ty o~ two l i s t s l i s t l and l i s t~

equal<X,Y):- subset(X,Y>, subset(Y~X)~ !.

/* nth element( integer l , l is t , integer2,symbol) * / / * RetUrns the posit ion integer2, oF the

symbol in the l i s t counting Prom integer l * /

nth element(IN,EHEAD~ ],IN,HEAD):- !.

nth element(IN,C_~TAIL],N,X):- OUT=IN+I, nth_element(OUT,TAIL,N,X).

predicates i n t e r s e c t ( l i s t , l i s t , l i s t )

clauses

i n t e r s e c t ( [ ] , _ , [ ] ) . intersect(EHIT3,Y,EH~T2]):-

member(H,Y),!,intersect(T,Y,T2). in tersect ( [ ~T3,Y,Z):- intersect(T,Y,Z).

* /

132

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / . * I / * FILE : SCREENS.PRO * / I . . / I* Pred icates in t h i s f i l e perform some standard screen *I / * ~unct ions, such as, d i s p l a y i n g l i s t s , d i sp l ay i ng f i l e * / I * names, d i s p l a y i n g a t t r i b u t e s , e tc . * I I. *I

PURPOSE: TO DISPLAY OPENING SCREENS AND * I INTRODUCE THE USER TO THE * /

PRELIMINARIES OF DATABASE DESIGN

I* /* /* /. /. /* /. /*

TOP LEVEL PREDICATE

SCREEN NUMBERS

i n t r o d u c t i o n

1-4

*I *I *I *I *I

PREDICATES

opening_screen screenl screen2 zoom(integer,integer,integer,integer) wait(integer) insignia introduction

CLAUSES

/, */

I* FILE: OPEN_SCR.TXT */

I. *I I. *I

I . *I I. *I I. *I I. * I

/ . * /

Hello!

We are here to assist you in developing a

Filing Scheme

~or your database.

Press any key to continue ....

o p e n i n g s c r e e n : - makewindew(2.11&,O,"" .7,15,15,50) , f i l e _ s t r ( " o p e n _ s c r = t x t " , A ) . w r i t e ( A ) , ¢ield_attr(6,17,13,79), readchar(_), removewindow.

* /

133

I ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ I

I~ FILE: SCREENIA.TXT ~I

/~ An e f f i c i e n t database design assures that only minimal e ~ o r t and ~/ /~ time are expended in s to r ing , r e t r i e v i n g , rev is ing and manipulating ~/ /~ the information stored in the database. ~/

/~ This programme uses A r t i f i c i a l I n t e l l i g e n c e concepts to guide you ~/ /~ to achieve an e f f i c i e n t database design based on the r e l a t i o n a l ~/ /~ model of s to r ing the data, ~/

I~ Press any key to continue . . . . . . ~I

/ ~ ~ ~ w ~ ~ ~ w ~ w ~ ~ ~ ~ ~ /

/~ FILE: SCREENIB.TXT 4/

/~ In a database the d i f f e r e n t pieces of re la ted in@ormation are ~/ /4 grouped at one place. For example, a database may contain : ~/

/~ Rol l No Name Class Home Town ~/ I~ 8678 Kastur i M.Tech. Madras ~I /~ 8760 V i j ay B.Tech. Delhi ~/

/~ The i nd i v i dua l data items in a database (Rol l No, Name, e tc . ) 4/ /~ are ca l led a t t r i b u t e s . ~/

/~ Press any key to continue . . . . . . ~/

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

/~ FILE: SCREENIC.TXT ~/

/4 Soon, You w i l l be asked some questions regarding the a t t r i b u t e ~ ~/ /4 ( i . e . data items) that w i l l appear in your database. ~/

I~ You should answer these questions th ink ing as i~ you are bu i ld ing e l I~ ord inary paper ~ i les for s to r ing data. ~I

/~ Press any key to continue . . . . . . ~/

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

134

s c r e e n l ~ - m a k e ~ i n d o ~ ( t , 1 5 , t 5 , " ' , O , O , 2 5 , 8 0 ) , cu rso r (2 ,36 ) , w r i t e ( " e x c e p t " ) , c u r s o r ( O , 3 2 ) , w r i t e ( "PRELIMINARIES" ) , makewindow ( 2, 116,15, "" ,2 2,4,34) write(" Files in a computer database'),nl, write(" are similar to paper ~iles"), makewindow(3,116,15 .... ,2 44,4 35) w r i t e ( " t ha t data is s tored on magnet ic " ) , write(" media rather than on paper."), makewindow(5r2,15, " " , 8 , 2 , 1 6 , 7 6 ) , ~ indow_a t t r (2 ) , ?ile_str("screenla.txt",A), ~rite(A), readchar(_), clear~indow, ~ i l e _ s t r ( " s c r e e n l b . t x t " , B ) , w i n d o w _ a t t r ( 2 ) , w r i t e ( B ) , ? i e l d _ a t t r ( 4 , 1 , 7 0 , 1 4 ) , ~ i e l d _ a t t r ( 9 , 1 6 , 1 1 , 1 " 1 ) , readchar(_) , clearwindow, ~ i l e _ s t r ( " s c r e e n l c . t x t " , C ) , write(C), readchar(), removewindow, removewindow, removewindow, clearwindow, shi~t~indow(1), m a k e w i n d o w ( 2 , 9 0 , 1 0 , " A t t r i b u t e s " , l , ~ , 3 , 3 1 ) , clearwindow, write("data items to be stored").

/~ FILE: SCREEN2A,TXT ~/

/~ As you start the process o~ building ~/ /~ your database you may a l ready have a ~/ /~ good idea about the data ~ i l es you ~/ /~ would l i k e to have, ~/ /~ ~or example: ~ /

/~ For example, ?or a i nven to ry manage- ~/ /~ ment database, you might have : ~/

/~ - a master file o~ parts ~/ /~ - a master ~ile o~ vendors ~/

135

screen2:- makewindo~(3,74,2,"",4,~6~15,47), ~ i l e_s t r< "sc reen2a . tx~" ,A) , ~ r i t e ( A ) , ~ ie ld a t t r ( 3 , 2 3 , 1 1 , 7 9 ) , # ie ld a t t r ( 1 0 , 1 , 3 5 , 7 9 ) , # ie ld a t~ r (11 ,1 ,35 ,79) , # a i l .

screen~:- make~indow(6,~,~1,"DIALOG",19,£,5,70), # a i l .

screen2.

wa i t< t000 ) : - !.

~ a i t ( N ) : - NO=N+I,

~ait(NO>.

/~ FILE: SCREEN~A,TXT ~/

/4 A TURBO-PROLOG IMPLEMENTATION OF NORMALIZATION ~/ /~ ALGORITHMS IN RELATIONAL DATABASE DESIGN ~/

/ ~ C o p y r i g h t 4 / /4 Vinay K Chaudhri ~/ /~ Tapan P. Bagchi 4/

/4 4/ /4 INDUSTRIAL AND MANAGEMENT ENGINEERING PROGRMME ~/ /~ liT KANPUR UP, 20801~ ~/

136

zoom(_,_,X, )~- X>15, ~ile_str("gigle,gxt",A),

!.

zoom(STXI,STYI,HTi,WIDTH!):- removewindow, makewindow(1,11,0,"",STXl,STYi,HTi,WiDTHl), STXO=STXI-I, STYO=STYI-5, HTO=HTI+2, WIDTHO=WIDTHI+IO, wait(O), !, zoom(STXO,STYO,HTO,WIDTHO),

insignia:- £ile str("insigniao~xt",A), makewindow(2,12,0,"",O,O,25,80), write(A), makewindow(1,90,O,"",11,37,3,3), zoom(11,38,3,3),wait(-31999),wait(-31999), removewindow, r e m o v e w i n d o w , !=

introduction:- insignia, opening_screen, s c r e e n l .

137

/ w ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

/w PURPOSE: TO IMPLEMENT A POP UP MENU ~/

/~ TOP LEVEL PREDICATE menu ~ /

/~ SCREEN NUMBERS 14 ~/

DOMAINS ROW,COL,LEN = INTEGER ST=st r ing KEY = cr ; esc ; break ; tab ; btab ; del ; bdel ; ins ;

end ; home ; ftast(INTEGER) ; up ; down ; l e f t ; r i g h t ; c t r l l e ~ t ; c t r l r i g h t ; c t r l e n d ; c t r l home; pgup; pgdn; chr(CHAR) ; o therspec

PREDICATES readkey(REY) readkeyl(KEY,CHAR,INTEGER) readkey2(KEY,INTEGER)

CLAUSES

r e a d k e y ( K E Y ) : - r e a d c h a r ( T ) , c h a r i n t (T ,VAL ) , r eadkey I (KEY ,T ,VAL ) .

readkey1(KEY,_,O):-!,readchar(T),char int(T,VAL),readkey~(KEY,VAL). r e a d k e y i ( c r , _ , 1 3 ) ~ - ! . r e a d k e y l ( e s c , _ , ~ 7 ) : - ~ . r e a d k e y 1 ( c h r ( T ) , T , _ )

r e a d k e y 2 ( u p , 7 2 ) : - ! . r e a d k e y ~ ( d o w n , 8 0 ) : - l . readkey~(~tast (N) ,VAL): -VAL>58,VAL<70,N=VAL-SB,! . r e a d k e y ~ ( o t h e r s p e c , _ ) .

/~ menu(L ine ,Co l l um,Header ,L i s tO fCho ices ,Cho iceNr ) ~ / /~ The f o l l o w i n g keys can be used: ~/ /~ arrows up and down: s e l e c t choice ~/ /~ cr and FIO: a c t i v a t e choice ~/ /~ Esc: abo r t ~ /

PREDICATES ma×len(LIST~INTEGER~INTEGER) /~ Find l eng th of the l onges t s t r i n g ~ / l i s t len(L IST, INTEGER) /~ Find the l eng th o~ a l i s t ~ / writel ist<INTEGER,INTEGER,LIST> /~ Used by the menu p r e d i c a t e ~ / menu(ROW,COL,STRING,LIST,INTEGER) menuI(ROW,LIST,INTESER,INTEGER,INTEGER) menu~(ROW,LIST,INTEGER,INTEGER,INTEGER,KEy)

138

clauses

max!en(EH~TD,MAX,MAX1):- ST=H, sir Ien(ST,LEN), ~EN>MAX,!, maxlen(T,LEN,MAX1).

maxlen(E_)T],MAX,MAX1):-maxlen(T,MAX,MAX'I).

maxlen(E],LEN,LEN)=

listlen(E]~O).

listlen(E_IT],N):- listlen(T,X), N=X+I.

wriSelist(_~_,E])°

wri~elist(LENE,LONGEST_CHOICE,EHIT]):-~ield_str(LINE,O,LONGEST_CHOICE,H), LINEI=LINE+I,writelist(LINEI,LONGEST_CHOICE,T).

menu(LINE,KOL, TXT,LIST,ACTUAL_CHOICE):- maxlen<LIST,O,LONGEST_CHOICE), Iistlen<LIST,LEN),NCHOICE=LEN,LEN>O, HHI=NCHOICE+2,HH~=LONGEST_CHOICE+2, makewindow(3,7,7,TXT,LINE,KOL,HH1,HH~), HH3=LONGEST_CHOICE, writelist(O,HH3,LIST>,cursor(O,O), menul(O,LIST,NCHOICE,LONGEST_CHOICE,CHOICE), ACTUAL_CHOICE=I+CHOICE, removewindow.

menu'i(LINE,LIST,NCHOICE,LONGEST_CHOICE,CHOICE):- @ield at~r(LiNE,O,LONGEST_CHOICE,11~), cursor(LINE,O), readkey(KEY), menu2(LINE,LIST,NCHOICE,LONGEST_CHOICE,CHOICE,KEY).

menu~(_~ ~_,_~-l,esc):-~=

menu2(LINE,_,_,_,CHDICE,~ast(IO)):-~,CHOICE=LINE.

menu2(LINE ....... CHOiCE,cr):-!,CHOICE=LINE.

menu~(LINE,LIST,NCHOICE,LONGEST_CHOICE,CHOICE,up):- LINE>O,~, ~ield attr(LINE,O,LONGEST_CHOICE,7), LINEI=LINE-I, menuI(LINEI,LIST,NCHOICE,LONGEST_CHOICE,CHOICE).

menu~(LINE,LIST,NCHOiCE,LONGEST_CHOICE,CHOICE,down):- LINE<NCHOICE-I,!, ¢ield_attr(LINE,O,LQNGEST_CHOICE,7), LINEI=LINE+I, menuI(LINEI,LIST,NCHOICE,LONGEST_CHOICErCHOICE).

menu2(LINE,LiST,NCHOiCE,LONGEST CHOICE,CHOICE,_):- menuI(LINE,LIST,NCHOICE,LONGEST CHOICE,CHOICE).

139

/ * PURPOSE: TO DISPLAY ATTRIBUTES, F ILES AND * / / * KEYS * /

/ * TOP LEVEL PREDICATES display_~i les, d isp lay_at t r ibs , */~ /* display_keys * / /. */

PREDICATES

dispIay_Iist(LIST,INTEGER,ROW,INTEGER,STRING,INTEGER,INTEGER) move cursor<INTEGER,INTEGER,INTEGER,INTEGER) disp_list col(INTEGER,INTEGER,LIST) writelist hz(list) display attribs(symbol) display attribs ew(symbol,symbol) display_~iles display_keys<symbol) display keys_es1(symbol) display keys es~(symbol) display keys_ew1(symbol,symbol) display keys ew2(symbol,symbol) writelist_in~ile(File,list) ~indall a~t(symbol,symbol,list)

CLAUSES

~ inda l l_a t t (F ILE," " ,ALL) : - Findal l (P,attr ibute_es(FILE,P),ALL), !.

~indall_att(FILE,GROUP,ALL):- ~indall(P,attribute_ew(FILE,GROUP,P),ALL).

display_Iist(LIST,WINDO_NO,LINE,COLUMN,HEADER,SCR_ATTRIB,FRAME_ATTRIB): LONGEST CHOICE=IO, listlen(LIST,LEN),NCHOICE=LEN,LEN>O,

HHI=NCHOICE+2,HH2=LONGEST_CHOICE+2, HH3=LONGEST_CHOICE, shi~twindow<WINDO_NO), removewindow, makewindow(WINDO_NO,SCR_ATTRIB,FRAME_ATTRIB,HEADER,

LINE,COLUMN,HHI,HH2), writelist(O,HH3,LIST).

display_list(_,WINDO_NO . . . . . . . . , _ ) : - shiFtwindow(WINDO_NO), removewindow, makewindow(4,0,O,"",7,1,3,3).

m o v e _ c u r s o r ( l O , 3 3 . . . . _ ) : - c u r s o r ( 1 1 , 3 2 ) , w r i t e ( " S P A C E F U L L " ) , ~ i e l d _ a t t r ( 1 1 , 3 2 , 1 0 , b 7 ) , shi~twindow(3), !,

140

move_cursor(~,X,O,Y):- Y=X+~I, cursor(O,Y)~

move_cursor(×~Y,P,Y)~- P = X+i, cursor(P,Y), !o

disp list_col< ,_~E]):- !.

disp_Iist_coI(STY,STX,EHEAD[TAIL]):- write(HEAD), move_cursor(STY,STX,STYO,STXO), !, disp_list_col(STYO,STXO,TAIL).

disp_!is% col{ ..... )o

write!ist_hz(E]):- cursor(X,Y>, P=Y-I, cursor(X,P), write(".">,

!.

writelis~_hz(EH[T]):- write(H), write("~"), !, ~ritelis~_hz(T).

display_¢iles:- shi~twindow(3), retract(all ~iles(_)), ¢indall(X,entity_strong(X),FILE_LIST), asser~a(all_files(FILE_LIST)), not(equal(FILE_LIST,El)), display_Iist(FILE_LZST,4,8,1,"FILES",74,15), shi~twindow(3), [.

display_{iles~

display_attribs_ew~ ~GROUP}:- shi~window(5), clearwindow, not (GROUP= .... ), write{GROUP), ~ield_attr(O,O,10,79),nl, Call.

141

display_attribs ew(FILE,GROUP):- Findall_att(FILE,GROUP,ATTRIB_LIST), c u r s o r ( P , G ) , disp_Iist_coI(P,G,ATTRIB_LIST), shiFtwindow(3).

display_atCribs(FILE):- all_Files(LIST), nth_element(O,LIST,N,FILE), shiFtwindow(4), Field attr(N,O,10,75), Fai l .

display at tr ibs(FILE):- shiftwindow(5), removewindow, concat("ATTRIBUTES IN FILE: ",FILE,X), makewindow(5,52,11,X,O,34,14,45), clearwindow, ~ai l ,

display_attribs(FILE~):- entity_weak(FILEI,EW), cursor(M,N), w r i t e ( E W ) , F i e l d _ a C t r ( M , N , l O , 7 9 ) , move c u r s o r ( M , N , P , G ) , F i n d a l l ( X , a t t r i b u t e _ e w ( F I L E 1 , E W , X ) , A T T R I B _ L I S T ) , disp_list_col(P,G,ATTRIB_LIST), c u r s o r ( X , Y ) , move c u r s o r ( X , Y , _ , ) , Fail.

display attribs<FILE1):- ~indal l(X,attr ibute es(FILEI,X),REST), c u r s o r ( P , G ) , d i s p _ l i s t _ c o l ( P , G , R E S T ) , s h i F t w i n d o w ( 3 ) , Fai l .

d isplay_attr ibs(_):- !.

d i s p l a y k e y s ( ) : - shiFtwindow(7), clearwindow, Fail.

display keys(FILE1):- entity_weak(FILEI,X), display_keys_ewi(FILEI,X), Fai l .

display_keys(FILE~):- display keys_es1(FILE1), Fai l .

d i s p l a y k e y s ( ) : - shiFtwindow(3).

142

display_keys_ewl(FILEI,X):- key_ew(EFILE1],EX], ), cursor(P,G), w r i ~ e ( " G r o u p : " ) , wri%e(X),nl, ~ield_attr(P,G,18,26), !, display_keys ew~(FILEI,X).

display_keys ewi(_,_),

display keys ew2(FILEI,X):- Eey_e~(CFILEI],CX],KEYI), writelist_hz(KEY1), ~ail.

display_keys_ew2(_,_).

display keys_es1(FILEl):- key_es(CFILE13,_), cursor(P,G), write("FILE= "), write(FILE1),nl, f i e l d a t t r < P , G , 1 8 , ~ 6 ) , ! , display_keys_es~(FILE1).

display_keys esl(_),

display keys_es2(FILE1):- key_es(EFILE1],KEY1), writelist_hz(KEYi), £ail,

display keys_es2(_)

writelis~_in~ile(FILE,E]):- ~ilepos(FILE,-2,1), write("."),nl, !.

writelist_in~ile(FILE,EH)T]):- write(H), write(", "), !, writelist_in~ile(FILE,T).

143

/ * FILE : INPFILE.PRO * /

/ * Pred icates in ~his ~ i l e le~ ~/ / * the user ~he user inpu~ the * / / * d a ~ a - i ~ e m s he w i s h e s ~o s ~ e r e i n * / / ~ t h e d a t a b a s e ~o be d e s i g n e d * /

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

/~ PURPOSE: TO TRUNCATE THE ATTRIBUTE NAMES ~/ /~ TO A LENGTH OF 10 CHARACTERS ~/

/~ TOP LEVEL PREDICATE chop_name ~/

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

PREDICATES

chop_name(symbol,symbol)

CLAUSES

chop name(A,A):- s t r _ l e n ( A , L ) , L < I I , !.

chop_name(A,B):- £ron%str('10,A,B,_).

144

I ~ ~ ~ ~ ~ ~ . ~ ~ ~ . ~ ~ ~ I

/~ PURPOSE: TO ACCEPT THE INPUT OF WEAK ENTITIES ~/

/~ explaingroup ~/

I * 7-10 ~/

/ . ~ ~ ~ ~ ~ ~ ~ @ ~ ~ ~ ~ /

TOP LEVEL PREDICATE

SCREEN NUMBERS

PREDICATES

explaingroup(symbol) ask groups_es(symbol) ask groups es~(symbol) ask_attr ib_ew(symbol,symbol) ask a t t r i b_e~ (symbo l , symbo l ) checkdup l i ca tegroup(symbo l ,symbo l ) check n u l l group<symbol ,symbol , l is t ) check name_at~rib ewe(symbol,symbol,symbol) edi tkeys ew(symbol,symbol)

CLAUSES

I ~ ~ ~ ~ ~ ~ ~ ~ I

I~ FILE: SCREEN2B.TXT ~I

/~ In a STUDENT daCabase ~iCh ~/ /~ a t t r i b u t e s : ~I

i~ Name, Rollno~ Class, S t ree t , ~I /~ C i t y , Zip ~/

/~ ~e might have the go l lo~ ing ~/ I * l o g i c a l groups: * I

I~ GROUP 1: Name~ Rol lno, Class ~I i~ GROUP 2: S~reet, C i t y , Zip ~/

145

/ ~ ~ . ~ ~ ~ ~ ~ ~ /

/~ FILE: SCREEN~C.TXT ~/

/~ I~ you can now 'group' the above ~/ /~ attributes in some logical way, ~/ /~ %ha% would reduce the number o~ ~/ /~ questions you will need %o ~/ /~ answer in this dialog ~/ /~ (see example) ~/

/~ Press any key %o continue .,. ~/

explaingroup(FILE1):- clearwindow, ~ile str("screen2c.tx%",C), write(C), makewindow(7,26y7,"EXAMPLE OF GROUPS",8,0,16,35), ~ile_str("screenab.t×t",A), write(A), readchar(_), removewindow, shi~twindow(3), clearwindow, ask_groups_es(FILE1).

ask_groups_es(FILE1):- d isp lay_at t r ibs(FILE1) ,n l , clearwindow, not (FILEt=""), write("> In File: "), write(FILEt), ~ield_attr(0,15,~5,11), nl,£ail.

ask g r o u p s _ e s ( F I L E 1 ) : - w r i t e ( " > Can you see any w r i t e ( " g r o u p s ( Y / N ) ? " ) , readln(ANS), u p p e r l o w e r ( " Y " , A N S ) , a s k _ g r o u p s _ e s l ( F I L E 1 ) .

such a t t r i bu te " ) , n l ,

ask_groups_es().

ask._groups es4(FILE1):- wr i te( "> Please type the group name " ) , n l , wr i te ( "> " ) , readln(NANEU), not(NAMEU="")~ upper lower(NAHEU,NAMEL), chop_name(NAHEL,NAME), check duplicate group(FILEI,NAME), ~a i l .

146

ask_groups_esl(FILEl):- write("> Any more groups readln(ANS), u p p e r _ l o w e r ( " Y " , A N S ) , ! , a s k _ g r o u p s _ e s l ( F I L E 1 ) .

(Y /N)? " ) ,

ask_groups_esl().

check duplicate_greup(FILEI,NAME):- e n t i t y w e a k ( F l L E l , X ) , X=NAME, wri te("> Duplicate names not al lowed"),nl , !, ask groups_es1(FILEl).

check_duplicate group(FILE1,NAME):- asserta(entity_weak(FILEI,NAME)), ask_attrib_ew(FILEI,NAME).

e d i t k e y s _ e w ( F I L E t , N A M E ) : - key_es( , )~ !, clearwindow, write("> For file : "), write<FILE1),nl, ~ield attr(O,15,25,11), cursor(PP, )~ w r i t e ( " > For g roup : " ) , write(NAME), ~ield_attr(PP,15,~5,14),nl, ask_keysl(FiLEI,NAME), clearwindow~

editkeys_ew(_,_).

ask_attr ib ew(FILE1,GROUP):- clearwindow, cursor(R,_), w r i t e ( " > For Group : " ) , write(GROUP),nl, ~ield_attr(R,15,~5,14), wri te("> Enter one a t t r ibu te per l ine w r i t e ( " When done, press Return"),nl , a s k _ a t t r i b _ e w l ( F I L E t , G R O U P ) , Cail.

. . . " ) , n l ~

ask_attr ib ew(FILEI,GROUP):- wr i te("> Any more at t r ibutes (Y/N)? readln(ANS), ~pper_lower("Y",ANS), !, ask attrib_ew(FZLEI,GROUP).

ask_art r ib ew(FILEI,GROUP):- findaiI<X~attribute_ew(FILE1,GROUP,X),ATT_LIST), check nul l group(FILEI~GROUP,ATT_LIST), display_attr ibs(FILE1), editkeys_ew(FILE1,GROUP).

147

ask a t t r i b ewl(FILEI,GROUP):- display at t r ibs(FILE1), wr i te( "> ") , readln(NAMEU)~ not (NAMEU=""), upper_Iower(NAMEU,NAMEL), chop_name(NAMEL,NAME), check_name_attrib_ew1(FILEI,GROUP,NAME), !, ask_attrib_ew1(FILEI,GROUP).

ask_attr ib ewl(_,_).

check name_attrib_ew1(FILEI,GROUP,NAME):- retract(attr ibute_es(FILEI,NAME)), assertz(attribute_ew(FILEI,GROUP,NAME)), !.

check_name_attrib ewI(FILEI,GROUP,NAME):- attribute_ew(FILEl,_,NAME), assertz(attribute_ew(FILEI,GROUP,NAME)), !.

check_name_attrib_ew1( . . . . . ) : - wr i te ( "> Ondeclared/Misspelt a t t r i b u t e " ) , n l , wr i te ( " Please check and input a g a i n " ) , n l , n l .

check_null_group(FILEI,GROUP,E]):- wr i te( "> Empty groups not accepted") ,n l ,n l , wr i te ( "> Do you want to keep th is group (Y/N)? readln(ANS), u p p e r _ l o w e r ( " Y " , A N S ) , !, ask a t t r i b_ew(F ILE1 ,GROUP) ,

check_null_group(FILEI,GROUP,Z])=- retract(entity_weak(FILEI,GROUP)), !.

check_null_group( . . . . . ),

")t

148

/4 PURPOSE: TO ACCEPT THE INPUT OF STRONG ENTITIES #/ /4 4/ /~ TOP LEVEL PREDICATE ask_tilenames2 ~/

PREDICATES

a s k _ t i l e namesl ask_tile_names~ check_nu l l_ f i l e l ( symbo l ) check_null t i l e 2 ( s y m b o l , l i s t ) check_dupl icate_~i le(symbol) ask_attribs_esl ask attribs_es2<symbol) check_dupl icate_at t r ib_es(symbol ,symbol) editkeys_es(symbol)

CLAUSES

ask_a~tr ibs_es1:- ent i~y_streng(FILE1), d i s p l a y _ t i l e s , clearwindow, w r i t e ( " > Now For t i l e : " ) , w r i t e ( F I L E 1 ) , n l , ¢ i e ld a t t r (O ,15 ,25 ,11 ) , w r i t e ( " Enter one a t t r i b u t e per l i ne . . . " ) , n l , w r i t e ( " When done, press Re tu rn " ) , n l , makewindow(5,52~7,"ATTRIBUTES",O,34,14,45), display_tiles, display_attribs(FILE1), shit twindow(3)~ ask a t t r ibs_es2(FILE1) , Ca l l .

ask_attribs_esl.

ask_attribs es2(FILE1):- write("> "), readln(AU), not (AU=""), upper_lower<AU,AL), chop_name(AL,A), check_duplicate_attrib_es(FILEI,A), display_attribs(FILE1), !, ask_attribs es2<FILE1).

ask_art r ibs_es2(FILE'1 ) :- write<"> Any more attributes (Y/N>? "), readln (ANS), upper lower<"Y",ANS), w r i t e ( " Enter one a t t r i b u t e per l i ne . . . " ) , n l , w r i t e ( " When done, press R e t u r n " ) , n l , !, ask a t t r i b s es~(FILEI>.

149

ask a t t r i bs es2(FILEI):- check null_~ile1(FILE1), !, explaingroup(FILEl), editkeys_es(FILE1).

ask_attribs_es2(_).

check_duplicate_attrib_es(AFILE,NAME):- attribute_es(AFILE,X), X=NAME, wri te("> Duplicate names not a l lowed") ,n l , wr i te ( " Give some other name"),nl, !.

check_duplicate_attrib es(AFILE,NAME):- attribute_ew(AFILE,_,Z), Z=NAME, wri te("> Duplicate names not a l lowed") ,n l , wr i te ( " Give some other name"),nl, !.

check dupl icate_at t r ib es(AFILE,ATTRIB):- assertz(attribute_es(AFILE,ATTRIB)).

check nu l l_ f i le1(F ILE1) : - #indal l (X,attr ibute_es(FILEI,X),L2), f indal l (Y,at t r ibute_ew(FILE1,_,Y),L l ) , union(L,LI,L~), shi~twindow(3), check nul l_~i le2(FILEI ,L) .

check n u l i _ f i l e 2 ( F I L E l , [ ] ) : - wr i te("> You should give at least one a t t r i bu te " ) , n l , n l , wr i te("> Do you want to give at t r ibutes (Y/N)? ") , readln(ANS), upper lower("Y",ANS), wr i te ( " Enter one a t t r ibu te per l ine . . . " ) , n l , wr i te ( " When done, press Return " ) , n l , !, ask a t t r i bs es2(FILEI), f a i l .

check_nu l l _ f i l e2 ( " " , [ ] ) : - !, Fai l .

check nu l l f i l e 2 ( F I L E l , [ ] ) : - retract(ent i ty_strong(FILEt)) , display f i l e s , !, f a i l .

check nu l l_ f i le~(FILE1,_) : - display attr ibs(FILE1), shiftwindow(3).

150

ask_~ile_names1:- clearwindow~ w r i t e ( " > Enter below names of y o u r data ~ i l e s , " ) , n l , w r i t e ( " one per l i ne . . . " > , n l , w r i t e ( " When done, press R e t u r n " ) , n l , ask_~ile_names~.

ask_~ile_names2:- write("> "), readln(NAMEU), not (NAMEU= .... )~ upper_Iower(NAMEU,NAMEL), chop name(NAMEL,NAME), check_duplicate_file(NAME), !, ask_~ile_names2.

ask_?ile_names2:- write("> Any more files (Y/N)? "), readln(ANS>, upper_lower("Y",ANS), clearwindow, write("> Enter below names of your data files,"),nl, w r i t e ( " one per line . . . " ) , n l , write(" When done, press Re tu rn " ) , n l , !, ask_~ile_names2.

ask_~ile_names2.

c h e c k _ d u p l i c a t e _ f i l e ( F I L E i ) : - en t i t y_s t rong (X ) , X=FILEI,nl, w r i t e ( " > Dupl icate names not a l l o w e d " ) , n l , n l , w r i t e ( " > Press any key to continue . . . " ) , n l , readchar(_), !, ~ail.

c h e c k _ d u p l i c a t e f i l e ( T ) : - n~ i l es (X ) , Y = X+i, not (Y>i5) , a s s e r t z ( e n t i t y _ s t r o n g ( T ) ) , d i sp iay_~ i l es , r e t r a c t ( n ~ i l e s ( _ > ) , asserta(n~iies(Y)), !.

check_duplicate_{ile(_):- write("> Max. No of ~iles(15) exceeded"),nl, nl, write("> Press any key to continue ... "), readchar(_), !, ~ail.

editkeys es(FILE):- keyes(_,_), !, clearwindow, write("> Now For ~ile: "), write(FlLE),nl, Field_attr(0,15,25,14), ask_keys1(FILE~"").

editkeys es(_).

152

* * * * * * * * * * * * * * * * * * * * * * * * / * EDITOR ~/ * * * * * * * * * * * * * * * * * * * * * * * *

/ ~ PURPOSE: TO ALLOW THE USER TO CHANGE THE INPUTS ~ / / ~ HE HAS MADE ONCE ~ /

I~ ne×t s~ep ~I

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

TOP LEVEL PREDICATE

SCREEN NUMBERS

/ ~ ~ ~ ~ / / ~ SUB-SECTIONS OF EDITOR ~I f ~ ~ ~ ~ 1

/~ PURPOSE: EDITING OF FILES ~/

/~ TOP LEVEL PREDICATE edi t_#i les ~/

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ * ~ ~ /

PREDICATES

edi~_~iles edi t ~iles'1(integer) dele~e~ile1(symbol) delete~ile2(symbol) rename~ilel rename~ile2(symbol,symbol>

CLAUSES

edit ?iles:- clearwindow, write("> "), menu( 16,40, "EDIT FILES",

E"ADD A FILE", "DELETE A FILE", "RENAME A FILE", " Q U I T " 3 ,

CHOICE) , edit #ilesI(CHOICE),

edit_?iles1(O):= !.

153

ed i t _~ i l es1 (1 ) : - clearwindow, wr i te ( "> Input ~ i le name to add " ) , n l , wr i te ( "> " ) , readln(NAMEU), not (NAMEU= .... ), upper_lower(NAMEU,NAMEL), chop_name(NAMEL,NAME), check duplicate_file(NAME), entity_strong(NAME), w r i t e ( " Enter one a t t r i b u t e per l ine . . . " ) , n l , w r i t e ( " When done, press Return") ,n l , ask_attribs_es2(NAME).

ed i t_~ i lesJ(1) .

edit_¢iles1(~):- clearwindow, write("> Give the file name to delete"),nl, write("> "), readln(NAMEU), upper_Iower(NAMEU,NAME), not (NAME="")~ !, clearwindow, wr i te ( "> Deleting F i l e : " ) , write(NAME),nl,nl, write("> ~ CAUTION ~"),nl,nl, w r i t e ( " On delet ing the ~ i le a l l other r e l a t e d " ) , n l , w r i t e ( " information ( a t t r i bu tes , groups, keys)">,nl , w r i t e ( " w i l l also be 1 o s t " ) , n l , n l , w r i te ( "> Proceed with delete (Y/N)?"), readln(ANS), upper_lower("Y" ,ANS), d e l e t e £ i l e l ( N A M E ) .

e d i t _ ~ i l e s l ( 2 ) : - !,

ed i t_~ i l es1(3):- clearwindow, rename~ilel.

e d i t _ ~ i l e s l ( _ ) .

de le te~ i le1 (A) : - r e t r a c t ( e n t i t y s t r o n g ( A ) ) , !, delete~i le2(A).

de l e te~ i l e l ( >:- wr i te ( "> No such ~ i l e " ) , n l , n l , w r i te ( "> Press any key to continue . . . " ) , readchar ( ) , !.

154

de le te f i l e2 (A)~- retract(ent i ty_weak(A, ) ) , f a i l .

deletefile2(A):- r e t r a c t ( a t t r i b u t e es(A,_)), fail.

deletefile2(A):- retract(attribute ew(A,_,_)), fail.

de le te f i le2(A):- retract(key_es([A],_)), fail~

deletefile2( ):- display_files,

renamefi le1:- clearwindow, wr i te ( "> Give the name of f i l e write("> " ) , readln(NAMEU), upper_lower(NAMEU,NAME), entity_strong(NAME), !, wr i te ( "> Give the new name"),nl, w r i te ( "> " ) , readln(NAMEU1), upper_Iower(NAMEUI,NAMELI), chop_name(NAMELI,NAMEI), renamefile~(NAME,NAMEi).

to rename") ,nl,

renamefile1:- write("> No such file exists"),nl,nl, wr i te ( "> Press any key to continue . . , " ) , readchar(_).

renamefile2(A,B):- retract(entity_strong(A)), asserta(entity_strong(B)), fail.

renamefile~(A,B):- retract(entity_weak(A,X)), asserta(enti ty_weak(B,X)), fail.

renamefi le~(A,B):- re t rac t (a t t r i bu te_es (A ,X ) ) , asserta(attribute_es(B,X)), fail,

renamefile2(A,B):- re t rac t (a t t r ibu te_ew(A,X,Y) ) , asserta(at t r ibute_ew(B,X,Y)) , f a i l .

155

rename~ile2(A,B):- retract(key es([A],X)), asserta(key es([B],X)), ¢ai l .

rename~ile~(_, ) : - display_~iles.

156

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

/~ PURPOSE: EDITING OF ATTRIBUTES ~/

/~ TOP LEVEL PREDICATE e d i t a t t r ib_menu ~/

PREDICATES conf irm e d i t _ a t t r i b 1 ( s y m b o l ) edit attrib menu edit~attribTinteger) delete_attrib_file1(symbol,symbol) delete attrib_file2(symbol,symbol) delete_attrib_file3(symbol,symbol) delete_attrib_file4(symbol,symbol) delete_attrib_file5(symbol) delete_attrib_group1(symbol,symbol) delete_attrib_group~(symbol,symbol,symbol) delete_attrib_group3(symbol,symbol,symbol) delete_attrib_group4(symbol,symbol,symbol) delete_attrib_group5(symbol,eymbol) edit_attrib_groupl(symbol,symbol)

CLAUSES

con f i rm : - w r i t e ( " > *~ CAUTION * * " ) , n l , n l , w r i t e ( " > A l l o ther r e l i e d i n fo rmat ion w i l l " ) , w r i t e ( " a lso be l os t w i th d e l e t e " ) , n l , n l , w r i t e ( " > Proceed w i th de le te Y/N? " ) , readln(ANS), upper IoweF("Y",ANS), !,

con f i rm : - f a i l .

e d i t _ a t t r i b i ( F I L E 1 ) ~ - clearwindow, w r i t e ( " > Please give the f i l e name whose" ) ,n l , w r i t e ( " a t t r i b u t e s you want to e d i t " ) , n l , w r i t e ( " > " ) , readln(FILEU), upper Iower(FILEU,FILEI), entitystrong(FILE'I), display attribs(FILE1), !.

ed i t a t t r i b 1 ( _ ) : - w r i t e ( " > No such f i l e " ) , n l , n l , w r i t e ( " > Press any key to cont inue . . . " ) , readchar(_>, f a i l .

157

edit_attrib_groupl(FILEI,GROUP):- wr i te("> Input the group name wri te("> ") , readln(GROUPU), upper_lower(GROUPU,GROUP), entity_weak(FILEI,GROUP), !.

of i n t e r e s t " ) , n l ,

edi t_at t r ib_groupl(_, ) : - wr i te("> No such group") ,n l ,n l , wr i te("> Press any key to continue . . . " ) , readchar(_), f a i l .

delete_attrib_group1(FILEI,GROUP):- clearwindow, wri te("> Give the a t t r ibu te to de le te" ) ,n l , wr i te("> ") , readln(NAMEU), upper_lower(NAMEU,NAME), attribute_ew(FILEI,GROUP,NAME), !, de le te_at t r ib group2(FILEI,GROUP,NAME).

delete_attr ib_group1(_,_):- wr i te("> No such a t t r i b u t e " ) , n l , n l , wr i te("> Press any key to continue readchar(_).

. . . " ) , n l ,

delete_attrib_group2(FILEI,GROUP,NAME):- clearwindow, wri te("> Deleting a t t r i bu te : ") , write(NAME),nl,nl, confirm, delete_at t r ib group3(FILEI,GROUP,NAME), !.

delete attrib_group2( . . . . . ).

delete attrib_group3(FILEq,GROUP,NAME):- retract(attribute_ew(FILEq,GROUP,NAME)), display_attr ibs(FILE1), findall(X,attribute_ew(FILEI,GROUP,X),L), check_null group(FILEI,GROUP,L), entity_weak(FILEI,GROUP), delete a t t r i b group4(FILEI,GROUP,NAME), !.

delete attrib_group3(FILEI,GROUP, ) : - display_attr ibs(FILEq), retract(key ew([FILEI3,[GROUP3, )), f a i l .

delete attrib_group3(FILE1 . . . . ) : - display_keys(FILEt), check nul l f i l e t (F ILE1) , !.

delete a t t r i b group3( . . . . . ).

158

dele~e_attrib group4(FILE1,GROUP,NAME)~- key_ew(EF!LEI3,EGROUP3,X), member(NAME,X), re t ract (key_ew(EFILEl3,EGROUP3,X)) , delete_attrib_greup5(FILEI,GROUP), ~ail~

delete_attrib_group4( ..... ).

delete_attrib_group5(FILE1,GROUP):- display_keys(FILE1>, key ew(EFILEI],EGROUP3,_), !.

delete_attrib_groupS(FILEI,GROUP):- write("> Group: "), write(GROUP),nl,nl, wr i te ( " Does not have any key a~ter d e l e t e " ) , n l , n l , write("> It must have at least one key"),nl, ask_keysl(FILEI,GROUP).

delete_attrib_file1(FILEI,NAME):- attribute_es(FiLEI,NAME), de le te_at t r ib ~ile2(FILEI,NAME), !.

d e l e t e _ a t t r i b _ f i l e l ( _ , _ ) : - wr i te("> No such a t t r i b u t e " ) , n l , n l , write("> Press any key to continue .... "), readchar(_).

delete_attrib_~ile2(FILEI,NAME):- clearwindow, write("> Deleting attribute: ">, write(NAME),nl,nl, confirm, retract(attribute_es(FILEI,NAME)). display_attribs(FILE1), !, check_null_~ile1(FILE1), delete_attrib_~ile3(FILEI,NAME).

delete_at~rib_~ile2<_,_).

delete_attrib_~ile3(F!LE1,NAME):- entity_strong(FILE1>, !, delete_attrib_~ile4(FILEI,NAME>.

delete_attrib_~ile3(FILE1,_):- delete~ile2(FILE1).

de!ete_attrib_file4(FILEI.NAME):- key_es(EFILE13,X), member(NAME,X), retract(key_es(EFILE13,X)), delete_attrib_~ile5(FILE1). ~ail.

delete_attrib_@ile4(_,_)o

159

delete_attrib_{ileS(FILEl):- display_keys(FILEl), key_es([FILE1],_), !.

delete_attrib_~ile5(FILE):- clearwindow, write("> File : "), write(FILE>,nl, write("> Does not has any key after delete"),nl,nl, write(" It must have at least one key"),nl, ask keys1<FILE,"").

edit_attrib_menu:- clearwindow, wr i te ( "> " ) , menu(16,40,"EOlT ATTRIBUTES",

["ADD TO A GROUP", "DELETE FROM A GROUP", "ADD TO A FILE", "DELETE FROM A FILE", "QUIT"],

CHOICE), edit_attrib(CHOICE).

edit_attrib(O):- !,

edit attrib(1):- edit attribl(FILE1), edit_attrib_group1(FILEI,GROUP), ask_attrib_ew(FILEI,GROUP), !.

ed i t_a t t r ib (1 ) : - !.

edit_attrib(2):- edit_attrib1(FILE1), edit_attrib_groupl(FILEI,GROUP), delete_attrib_group1(FILEI,GROUP), !.

edit_attrib(2):- !.

edit_attrib(3):- edit_attrib1(FILEl), clearwindow, write("> Input the attributes one by one"),nl, write(" At end press Return"),nl, ask_attribs_es2(FILEl), ).

edit_attrib(3):- !.

160

e d i t _ a t t r i b ( 4 ) : - edi t attr ib1{FILE1), clearwindow, wr i te("> Please give the a t t r ibu te write("> "), readln(NAMEU), upper lower(NAMEU~NAME), delete attrib_~ilei(FILEI,NAME),

edit_at~rib(4):- !.

to delete")~nl ,

161

/~ PURPOSE: EDITING OF GROUPS ~/

/# TOP LEVEL PREDICATE edit_groups ~/

PREDICATES

edit_groups edit_groupsl(integer,symbol) add_groupsl(symbol) deletegroup1(symbol,symbol) deletegroup2(symbol,symbol) renamegroup1(symbol) renamegroup2(symbol,symbol,symbol)

CLAUSES

edit_groups:- clearwindow, write("> Input the ?ile name o~ which "),nl, write(" you want to edit the groups "),nl,nl, write("> "), readln(NAMEU), upper_Iower(NAMEU,NAME), entity_strong(NAME), !, display_attribs(NAME), clearwindow, write("> "), menu(16,40, "EDIT GROUPS",

["ADD A GROUP", "DELETE A GROUP", "RENAME A GROUP", "QUIT"3,

CHOICE), edit groupsI(CHOICE,NAME).

edit_groups:- wr i te( "> No such ~ i l e " ) , n l , n l , wr i te( "> Press any key to continue . . . " ) , readchar( ) ,

edit_groups1(O, ):- !.

edit groupsl(1,FILE1):- add_groups1(FILE1), !.

162

edit_groupsi(2,FILE1):- clearwindow, wr i te("> Give the group name to de le te " ) ,n l , write("> "), readln(NAMEU), upper_lower(NAMEU,NAME), not (NAME = .... ), clearwindow, write("> Deleting Group: "), write(NAME),nl,nl, w r i t e ( " > * * NOTE * * " ) , n l , n l , wr i te ( " On delet ing the group, the a t t r i b u t e s " ) , n l , wr i te ( " w i l l not be deleted ~rom the ~ i l e " ) , n l , n l , wr i te("> Proceed with delete (Y/N)?"), readln(ANS), upper_Iower("Y",ANS), deletegroupi(NAME,FZLEi), !.

edit groups1(2, ) : - !.

edit_groupsl(3~FILE1):- clearwindow, renamegroupi(FILEl), !.

edit_groupsi(_,_).

add_groupsi(FILEi):- en t i t y strong(FiLEi), !, ask_groups_esi(FILEi).

add_groupsl( ):- write("> No such file"),nl,nl, write("> No such ~ile exists"),nl,nl, write("> Press any key to continue ..."), readchar().

deletegroupl(NAME,FILEl):- retract(entity_weak(FILEq,NAME)), !, deletegroup2(NAME,FILEl).

deletegroupi( , ):- write("> No such group"),nl,nl, wri te("> Press any key to continue readchar(_).

. . . " ) ,

deletegroup2(NAME,FILE):- retract(attribute_ew(FILE,NAME,X)), aseerta(at t r ibute es(FILE,X)), £a i l .

deletegroup2( ,FILE)~- display at t r ibs(FILE).

163

renamegroupl(FILEl):- wr i te("> Give the name of group to wr i te("> " ) , readln(NAMEU~, upper_lower(NAMEO,NAME), en t i ty weak(FILEI,NAME)~ !, wr i te("> Give the new name"),nl, wr i te("> " ) , readln(NAMEU1), upper_lower(NAMEUI,NAMELi), chop name(NAMELI,NAMEI), renamegroup2(NAME,NAMEI,FILEi).

renamegroupi( ) : - wr i te("> No such g r o u p " ) , n l , n l , wri te("> Press any key to continue readchar() .

renamegroup2(A,B,FILE1):- re t rac t (en t i t y weak(FILEI,A)), asserta(ent i ty weak(FILEI,B)), f a i l .

renamegroup2(A,B,FILEi):- re t rac t (a t t r ibu te ew(FILEI,A,Y)), asserta(attribute_ew(FILEI,B,Y)), f a i l .

renamegroup2( . . . . FILE):- display at t r ibs(FILE).

rename") ,n l ,

. . . " ) ,

t64

/~ PURPOSE: MAIN MENU FOR EDITING ~/

/~ TOP LEVEL PREDICATE ne×tstep ~/

/#~####~#######,#~#####~###~##~##~########~####~#####~#~#~##e~#*##~##~/

PREDICATES

e d i t l e d i t 2 ( i n t e g e r ) nextstep n e x t s t e p l ( i n t e g e r )

CLAUSES

editl:- menu(16~40, "Editing o~",

E "FILES", "GROUPS", "ATTRIBUTES ", "QUIT "], CHOICE),

edit2(CHOICE).

e d i t 2 < O ) : - ! .

edit2(1):- edit_£iles, !.

ed i t2 (2 ) edit_groups, !.

edit2(3) edit_art rib_menu, !.

edit2(_):- !.

165

nextstep:- clearwindow, wr i te( "> ") , menu( 16,40, "NEXT STEP",

["EDIT THE DATA", "PROCEED WITH D~ALOG"], CHOICE),

nex%s%epl(CHOICE).

nextstep1(O):- !,

nextstep1(1):- e d i t l , !, nextstep.

nextstep1(_).

166

/ . . / / * PURPOSE~ OVERALL CONTROL OF THE INPUT OF * / / * THE DIALOG THAT ACCEPTS THE USER * / I* INPUTS OF THE DATA ITEMS */ / . * /

/ * TOP LEVEL PREDICATE inpu tda ta * / I. */ /* SCREEN NUMBERS 5-13 */ /. */

PREDICATES

inputdata askesl askes2a

CLAUSES

inpu~data:- write("> Can you already Foresee readln(ANS)~ upper_lower("Y",ANS), !, askesl, nextstep.

the data ~ i l es you w i l l need

<Y/N) ?"

inputdata:- removewindow,removewindow, makewindow(3,2,11,"DIALOG",iS,35,10,45), clearwindow, write("> Input the attributes you wish to store"),nl, write(" Give one attribute per line ..."),nl, write(" At end press Return"),nl, makewindow(5,52,7,"ATTRIBUTES",O,34,14,45), shi~twindow(3) , ask attribs_es2( .... ), entity weak(,_), !, askes~a, ne×tstep.

inputdata:- makewindow(4,0,O,"",7,1,3,3), asserta(entity_strong("~lat file")), retract(attribute es( .... ,X)), asserta(attribute_es("#lat #ile",X)), #ail,

i npu tda ta . askes1:-

removewindow,removewindow, makewindow(3,2,11,"DIALOG",15,35,10,45), makewindow(4,0,O,"",7,1,3,3), shi~twindow(3) , ask f i l e_names l , f a i l .

167

askesl:- entity_strong(_), !, a s k _ a t t r i b s _ e s l .

/~ Checks ex is tence oF £ i l e s ~/

askes2a:- makewindow(4 ,0 ,O, " " ,7 ,1 ,3 ,3 ) , sh i£ twindow(3) , clearwindow, w r i t e ( " > To begin wi th we w i l l make one £ i l e " ) , n l , w r i t e ( " ~or each g r o u p . " ) , n l , n l , w r i t e ( " A t t r i b u t e s which are not in any g r o u p " ) , n l , w r i t e ( " w i l l be put in a F i l e named 'ung~ouped ' " ) , n l , n l w r i t e ( " > Press any key to continue . . . . " ) , readchar(_) , F a i l .

askes2a r e t r a c t ( e n t i t y _ w e a k ( " " , X ) ) , a s s e r t a ( e n t i t y _ s t r o n g ( X ) ) , F a i l .

askes2a ~m

r e t r a c t ( a t t r i b u t e _ e w ( " " , X , A ) ) , a s s e r t a ( a t t r i b u t e _ e s ( X , A ) ) , £ a i l .

askes2a:- ~ i n d a l l ( X , a t t r i b u t e _ e s ( " " , X ) , L ) , n o t ( e q u a l ( L , [ 3 ) ) , asse r t a (en t i t y_s t r ong (ung rouped ) ) , r e t r a c t ( a t t r i b u t e es( .... ,X ) ) , asse r t a (a t t r i bu te_es (ung rouped ,X ) ) , F a i l .

askes2a:- d isp lay_~ i les , . ~ a i l .

askes2a:- clearwindow, w r i t e ( " > In these ~ i l e s , you might be a b l e " ) , n l , w r i t e ( " t o F u r t h e r g r o u p t h e a t t r i b u t e s . " ) , n l , n l , w r i t e ( " > P r e s s a n y k e y t o c o n t i n u e . . . . " ) , r e a d c h a r ( _ ) , e n t i t y _ s t r o n g ( X ) , d i s p l a y _ £ i l e s , clearwindow, ask_groups_es(X), ~ a i l .

askes2a.

168

***************************************************************************

I* . / /* FILE : FDS.PRO */ / * . / / * The predicates in t h i s ~ i l e conduct the d ia log to * / / * in~er the #uct ienal dependencies * / /. * I ***************************************************************************

/@@@@@~@@@@@@@~.~@@@~@@@@@@@@@@@@@@@@@@@@@~@@@@@@~@~@@~@@@~@@@@@@@@@@@/ I. *I /* TO INFER THE FD'8 BASED ON KEY */ I* *I / * keys * / I. *I /* 15 -18 */ I. *I ************************************************************************

PURPOSE:

TOP LEVEL PREDICATE

SCREEN NUMBERS

PREDICATES

keys explain_key ask_keys ask keys_es(symbol) ask_keys_ew(symbol) ask_keys1(symbol,symbol~ ask_keys2(symbol,symbol) ask_keys3(symbol,symbol,lis~,list> ~heck_key(symbol,symbol,list) check existence(symbel,symbol,symbol,list,list)

CLAUSES

k e y s : - explain_key, a s k _ k e y s .

169

I# El /~ FILE: KEY_DEF.TXT ~/

/# > In every ~ i l e / g r o u p there w i l l be an #/ /# i d e n t i f i e r : an a t t r i b u t e or a group #/ /~ of a t t r i b u t e s ca l l ed the: ~/ /# KEY #/ /# whose vlaue is unique f o r a l l the ~/ /~ e n t r i e s in tha t ~ i l e or group ~/ /~ (see example). ~/

/~ Press any key to cont inue . . . #/

/~ FILE: KEY EG.TXT ~/

/~ For a STUDENTS f i l e : #/

/~ ROLL NO NAME CLASS ~/ /~ 8769 Kasturi M.Tech. ~/ /~ 8734 V i j a y B.Tech. #/

/~ ROLL NO is unique ~or a l l the #/ /# e n t r i e s in t h i s ~ i l e . ~/

/# Hence ROLL NO is a KEY. ~/

explain_key:- shi~twindow(3), clearwindow, f i l e _ s t r ( " k e y s d e ~ . t x t " , C ) , write(C), field_attr(3,15,3,79), field_attr(4,17,7,15), makewindow(9,26,7,"EXAMPLE OF KEY",8,0,16,35), file_str("keys_eg.t×t",B), w r i t e ( B ) , field_attr(3,1,7,79), field_attr(5,1,4,31), field_attr(6,1,4,31), readchar(_), removewindow, sh i f tw indow(3 ) , f a i l .

explain_key:- makewindow(6,90,10,"KEY",4,1,4,31), w r i t e ( " a t t r i b u t e ( s ) tha t d e t e r m i n e " ) , n l , write("values o~ all attributes " ) , shi~twindow(3), fail.

170

explain_key:- clearwindow, write("> In general, there may be more than"~,nl, write(" one key in a File (or a group)."),nl, nl,nl, write("> Press any key %o continue .... "),nl, readchar(_), ~ail.

explain_key:- !,

askkeys:- makewindow(7~3£,7,"KEYS',8,14,17,20), shi~twindow(3), ~ail.

ask_keys:- entity s~rong(FILEl), display_Files, shi~twindow(3)~ d i sp lay_a t t r i bs (F ILE1) , shi~twindow(3), ask_keys_es(FILE1~, ~ail.

ask_keys~

ask_keysl(FiLEI,GROUP):- ask keys2(FILE1,GROUP), write("> Are there any more keys readln(ANS1), upper_lower('Y",ANS1),

ask keysI(FILEI,GROUP).

(Y/N) 2 " ) ,

a s k _ k e y s t < F t L E l , " " ) : - key_es<EFtLE1] , ) , ! .

ask_keysl(FlLE1,""):-

write("> There must be at !, ask_keysl(FILE1,"">.

leas% one key " ) , n l ,

ask_keys1(FILEI,X):- key_ew(EFILEl],EX],_), !.

ask_keysl(FiLEI,GROUP):- nl, write("> There must be at !, ask_keysl(FiLE1,GROUP).

least one key " ) ~ n l ,

171

ask_keys2(FILEI,GROUP):- wr i te ( "> Enter the a t t r i bu tes that ~orm a k e y , " ) , n l , w r i t e ( " Enter one a t t r i b u t e per l i n e , " ) , n l , w r i t e ( " When done, press r e t u r n " ) , n l , ask_keys3(FILEI,GROUP,KEYI,[]), check_key(FILEI,GROUP,KEYI), display_keys(FILEl), !, w r i te ( "> Are there any more keys (Y/N) ?") , readln(ANS1)~ upper_lower("Y",ANS1), ask_keys~(FILE1,GROUP).

ask_keys2(_,_).

ask_keys3(FILE1,GROUP,KEYI,IN):- wr i te ( "> " ) , readln(NAMEU), not (NAMEU = .... ), upper_lower(NAMEU,NAME), !, check_existence(FILEI,GROUP,NAME,IN,OUT), ask keys3(FILEI,GROUP,KEYI,0UT).

ask_keys3(FILEI,GROUP,KEYI,IN):- wr i te ( "> Any more a t t r i bu tes in readln(ANS), upper_Iower("Y",ANS), !, ask keys3(FILEI,GROUP,KEYI,IN).

the key (Y/N)?"),

ask_keys3( .... KEYI,KEYI).

check_existence(FILE1,"",NAME,IN,OUT):- a t t r ibu te_es(FILEI ,X) , X=NAME, !, union(OUT,[NAME3,IN).

check_existence(FILEl,"",NAME,IN,OUT):- attribute_ew(FILE1,_,X), X=NAME, !, union(OUT,ENAME],IN).

check_existence(FILEI,GROUP,NAME,IN,OUT):- attribute_ew(FILEI,GROUP,X), X=NAME, !, union(OUT,ENAME3,IN).

check_e×istence(_,_,_,X,X):- wr i te ( "> Undeclared/Mis-spelt a t t r i b u t e " ) , n l , !.

172

check_key (F ILE l , " " ,KEY) : - key_es(EFZLEl ] ,X) , equal(X,KEY), write("> This key !.

is already known"),nl,

check_key(FILEI,GROUP,KEY):- key_ew(EFILEI],EGROUP],X), equal(X,KEY)~ write("> This key is already known ") ,nl,

check_key(_,_,E]):- write("> Key must J=

have at least one a t t r i b u t e " ) , n l ,

check key(FILEI,"",KEY1):- assertz(key_es(EFILE1],KEY1)),

check_key(FZLE~,GROUP,KEYi):- assertz(key_ew(EFILE1],EGROUP],KEY1)).

ask_keys_es(FILEl)~- clearwindow, ask_keys_ew(FiLEl), write("> Now ~or ~ile: ")~ write(FILE1),nl, ~ield_attr(O,15,25,11), display_attribs_ew(FILE1,""), ask_keysl(FILE1,"").

ask_keys_e~{FILE1):- entity_weak(FILEI,X), write("> For group : "), write(X),nl, field_a~tr(0,15,~5,14), write("> In ~ile : "), cursor (PP,_) , w r i t e ( F I L E 1 ) , ~ield_attr(PP,15,~5,11),nl, display_attribs_ew(FILEI,X), ask_keys1(FiLEI,X), ¢learwindow, Fail.

ask_keys_ew(_),

173

/ ~ ~ ~ ~ ~ . ~ ~ ~ ~ ~ * ~ /

/~ PURPOSE: TO INFER THE FD'S BASED ON A * / /~ PART OF THE REY ~/

/~ p a r t e d ~/

/ ~ ~ 3 - ~ 6 ~ /

I ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ I

TOP LEVEL PREDICATE

SCREEN NUMBERS

PREDICATES

explain part ial~d part ia l~d getkey(symbol,symbol,l ist) part ial~d1(symbol,symbol, l ist) part ial~d2(symbol,symbol, l ist) read_part k e y ( l i s t , l i s t , l i s t ) read part attrib(symbol,symbol,symbol) checkname pk e s ( l i s t , s y m b o l , l i s t , l i s t )

CLAUSES

getkey(FILE,"",REY):- ent i ty_strong(FILE), key es([FILE3,KEY).

getkey(FILE,GROUP,REY):- entityweak(FILE,GROUP), key ew(EFILE],EGROUP],KEY).

174

I* .I /* FILE: PARTFD.TXT ~/ I* *I /* Roll No Name Course Grade #/ I* *I /* 1267 ATUL CADS A */ /* 1267 ATUL DPS B */ /* 1267 ATUL OR C */ /* 1270 JOY CADS C * / 7" 1270 JOY DPS B */ /* .I I* ./ / # Key is (Ro l l No, Course) * / /~ Name depends on on ly a par t * / /* of the key, i.e. Roll No. */ I* ./ /@@~@@@@@~@@@@@~@@@@@@@@@@@~@~@@@@@@@@@@@~@@@@~/

explain_partialfd:- clearwindow, write("> Here we want to see if there are"),nl, w r i t e ( " some a t t r i b u t e s which depend on " ) , n l , w r i t e ( " on ly a part of the key (see e x a m p l e ) . " ) , n l , n l , w r i t e ( " > Press any key to continue . . . " ) , d i s p l a y _ f i l e s , makewindow(2,26,7,"Example of part key",8,0,16,35), nl, file str('partfd.txt",A), write(A), shiftwindow(3), readchar(_), m a k e w i n d o w ( 7 , 9 0 , 1 4 , " K E Y S " , O , 1 3 , 7 , 2 0 ) ~ partialfd, !.

partialfd:- getkey(FILEI,GROUP,EX~XT]), not (equal (XT,E])), dieplay_attribs_ew(FILEI,GROUP), shiftwindow(7), ¢learwindow, write("For Key :"),nl, writelist_hz(EXIXT]), partialfdl(FILEI,GROUP~EXIXT]), fail.

partialfd.

175

par t ia lFd1( . . . . . ) : - shiFtwindow(3), clearwindow, f a i l .

partialfd1(FILE1,GROUP,KEY):- clearwindow, w r i t e ( " > For the Key shown in KEYS w i n d o w : " ) , n l , n l , d i sp lay_a t t r i bs (F ILE1) , w r i t e ( " Is there any a t t r i b u t e which is a F f e c t e d " ) , n l , w r i t e ( " by only a part of the key (Y/N)?") , readln(ANS), u p p e r _ l o w e r ( " Y " , A N S ) , partialFd2(FILEI,GROUP,KEY).

partialFdl( . . . . . ) .

partial~d2(FILEI,GROUP,REY):- w r i t e ( " > Please enter the part key a t t r i b u t e s " ) , n l , w r i t e ( " one by one. When done, press R e t u r n " ) , n l , read_part_key(KEY,E3,KEYl), read_part_attrib(FILEI,GROUP,NAME), asserta(Fd(KEY1,[NAME3)), w r i t e ( " > Any more such a t t r i b u t e s (Y/N)?") , readln(A), upper_lower("Y",A) , !, partialFd2(FILEi,GROUP,KEY).

par t ia lFd2( . . . . . ) .

read_par t_at t r ib(FILE1,"" ,NAME): - w r i t e ( " > Please type the a f fec ted a t t r i b u t e " ) , n l , w r i t e ( " > " ) , readln(NAMEU)~ upper lower(NAMEU,NAME), attr ibute_es(FILEI,NAME), !.

read_par t_a t t r ib (F ILE i , " " ,NAME) : - w r i t e ( " > No such att r ibute") ,n l ,n l , w r i t e ( " > Do you want to give a f fec ted " ) , n l , w r i t e ( " a t t r i b u t e (Y/N)? " ) , readln(A), upper_lower("Y",A), !, read_part_attr ib(FILE1,"" ,NAME).

read_part a t t r i b ( _ , " " , _ ) : - !, f a i l .

r e ad_pa r t_a t t r i b ( FILE i , GROUP, NAME ) : - w r i t e ( " > Please input the a f fec ted a t t r i b u t e " ) , n l , w r i t e ( " > " ) , read in (NAMEU), upper_lower (NAMEU, NAME), a r t r ibute_ew(FILE1 ,GROUP ,NAME), !.

176

read_par t_a t t r i b (FZLE1 ,GROUP,NAME) : - w r i t e ( " > No such a t t r i b u t e " ) , n l , w r i t e ( " > Do you want to give a{ {ected ? " ) , n l , w r i t e ( " a t t r i b u t e (Y/N)? " ) , readln(A), upper lewer("Y"~A), !, read part attrib(FILEI,GROUP,NAME).

read p a r t a t t r i b ( . . . . . ) : - C a i l .

r e a d _ p a r t key (KEY,A ,KEYt )~ - w r i t e ( " > " ) , readln(NAMEU), upper lower(NAMEU,NAME), not (NAME= .... ) , checkname_pk_es(EEY,NAME,A,X), !, read_part_key(KEY,X,KEY1).

read p a r t k e y ( K E Y , A , E E Y i ) : - w r i t e ( " > Any more a t t r i b u t e s in pa r t key ( Y / N ) ? " ) , readln(ANS), u p p e r _ l o w e r ( " Y ' , A N S ) , ! , read_par t_key (KEY,A ,EEY1) .

read part key(KEY,E],KEY1):- w r i t e ( " > You should give at least one a t t r i b u t e ~ ' ) , n l , n l , w r i t e ( " > Do you want to g i v e the p a r t key ( Y / N ) ? " ) , readln(ANS), u p p e r _ l o w e r ( " Y ' , A N S ) , !, read pa r t key (KEY,E ] ,KEY I ) .

read_part key (_ ,E3 ,_ ) : - !, #ai l~

r e a d _ p a r t _ k e y { _ , A , A ) o

checkname pk_ee(KEY,NANE,A,X):- member(NAME,EEY), uniQn (X,ENAME],A), !,

checkname_pk_es (_,_,A,A) : - w r i t e ( " > I t is not a member !, n l , w r i t e ( " > Input a g a i n " ) , n l .

o# t h i s k e y " ) , n l ,

177

/#~##~#~##~.~####~#~###~#~#~###~###~##~#####~##~#~.~#~##~#/

/# PURPOSE: TO INFER THE FD'S IN WHICH A NON-KEY * / /~ ATTRIBUTE DETERMINES A KEY ATTRIBUTE #/

/~ nonkeyfd #/

/~ 19-20 ~/

TOP LEVEL PREDICATE

SCREEN NUMBERS

PREDICATES

nonkeyfd f i nda l l _key ( l i s t , symbo l , symbo l , l i s t ) r e a d n o n k e y ( l i s t , l i s t , l i s t ) r e a d n o n k e y l ( l i s t , l i s t , l i s t , s y m b o l ) n o n k e y f d 4 ( l i s t , l i s t ) nonkeyCd3(list,symbol) n o n k e y f d S ( l i s t , l i s t ) nonkeyfdl(symbol,symbol)

CLAUSES

nonkeyfd:- makewindow(7,90,14,"KEY ATTRIBUTES",O,13,7,80), shiftwindow(5), removewindow, makewindow(5,58,7,"NON KEY ATTRIBUTES",O,34,14,46), shi~twindow(3), clearwindow, wr i te ( "> Locate the window t i t l e d KEY ATTRIBUTES"),nl, field_attr(O,86,15,14)~ write(" on the screen (upper left corner) and"),nl, w r i t e ( " Also the NON KEY ATTRIBUTES window (up ) " ) , n l , w r i t e ( " Proceed now keeping these two windows"),nl, w r i t e ( " in mind.") , n l , n l , wr i te ( "> Press any key to continue . " ) - . . F

readchar(_), f a i l .

nonkey~d:- clearwindow, wr i te ( "> Normally key a t t r i bu tes w i l l determine") ,n l , w r i t e ( " the values of non-key a t t r i b u t e s . " ) , n l , n l , w r i t e ( " However, there may be excep t i ons . " ) , n l , n l , wr i te ( "> Press any key to continue . . . . " ) , readchar(_), f a i l .

nonkey~d:- en t i t y strong(FILE1), shi~twindow(3), clearwindow, nonkey~dl(FILEi,""), f a i l .

178

nonkeytd:- en%i%y_weak(FiLE1~GROUP), shi~twindow(3), clearwindow, nonkeyCdl(FILEI,GROUP), t a i l .

nonkey£d:- shittwindow(7)~ removewindow, shi~twindow(5), clearwindow, shi£twindow(3),

nonkeyFd1(FILEI,GROUP):- t i n d a l l att(FILEI,GROUP,ALL), Findall_key(E3~FILEI,GROUP,ALLKEY), minus(NONKEY,ALL,ALLKEY), not(equal(NONKEY,[3)), !, shittwindow(7), clearwindow, ~ritelist_hz(ALLKEY), shittwindow(5), clearwindow, cursor(T,R), diep_list_col(T,R,NONKEY), shittwindow(3), wr i te("> In above windows do you see any wr i te ( " a t t r i bu te whose value depends wr i te ( " some o~ the non-key at t r ibutes readln(ANS), upper_lower("Y",ANS), nonkeytd2(ALLKEY~NONKEY), tail.

key"),nl, on "),nl,

( Y / N ) ? " ) ,

nonkeytd1(_,_).

~indall_key(A,FILEi,"",ALLKEY):- key_es(EFILE1],L), union(M,L,A), not (equal (M,A)),

~indalI_key(M,FILEI,"",ALLKEY)~

findall key(A~_,"",A)=

nonkeytd2(KEY,NONKEY):- nonkeytd4(NONKEY,Q), nonkey£d3(NEY,P), asserta(td(G,EP3)).

nonkeytd2(KEY,NONKEY):- clearwindow, write("> Any more Key attribute whose value"),nl, write(" depends on Non-key attributes (Y/N)? "), read!n(ANS), upper lower("Y",ANS), ?, nonkey~d2(KEY,NONKEY).

179

nonkey~d2(_,_).

nonkey~d3(KEY,P):- wr i te("> Input the key a t t r i b u t e . " ) , n l , wr i te("> "), readln(NAMEU), upper_lower(NAMEU,NAME), member(NAME,KEY), P=NAME, !,

nonkeyfd3(KEY,P):- wr i te("> This a t t r ibu te wri te("> Do you want to readln(ANS), upper_lower("Y",ANS), !, nonkey~d3(KEY,P).

is not in key" ) ,n l ,n l , input again (Y/N)?"),

nonkey~d3(_,_):- !, ~a i l .

nonkey~d4(NONKEY,Q):- wr i te("> Input such non key at t r ibutes wr i te ( " When done press re tu rn . " ) , n l , readnonkey([3,NONKEY,Q).

one by

readnonkey(IN,NONKEY,OUT):- wri te("> ") , readln(NAMEU), upper_lower(NAMEU,NAME), not(NAME=""), readnonkeyi(IN,NONKEY,OUTI,NAME), !, readnonkey(OUTI,NONREY,OUT).

readnonkey(A,NONREY,B):- wr i te("> Any more at t r ibutes (Y/N) ?"), readln(ANS), upper_lower("Y",ANS), !, readnonkey(A,NONREY,B).

readnonkey(E3,NONEEY,B):- wr i te("> You should give at least one") ,n l , wr i te ( " a t t r ibu te " ) , n l , n l , wr i te("> Do you want to give (Y/N)?"), readln(ANS), upper_lower("Y",ANS), !, readnonkey(E],NONKEY,B).

readnonkey(E],_,_):- !, ~ail.

readnonkey(IN,_,IN).

one") ,n l ,

180

readnonkeyI(IN,NONKEY,OUT,NAME):- member(NAME,NONKEY), union(QUT,IN,[NAME]), !.

readnonkeyi( IN,_, IN, ) : - w r i t e ( " > I t is not a non key a ~ t r i b u t e " ) , n l , w r i t e ( " > Input a g a i n " ) , n l .

181

/~ PURPOSE: TO INFER MULTI VALUED DEPENDENCIES ~/

/ * mvd~ ~/

/ * 2 1 - 2 2 ~/

TOP LEVEL PREDICATE

SCREEN NUMBERS

PREDICATES

mvds explainmvd mvdl mvd2(symbol) mvd3(symbol,symbol) mvd4(symbol ,symbol , l i s t ) ask md_a t t r ( s ymbo l , s ymbo l , l i s t ) ask_md_at t r1 (symbol ,symbol ,symbol , l i s t ) ask md a t t r 2 ( s y m b o l , s y m b o l , s y m b o l , l i s t , l i s t ) check md a t t r (symbol ,symbol ,symbol )

CLAUSES

/~ FILE: MVD EG.TXT ~/

/~ EXAMPLE : ~/

/~ ROLL NO COURSES TAKEN #/ /~ 8765 IME602,CS60I,IME624 * / /# 8766 IME602,IME624,ME651 ~/ /# 8767 IME602,1ME673,IME621 #/ / * B769 HSS730,EE450 * /

/~ Here, COURSE TAKEN can be seen ~/ /~ to take severa l values fo r any * / /# given value of the key, ROLL NO. #/

explainmvd:- clearwindow, w r i t e ( " > Now we need to know which among the " ) , n l , write<" attributes listed can take several"),nl, w r i t e ( " values ~or any given value o~ the k e y " l , n l , w r i t e ( " (see e×ample). ") , n l , n l , makewindow(2,26,7 , " 'Mul t i valued a t t r i b u t e s ' " , B , O , 1 6 , 3 5 ) , f i l e _ s t r ( "mvd_eg. t x t " , B>, w r i t e ( B ) , shiFtwindow(3), w r i t e ( " > Press any key to continue . . . . " ) , readchar(_) .

182

?ail~

check md attr(FILE!,:~',NAME>~ - key_es(EFILE13,X>, member(NAME,X),

~rite("> This attribute is already in keyo"),nl, ~ail.

check: md at%r<FILE1,'",NAME)~- retract(attribute_es(FILEI,NAME)), {.

check md attr( , " " )~- ! , write("> Undeclared/Misspelt a~%ribute'),nl, ¢ail~

chec< md attr(FILEI,GROUP,NAME):- key_ew(EFILE13,EGROUPD,X), member(NAME,X),

write("> This attribute is already in key."),nl, Call.

check_m~_attr(FiLE1,GROUP,NAME):- retract(attribute_ew(FILE1,GROUP,NAME)),

check ma attr<_,_~_):- write("> Undeclared/Misspelt attribute"),nl, #ail.

ask md a~tr2(FILEJ,GROUP,MD,IN,OUT):- ~ r i % e ( " > " > , readln(NAMEU), upper_lo~er(NAMEU,NAME), ~heck md attr(FILEI,GROUP,NAME),

union(OUTI,IN,ENAME]), ask md attr2(FILEI,GROUP,MD,OUTI,0UT)o

ask: md a~tr2(FiLEI,GROUP,NAME,IN,OUT):- write("> Any more attributes whose value"),nl, write(" depends on the value o~ : "), cursor(P,8), ~rite(NAME), ¢ield attr(P,Q,14,12),nl, write(" (Y/N)? " ) , readln(ANS), upper_lower("Y",ANS),nl,

write("> Enter %he attributes one per line."),nl, ~rite("> When done, Press return."),nl, ask md at%r~(F!LEI,GROUP,NAME,IN,OUT).

ask md attr2( ,_ .... X,X).

183

ask_md_attrl(FILEI,GROUP,NAME,RHS):- clearwindow, w r i t e ( " > Are there any a t t r i b u t e s whose w r i t e ( " depends on the value o~ : " ) , cursor(P,G), write(NAME),nl, ~ ie ld_a t t r (P ,G,14 ,12) , w r i t e ( " (Y/N)? " ) , readln(ANS), u p p e r _ l o w e r ( " Y " , A N S ) , I F

w r i t e ( " > I n p u t such a t t r i b u t e s one p e r w r i t e ( " When done, press r e t u r n . " ) , n l , ask md_attr2(FILEI,GROUP,NAME,ENAME],RHS).

ask md attrl(_,_~NAME,[NAME]).

ask md attr(FILEI,GROUP,KEY):- w r i t e ( " > " ) , readln(NAMEU), upper_lower(NAMEU,NAME), check_md attr(FILEI,GROUP,NAME), ask md attrI(FILEI,GROUP,NAME,RHS), asserta(mvd(KEY,RHS)), ~ a i l .

ask md attr(FILEI,GROUP,KEY):- w r i t e ( " > Any more a t t r i b u t e s which can w r i t e ( " more than one value ~or same w r i t e ( " the key (Y/N>? " ) , readln(ANS), upper_lower(ANS,"Y"), i F

w r i t e ( " > Enter the a t t r i b u t e " ) , n l , ask md_attr(FILEI,GROUP,KEY).

mvd2(FILEi):- entity weak(FILEI,GROUP), mvd3(FILEI,GROUP), ~ail.

mvd2 (_) .

mvd4( . . . . . ) : - shi£twindow(3), clearwindow, ~ a i l .

mvd4(_,_,X):- shi~twindow(7), clearwindow, w r i t e l i s t _ h z ( X ) , ~ a i l .

value") , n l ,

l i n e . " ) , n l ,

take " ) , n l , value o~") ,n l~

184

mvd4(FILE!,GROUP,X)~- shi{twindow(3), write("> Is ~here any attribute above which can"),nl, write(" take several values ~or a single value"),n!, w r i t e ( " o f ~he key (Y/N)? " ) , readln(ANS), u p p e r _ l o w e r ( A N S , " Y " ) , clearwindow, write("> Enter the attribute"),nl, ask md attr(F!LEI,GROUP,X).

mvd3(FILEI,GROUP):- getkey(FILEI,GROUP,X)~ ~indalI_att(FiLEI,GROUP,ALL), ?indall key(E],FILEI,GROUP,ALLKEY), minus(NONKEY,ALL,ALLKEY), not(equal(NONKEY,E])), shi{twindow(5), clearwindow, cursor(T~R), disp_list_co1(T,R,NONKEY), shi~twindow(3), mvd4(FILEI,GROUP,X), Fail.

mvd3(_,_)o

mvd1:- entity_strong(F!LEl>, mvd2(FILEl), mvd3(FILEl,"'>, ?all.

mvdl.

mvds:- expiainmvd, makewindow(7,90,7,"Keys",O,13,7,20), mvdl, shi~twindow(2), removewindow, shi~twindaw<3).

185

/ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ /

/~ PURPOSE: MAIN CONTROL FOR INFERENCE OF FD'S ~/

/# TOP LEVEL PREDICATE {ds ~/

PREDICATES

Fds asser~Fds

CLAUSES

f d s : - shiFtwindow(~), removewindow, shiFtwindow(6), removewindow, shi~twindow(7~, removewindow, shi f twindow(3~, F a i l .

Fds:- nonkeyfd, mvds, F a i l .

~ds:- getkey(_,_,E_~XT3), not (equal (XT,E3)), !, explain_partial~d, shi£twindow(2), removewindow, shi~twindow(7), removewindow, shi~twindow(3) , asser t fds .

Fds:- assertFds.

asser tFds : - key_es(EFILE3,X), a t t r i b u t e _ e s ( F I L E , Y ) , asserta(~d(X,[Y3)), ~ail.

assertFds:- key_ew<EFILE3,[GROUP],X), attribute_ew(FILE,GROUP,Y), asserta(Fd(X,EY3)), fail.

assert~ds:- key_es(EFILE3,X), key_ew(EFiLE3,_,Y), member(M,Y), a~serta({d(X,EM])), ?all.

asser~ds~

~86