home *** CD-ROM | disk | FTP | other *** search
- ------------------------------------------
- BOX 1
-
- PROMOTION TABLE (RDBMS)
-
- CareerField Selects Eligible Cycle
- avionics 66 326 fy83a5
- personnel 229 1397 fy85a6
- linguist 39 123 fy84a7
-
- PROMOTION TABLE (PROLOG)
-
- waps(avionics,66,326,fy83a5).
- waps(personnel,229,1397,fy85a6).
- waps(linguist,39,123,fy84a7).
-
- PROMOTION RATE TABLE
- Cycle RATE
- fy83a5 .17
- fy84a7 .28
- fy85a6 .18
-
- PROMOTION RATE TABLE (PROLOG)
- p_rate(fy83a5,0.17).
- p_rate(fy84a7,0.28).
- p_rate(fy85a6,0.18).
- ------------------------------------------
- BOX 2
-
- To identify those career fields which may
- have a promotion advantage:
-
- advantage(CareerField) :-
- waps(CareerField,Selects,Eligible,_,Cycle),
- p_rate(Cycle,Rate),
- Selects / Eligible >= Rate+0.05.
-
- To identify career fields which may have
- abnormal selection rates due to the small
- size of the career field:
-
- small_cell(CareerField) :-
- waps(CareerField,Selects,Eligible,_,Cycle),
- Eligible < 100,
- p_rate(Cycle,Rate),
- SelectRate = Selects / Eligible,
- not(Rate-0.005 <= SelectRate <= Rate+0.005).
- ------------------------------------------
- BOX 3
- relation_1
-
- SSAN RANK CareerField
- 3 lieutenant pilot
- 1 captain mathematician
- 2 major pilot
-
- relation_2
-
- SSAN RANK CareerField
- 2 major pilot
- 3 lieutenant pilot
- 1 captain mathematician
-
- relation_3
-
- SSAN RANK CareerField
- 3 lieutenant pilot
- 4 colonel commander
-
- relation_4
-
- SSAN RANK CareerField
- 4 colonel commander
- 3 lieutenant pilot
-
- relation_5
-
- SSAN CareerField RANK
- 3 pilot lieutenant
- 1 mathematician captain
- 2 pilot major
-
- ----------------------------------------------
- BOX 4
- A Simple Display Loop
-
- % Display the instances of relation r
- display :-
- r(X, Y, Z),
- display_hlpr(X, Y, Z),
- fail.
- display.
-
- Here's how this
- loop works. Each time Prolog can find an
- <I>X<R>, <I>Y<R> and <I>Z<R> which
- satisfy <I>r<R>, it does so. Prolog
- passes these values to display_hlpr,
- which writes them to the screen. Then
- the <I>fail<R> causes Prolog to
- BACKTACK. It goes back to the last
- point where a choice was made -- namely
- <I>r(X, Y, Z)<R>, where the values of
- the variables were chosen. Prolog looks
- for another choice for these variables
- in the as yet unsearched part of its
- database. If it finds one, it repeats
- the display and failure in another cycle
- through the loop. If it finds no more
- values satisfying <I>r<R>, it
- abandonsthe first <I>display<R> clause
- and goes on to the second clause, namely
- <I>display.<R> This clause does not
- display anything, but as a clause stored
- in Prolog's database of
- assumed-to-be-true logical statements,
- <I>display.<R> is logically true. This
- causes <I>display<R> as a Prolog goal
- (Prolog procedure call or statement to
- proved) to be satisfied. This
- satisfaction, essentially a boolean
- value for <I>display<R> of TRUE, is
- returned to the caller of the predicate
- (Prolog procedure) or to the user if the
- user directly asked for <I>display<R>.
-
- ---------------------------------------------------------
- Box 5
- Example of Quotient in Prolog
-
- % r6 / r7
- r6_div_r7( Name) :-
- % find a name in r6
- r6( Name, _),
- % make sure it appears with all possible r7's
- r6_div_r7_hlpr( Name).
-
- % succeed if Name can be extended in all r7
- % ways so result is in r6
- r6_div_r7_hlpr( Name ) :-
- % get possible values of Expertise
- r7( Expertise ),
- % if some Name -- Expertise pair is not in r6
- ( not r6( Name, Expertise),
- % then fail and quit
- !, fail
- % else fail to get the next Expertise to try
- ; fail).
- % succeed when all Expertise have been tried
- r6_div_r7_hlpr( _) .
-
- --------------------------------------
- Box 6
- Synthesizing Quotient Rules
-
- % rule for quotient
- define_goal( Query, %%% user query
- Goal) :- %%% name and arity of synthesized rule
- %%% is Query a quotient?
- functor( Query, '/', 2), !,
- %%% if so, get its arguments
- arg( 1, Query, R1), !,
- arg( 2, Query, R2), !,
- %%% define subgoals
- define_goal( R1, Goal1),
- define_goal( R2, Goal2),
- %%% and get their names and arities
- get_name_and_arity( Goal1, Name1, Arity1),
- get_name_and_arity( Goal2, Name2, Arity2),
- %%% create a name for the quotient predicate
- build_name( Name1, Name2, '/', Quotient_name),
- %%% get arity of quotient
- Quotient_arity is Arity1 - Arity2,
- %%% make sure it's positive
- ( Quotient_arity > 0
- ;
- write($ Quotient can not be defined.$), nl, !, fail
- ),
- %%% generate call to quotient
- functor( Quotient_call, Quotient_name, Quotient_arity),
- %%% get call to denominator
- functor( Denominator_call, Name2, Arity2 ),
- %%% get args of Denominator
- Denominator_call =.. [ _ | Denominator_args],
- %%% get args of quotient
- Quotient_call =.. [ _ | Quotient_args],
- %%% get args to Numerator
- append( Quotient_args, Denominator_args, Numerator_args),
- %%% build call to numerator
- Numerator_call =.. [ Name1 | Numerator_args],
- %%% get name of quotient helper
- concat( Quotient_name, $_hlpr$, S_hlpr_name),
- atom_string( Hlpr_name, S_hlpr_name),
- %%% build call to helper predicate
- Hlpr_call =..[ Hlpr_name | Quotient_args],
- %%% build main helper rule
- Hlpr_rule_1 =
- ( Hlpr_call :- Denominator_call,
- ( not Numerator_call, !, fail;
- fail)),
- %%% build loop terminator helper rule
- Hlpr_rule_2 = Hlpr_call,
- %%% remove old clauses with same name as helper
- retractall( Hlpr_call),
- %%% define the helper predicate
- assertz(Hlpr_rule_1),
- assertz(Hlpr_rule_2),
- %%% define quotient rule
- Quotient_rule = ( Quotient_call :- Numerator_call, Hlpr_call),
- %%% remove all old predicates of this name
- retractall( Quotient_call),
- %%% define the quotient predicate
- assertz(Quotient_rule),
- %%% set output to name and arity of this predicate
- Goal = Quotient_name / Quotient_arity.
-
- --------------------------------------------------
-
- ri