micro proust u) yale univ newj haven ct dept of … · ,ad-ri57 505 micro proust u) yale univ newj...
TRANSCRIPT
,AD-Ri57 505 MICRO PROUST U) YALE UNIV NEWJ HAVEN CT DEPT OF COMPUTER 1/2SCIENCE WL L JOHNSON ET AL. JUN 85 YALEU/CSD/RR-402N00014-82-K 8714
UNLSIIDFG92 N
2..
II4II 111220
11111 11111J.4
MICROCOPY RESOLUTION TEST CHART
S"- )ARDS 1963 A
S!!?
Ii~
Sii
". . .
," .' "" o o." .* -. ° . ". * -. * " . -- I• % . " - • . - ° • . .. .. ' o -
In
Lfl
Micro-PROUST
W. Lewis Johnson and Elliot Soloway
YALEU/CSD/RR #402
June 1965
> ELECTEThis docuent has ben cippoved AUG 5 Mfor public telease and !Zh.;lc its
U LAU distributionisulitd
j A85 0'?07 023
i I I ~~- nmnnn.n. . m.. . II.. ....... . ... ....... .' 1- , -
YALE UNIVERSITY* DEPARTMENT OF COMPUTER SCIENCE
- - .. . . .
~Accessio'n For
MiroPRUS
W. Lewis Johnson and Ellot Soloway
-. YALEU/CSD,'RR #402
June 1985
U3 5 M5
0 AA
This docl~zflj,~~
Micro-PROUST
W. Lewis Johnson and Elliot Soloway
YALEU/CSD/RR #402
June 1985
The reseach described in this paper was co-sponsored by the Personnel and Training
Research Groups, Psychological Sciences Division, Office of Naval Research and the Army
Research Institute for the Behavioral and Social Sciences, under Contract No. N00014-82-
K-0714, Contract Authority Identification Number 154-492. Approved for public release;
distribution unlimited. Reproduction in whole or part is permitted for any purpose of the
United States Government.
L:- - ho
Micro-PROUST
Designed by:W. Lewis Johnson
Elliot SolowayDepartment of Computer Science
Yale UniversityP.O. Box 2158
New Haven, Connecticut 06520
Programmed by:Bret Wallach
Advanced Processing, San Diego, Calif.
The research described in this paper was co-sponsored by the Personnel and Training ResearchGroups, Psychological Sciences Division, Office of Naval Research and the Army ResearchInstitute for the Behavioral and Social Sciences, under Contract No. N00014-82-K-0714,Contract Authority Identification Number 154-492. Approved for public release; 'distributionunlimited. Reproduction in whole or part is permitted for any purpose of the United States
Government.
it IThe authors gratefully acknowledge the support of Courseware, Inc., of San Diego, California,for providing the funds to develop Micro-PROUST. We would particularly like to thank Dr.Gregg Kearlsey of Courseware for his unflagging effort and support in seeing this project throughto fruition.
V
7 .. ° - . . - , .-. - . - ., S.-' S 1. ES , " , - u < . i ' -
SiCU,r7 CLASS,FICAON o is PAGE sh,-n Data Entered) . "
REPORT DOCUMENTATION PAGE BEFORE CMPTICO R
.It REPORT NUMBER 2. GOVT ACCESSION NO. 3. RECIPIENT'S CATALOG NUMBER
i 4 TITLE (and Subtitl S. TYPE OF REPORT A PERIOD COVERED
Micro-PROUST Research Report
6. PERFORMING ORG. REPORT NUMBER
7. AUTNOR(s) I. CONTRACT OR GRA8T .NUMIEfR(a)
W. Lewis Johnson and Elliot Soloway NOO0I-82-K-0714
S. PERFORMING ORGANIZATION NAME AND ADDRESS S0. PROGRAM ELEMENT. PROJECT. TASK
Yale University - Dept. of Computer Science AREA A WORK UNIT NUMBERS
10 Hillhouse AvenueNew Haven, CT 06520
11. CONTROLLING OFFICE NAME AND ADDRESS 12. REPORT DATE
Advanced Research Projects Agency June, 1985
1400 Wilson Boulevard U. NIMSEROPPAGESArlington, VA 22209 136
14 MONITORING AGENCY NAME & ADORESS(I1 different Ife. Controllit Ofllice) 1. SECURITY CLASS. (of this report)
Office of Naval Researach Unclassified
Information Systems ProgramArlington, VA 22217 ISO. ILDECL ASLSIlCATION/ DOWNGRADING
1S. DISTRIBUTION STATEMENT (of this Reporf)
Distribution of this report is unlimited.Ii
17. OISTRISUTION STATEMENT (of the abstract ontted in Block 20. i difforent fmwm Repat)
1S. SUPPLEMENTARY NOTES
IS. KEY WORDS (Caninue an reverse &)do if necessar ONd Identify by Nock mimbe?)
,intelligent tutoring sytemsstudent modelling, '.automatic program debugging.-
20. ABSTRACT (Csetlrmnu an reverse side II neceoemy and Identify by toek number)
PROUST is a system that can identify, for a class of moderately complex
introductory looping assignments, the non-syntactic bugs in novices' programs.
PROUST is a 15,000 LISP program and runs on a VAX. Micro-PROUST is a program
meant to capture the essence of PROUST. Micro-PROUST is a 1500 line LISP
program and runs on an IBM PC (with 512K). 'In this document we present,
the inner workings of Micro-PROUST. Our intent is to enable those who so
are inclined to see at a nuts and bolts level how a system like PROUST
actually works. - . .
DD 1473 EDITION of I Nov 5 is oSoLIT9S N 0102. LF. 014.6601 SOCURITY CLASSIFICATION OF Twig P469 (R" bwe
r
- OFFICIAL DISTIRUBTION LIST -
Army Private Sector
Technical Director I copy Dr Michael Genesereth I copy
U S Army Research Institute for the Department of Computer Science
Behavioral and Social Sciences Stanford University
5001Eisenhower Avenue Stanford. California 94305Alexandria. Vircinia 22333
Dr Dedre Gentner I copyMr James Baker 1 copy Bolt Beranek I NewmanArmy Research Institute 10 Moulton Street
5001 Eisenhower Avenue Cambridge. Massachusetts 02138Alexandria. Virginia 22333
Dr Robert Glaser 1 copy
Dr Beatrice J Farr I copy Learning Research £ Development CenterU S Army Research Institute University of Pittsburgh5001 Eisenhower Avenue 3939 O'Hara StreetAlexandria. Virginia 22333 Pittsburgh, Pennsylvania 15260
Dr Milton S Katz 1 copy Dr Joseph Goguen 1 copy
Williams Technical Area SRI International
U S Army Research Institute 333 Ravenswood Avenue5001 Eisenhower Avenue Melo Park. California 94025Alexandria, Virginia 22333
Dr. Bert Green 1copy
Dr Marshall Narva I copy Johns Hopkins University
U S Army Research Institute for the Department of Psychology
Behavioral A Social Sciences Charles A 34th Street
5001 Eisenhower Avenue Baltimore. Maryland 21218Alexandria, Virginia 22333
Dr Harold F O'Neil. Jr 1 copy Dr James 0 Greeno I copy
Director. Training Research Lab LRDCArmy Research Institute University of Pittsbrgh5001 Eisenhower Avenue 3939 O'Hara StreetAlexandria. Virginia 22333 Pittsburgh. Pennsylvania 15213
Commander, US Army Research Institute 1 copy
for the Behavioral * Social Sciences Dr Barbara Hayes-Roth I copy
Attn PERI-BR (Dr Judith Orassau) Department of Computer Science5001 Eisenhower Avenue Stanford UniversityAlexandria, Virginia 22333 Stanford. California 95305
Joseph Psotka. Ph D I copy Dr Frederick Hayes-Roth 1 copyAttn PERI-IC Teknowledge
Army Research Institute 525 University Avenue
5001 Eisenhower Avenue Palo Alto, California 94301
Alexandria, Virginia 22333Glenm Greenwald. Ed
Dr Robert Sasmor I copy Human Intelligence Newsletter I copy
U S Army Research Institute for the P 0 Box 1163
Behavioral and Social Sciences Birmingham, Michigan 480125001 Eisenhower AvenueAlexandria, Virginia 22333 Dr Earl Hint I copy
Department of PsychologyDr Robert Wisher I copy University of WashingtonArmy Research Institute Seattle. Washington 98105
5001 Eisenhower AvenueAlexandria. Virginia 22333 Dr Marcel Just I copy
Department of Psychology
Caraegie-Mellon University
Pittsburgh. Pennsylvania 15213
Air Force
U S Air Force Office of Scientific I copy
Research Dr David Kieras 1 copy
Life Sciences Directorate. IL Department of Psychology
Bolling air Force Base University of Arizona
Wasb ington. DC 20332 Tuscon. Arizona 85721
Dr Earl A Alinist I copy Dr Walter Kiatsch 1 copyHQ AFHRL (AFSC) Department of Psychology
Brooks AFB, Texas 78235 University of ColoradoBoulder. Colorado 80302
Bryan Dallman 1 copy
AFHRLLRT Dr Stephen Kosslyn 1 copyLowry AFB. Colorado 80230 Department of Psychology
The John Hopkins Univers ity
Dr Genevieve Haddad I copy Baltimore. Maryland 21218Program Manager
Life Sciences Directorate Dr Pat Langley I copy
AFOSR The Robotics Institute
Bolling AFB. DC 20332 Carnegie-Mellon University
Pittsburgh. Pennsylvania 15213
Dr John Tangvey 1 copyAFOSR/AL Dr Jill Larkin I copy
Bolling AFB. DC 20332 Department of PsychologyCarnegie-mellon University
Dr Joseph Yasatuke I copy Pittsburgh, Pennsylvania 15213
AFHRLLRT
Lowry AFB, Colorado 80230Dr Alan Lesgold I copy
Marine Corps Learning R&D CenterUniversity of Pittsbnrgh
H Wiliam Greepup 1 cop, 3939 O'Hara Street
Education Advisor (E031) Pittsbnrgh. Pennsylvania 15213
Education Center. MCDECQuantico. Virginia 22134 Dr Jim Lenin I copy
University of CaliforniaSpecial Assistant for Marine I copy at Sam Diego
Corps Matters Laboratory for Comparative
Code looM Human Cognition - DOO3AOffice of Naval Research La Jolla, California 02093
800 N Quincy StreetArlington, Virginia 22217 Dr Michael Levine I copy
Department of Educational Psychology
Dr A L Slafkosky I copy 210 Education BldgScientific Advisor (Code RD-i) University of Illinois
HQ. U S Marine Corps Champaign. Illinois 61801Washington. DC 20380
Dr Marcia Lioa I copyDepartment of Defense University of California
Director. Adolescent Reasoning Project
Defense Technical Information Center 12 copies Berkeley. California 94720
Cameron Station. Bldg 5Alexandria, Virginia 22314 Dr Jay McClelland 1 copy
Attn TC Department of Psychology
MITMilitary Assistant for Trasinig and I copy Cambridge. Massachsetts 02139
Personnel Technology
Office of the Under Secretary of Defense Dr James R Miller I copy
for Research A Engineering Computer Thought CorporationRoom. 3D129. The Pentagon 1721 West Piano Highway
Washington. DC 20301 Piano. Texas 75075
Major Jack Thorpe I copy Dr Mark Miller I copy
DARPA Computer Thought Corporation1400 Wilson Blvd 1721 West Piano Highway
Arlington. Virginia 22209 Piano. Texas 75075
i-. a -T 4--: .- .. - . o - - -,
-. ' _ . --- - . 3 -T :- - Cl Kr -9- -C '.M - ,,k7 . -. . - -T 7 1
3
Navy Dr Tom Mora 1 copyXerox PARC
Robert Ahlers I copy 3333 Coyote Hill Road
Code N711 Palo Alto. California 94304Humas Factors LaboratoryNAVTRAEQUIPCEN Dr Allen Munro I copy
Orlando. Florida 32813 Behavioral Technology Laboratories1845 Elena Avenue, Fourth Floor
Code N711 1 copy Redondo Beach, California 90277
Attun Arthur S Blaiwes
Naval Training Equipment Center Dr Donald Norman I copy
Orlando. Florida 32813 Cognitive Science. C-015Univ of California. San Diego
Liaison Scientist I copy La Jolla, California 92093
Office of Naval ResearchBranch Office. LondonBox 39 Dr Jesse Orlansky 1 copy
FPO New York. New York 09510 Institute for Defense Analyses
1801 N Beauregard Street
Dr Richard Cantons 1 copy Alexandria, Virginia 22311Navy Research Laboratory
Code 7510 Professor Seymour Papert 1 copyWashington. DC 20375 20C-109
MITChief of Naval Education and Training I copy Cambridge, Massachusetts 02139
Liason OfficeAir Force Human Resource Laboratory Dr Nancy Pennington 1 copy
Operations Training Division University of Chicago
WILLIA S AFB, Arizona 85224 Graduate School of Business1101 E 58th StreetChicago. Illinois 60637
Dr Stanley Collyer 1 copy Or Richard A Pollak I copyOffice of Naval Technology Directo. Special Projects
800 N Quincy Street MECC
Arlington, Virginia 22217 2354 Hidden Valley LaneStillwater, Minnesota 55082
CDR Mike Curran I copy
Office of Naval Research Dr Peter Poison 1 copy
800 N guincy Street Department of Psychology
Code 270 University of Colorado
Arlington, Virginia 22217 Boulder, Colorado 80309
Dr John Ford 1 copy Dr Fred Ref I copy
Navy Personnel R&D Center Physics Department
San Diego, California 92152 University of CaliforniaBerkeley. California 94720
Dr Jude Franklin I copy
Code 7510 Dr Lauren Resnick I copyNavy Research Laboratory LRDC
Wash ington. DC 20375 University of Pittsburgh
3939 O'Hara StreetDr Mike Gaynor I copy Pittsburgh. Pennsylvania 15213
Navy Research Laboratory
Code 7510 Mary S Riley I copyWashington. DC 20375 Program tn Cognitive Science
Center for Human Information Processing
Dr Jim Hollan I copy University of California. San DiegoCode 14 La Jolla, California 92093
Navy Personnel RID Center
San Diego. California 92152 Or Andrew Rose I copyAmerican Institutes for Research
Dr Ed Hutchins I copy 1055 Thomas Jefferson Street. NWNavy Personnel R&D Center Washington. DC 20007
San Diego, California 92152
.- - --' . : . ' ' - • -. .. . ... : - .. .. . . ." . - . . . - . . ,2,. - .
4
Dr Ernst Z Rothkopf 1 copy
Dr Norman J Kerr 1 copy Bell LaboratoriesChief of Naval Technical Training Murray Hill, New Jersey 07974
Naval Air Station Memphis (75)Millington, Tennessee 38054
Dr Williams 8 Rouse I copy
Dr James Lester I copy Georgia Institute of Technology
ONR Detachment School of Industrial A Systems
495 Summer Street Engineering
Boston. Massachusetts 02210 Atlanta. Georgia 30332
Dr William L Maloy (02) 1 copy Dr David Rumelhart 1 copy
Chief of Naval Education and Training Center for Human Information Processing
Naval Air Station University of Californsa. Sin Diego
Pensacola, Florida 32508 La Jolla, California 92093
Dr Joe McLachlan 1 copy Dr Michael J Samet 1 copy
Navy Personnel R&O Center Perceptronics. Inc
San Diego. California 92152 6271 Variel AvenueWoodland Hills, California 91364
Dr Roger Schank I copy
Dr William Montague I copy Yale University
NPRDC Code 13 Department of Compnter Science
San Diego, California 92152 P 0 Box 2158New Haven. Connecticut 06520
Library. Code P201L I copy
Navy Personnel R&D Center Dr Walter Schneider 1 copy
San Diego. California 92152 Psychology Departmeft603 E Daniel
Technical Director I copy Champaign. Illinois 61820
Navy Personnel R&O Center
San Diego. California 92152 Dr Alan Schoenfeld 1 copyMathematics and Education
Commanding Officer 6 copies The University of Rochester
Naval Research Laboratory Rochester. New York 14627
Code 2627
Washi gton. DC 20390 Mr Colin Sheppard I copyApplied Psychology Unit
Office of Naval Research I copy Admiralty Marine Technology Est
Code 433 Teddington. Middlesex
800 N Qnncy Street United Kingdom
Arlington. Virginia 22217Dr H Wallace Sinailo I copy
Personnel A Training Research Group 6 copies Program Director
Code 442PT Manpower Research and Advisory Service
Office of Naval Research Smithsonian Institution
Arlington. Virginia 22217 801 North Pitt StreetAlexandria. Virginia 22314
Office of the Chief of Naval Operations I copy
Research Development A Studies Branch Dr Edward E Smith I copy
OP 115 Bolt Beranek A NewmanWashington. DC 20350 50 Moulton Street
Cambridge. Massachusetts 02138
LT Frank C Petho. MSC. USN (Ph D) I copyCNET (N-432) Dr Richard Snow 1 copyNAS School of Education
Pensacola. Florida 32508 Stanford University
Stanford, California 94305
Dr Gary Pooch I copy
Operations Research Development
Code 55PK Dr Kathryn T Spoehr I copy
Naval Postgraduate School Psychology DepartmentMonterey. Californa 93940 brown University
Providence. Rhode Island 02912
5
Dr Gil Ricard I copy
Code N711 Dr Robert Sternberg I copy
NTEC Department of Psychology
Orlando. Florida 32813 Yale UmiversityBoa 11A. Yale Station
Dr Worth Scanland 1 copy New Haven, Connecticut 06520
CNET (N-S)
NAS. Pensacola. Florida 32508 Dr Albert Stevens 1 copyBolt Beranek A Newman
10 Moulton Street
Dr Robert G Smith I copy Cambridge, Massachusetts 02238
Office of Chief of Naval Operations
OP-87H David E Stone. Ph D 1 copy
Washington. DC 20350 Hazeltine Corporation7680 Old Springhouse Road
Dr Alfred F Smode. Director I copy McLean, Virginia 22102
Training Analysis A Evaluation Group
Department of the Navy Dr Patrick Suppes I copy
Orlando. Florida 32813 Institute for Mathematical Studies in
the Social Sciences
Dr Richard Sorensen 1 copy Stanford University
Navy Personnel RID Center Stanford. California 94305
San Diego. California 92152Dr Kikumi Tatsuok 1 copy
Dr Frederick Steinheiser 1 copy Computer Based Education Research Lab
CNO - OP115 252 Engineering Research Laboratory
Navy Annes Urbana. Illinois 61801
Arlington, Virginia 20370Dr Maurice Tastsuoka 1 copy
Roger Weissinger-Baylov 1 copy 220 Education Bldg
Department of Adm:nistrative Sciences 1310 S Sixth Street
Naval Postgraduate School Champaign, Illinois 61820
Monterey, California 93940Dr Perry V Thorudyke I copy
Mr John H Wolfe 1 copy Perceptronics. Inc
Navy Personnel RID Center 545 Middlefield Road. Suite 140
San Diego. California 92152 Menlo Park, California 94025
Dr Wallace Wulfeck, III I copy Dr Douglas Towne 1 copy
Navy Personnel R&D Center University of So California
San Diego. California 92152 Behavioral Technology Labs
1845 S Elena Avenue
Private Sector Redondo Beach, California 90277
Dr John R Anderson 1 copy Dr Kurt Van Lehu 1 copy
Department of Psychology Xerox PARC
Carnegie-Mellon University 3333 Coyote Hill Road
Pittsburgh, Pennsylvania 15213 Palo Alto, California 94304
Dr John Annett 1 copy Dr Keith T Wescourt 1 copy
Department of Psychology Perceptronics. Inc
University of Warwick 545 Middlefield Road. Suite 140
Coventry CV4 7AJ Menlo Park. California 94025
ENGLAND
Dr Michael Atwood 1 copy William B hitten copy
ITT - Programming Bell Laboratories
1000 Oronoque Laoe 2D-610
Stratford, Connecticut 06497 Holmdel. New Jersey 07733
Dr Alsa Baddeley I copy Dr Mike Williams 1 copy
Medical Research Council Xeron PARC
Applied Psychology Unit 3333 Coyote Hill Road
15 Chaucer Road Palo Alto, California 94304
Cambridge CM2 2EFENGLAND
u - i. ..-. . . . . . ..h. . . . . . . ..ill~lid ll a l l i
" m '' . . d. .. .• ; .. '
Civilian Agencies
Dr Patricia A Butler 1 copyDr Patricia Baggett 1 copy NIE-BRN Bids. Stop *7Department of Psychology 1200 19th Street NWUniversity of Colorado Washington. DC 20208Boulder. Colorado 80309
Dr Susan Chipman 1 copyMs Carole A Bagley I copy Learning and DevelopmentMinnesota Educational Computing National Institute of EducationConsortium 1200 19th Street NW2354 Hidden Valley Lane Washington. DC 20208Stillwater, Minnesota 55082
Edward Esty 1 copyDr Jonathan 8aron 1 copy Department of Education, OERI80 Glenn Avenue MS 40Berwyn, Pennsylvania 19312 1200 19th Street. NW
Washington. DC 20208Mr Anron Barr 1 copy
Department o Computer Science Edward J Fuentes 1 copyStanford University Department of EducationStanford. California 94305 1200 19th Street. NW
Washington. DC 20208
Dr John Black I copy
Yale University TAlE. TIN 1 copyBon 11A. Yale Station National Institute of EducationNew Haven. Connecticut 06520 1200 19th Street. NW
Washington. DC 20208Dr John S Brown I copy
XEROX Palo Alto Research Center Dr John mays I copy1333 Coyote Road National Institute of EducationPalo Alto. California 94304 1200 19th Street. NW
Washington. DC 20208
Dr Bruce Buchanan I copy
Department of Computer Science Dr Arthur Melmed I copyStanford University 724 BrownStanford. California 94305 U S Dept of Education
WaShington. DC 20209Or Jailme Carbonell
1 copy
Department of Psychology Dr Andrew R Molnar 1 copyCarnegie-Mellon University Office of Scientific and EngineeringPittsburgh, Pennsylvania 15213 Personnel and Education
National Science FoundationDr Pat Carpenter I copy Washington. DC 20550Department of PsychologyCarnegie-Mellon UniversityPittsburgh. Pennsylvania 15213 Everett Palmer 1 copy
Research ScientistDr William Chase 1 copy Mail Stope 239-3Department of Psychology NASA Ames Research CenterCarnegie-Mellon University Moffett Field, California 94035Pittsburgh. Pennsylvania 15213
Dr Mary Stoddard I copyDr Micheline Chi I copy C 10, Mail Stop B296Learning R A D Center Los Alamos National LaboratoriesUniversity of Pittsburgh Los Alamos. New Mexico 975453939 OHara StreetPittsburgh, Pennsylvania 15213 Chief. Psychological Research Branch 1 copy
U s Coast Guard (G-P-1/2/TP42)Washington. DC 20593
.- - .t.- . .o. - . *.. - . -.- -. - -" .. o- . . ,".... ... ...... . ".- . .
7
Dr William Clancey 1 copy
Department of Computer Science Dr Frank Withrow 1 copyStanford University U S Office of EducationStanford. California 94306 400 Maryland Avenue SW
Washington. DC 20202Dr Allan M Collins 1 copyBolt Beranek A Newman, Inc Dr Joseph L Young. Director I copy50 Moulton Street Memory A Cognitive ProcessesCambridge, Massachusetts 02138 National Science Foundation
Washington. DC 20550ERIC Facility-Acquisitions 1 copy4833 Rugby AvenueBethesda, Maryland 20014
Mr Wallace Feurzeig 1 copyDepartment of Educational TechnologyBolt Beranek and Newman10 Moulton StreetCambridge. Massachusetts 02238
Dr Dexter Fletcher 1 copyWICAT Research Institute1875 S State StreetOrem. Utah 22333
Dr John R Frederiksen 1 copyBolt Beranek I Nevman50 Moulton StreetCambridge. Massachusetts 02138
- ; . . ... . -. . . . .. .. ...- -..
PROUSTMacIn k er Ultmately PROS beicroae nt rgamn
Re-ink ay fabric ribbon cuculur and provide significantTOM ICALLY for low will incorporated enet e sdents Hrwee have
than 9. Extremely simple given a simplified view of howopermotor ti ioae a programming PROUST finds bugs. The next step iselectric mtor. We h a to build an automated programmingMAC, 1M for any printerf. course around PRO Such aazde/spol/harmonica/ c u fr system would not only correct -u-for dacit pnzreidn dents' mistakes but would also sug-
Multicolored inks. uninked gest additional problems for the stu- _
cartridges available. Ask for nosed or missed entirely. Bugs are dents to solve to give them practicebrochure Thousands of counted as false alarms if they are where they need it. asatisfied customem either not present in the program or
s545. + if they are present but misdiagnosedconsequently, misdiagnosed bugs are AUThORS' NOTE
• 7 counted both as false alarms and as This work v= cosponsored by the Person-not recognized, which inflates the nel and 7ftaming Research Gioup& Psyho-total numbs' Of k c loical Sciences Division. Office of Navalah ber of dialoss erroan Rsearc and the Army Research InL tuteWhen PROUST tals to understand for the Behaviorlal and Sodal Sciences. I .
a ;-VrM completely. il ability to under Contract Number N00014-82-K-eogrize bugs deteriorates: 17 per- 0714. Contract Authority identification
cent of the progrms we analyzed Number Nr 154-492.part0laiy. in such -ase PROUST Additioal papers delig it bug
deleted from it bug descriptions duification autmmatic debugtgmandtose bug analyses that were ques- the cognitive undfPinnng of prwartionable. given hwthe proram was mll am beoedb9WVtitlUothe
onhr artilly nder th e bug following acdres. Cooplti anid Pro-descrcOnS that remained we fr- gaina Piec. Department of Com p rquendy wiog but at lea PROUST __ Yale u H .C' 06520.
hii Swp,-ik~m lt$ 7W Shanwas able to warn the student to te Spcial t GM yr and AT speyor computer with any two the analysis with a gain of salt. The Leszek lzdebswk of CoWsesre Inc andperipherals (.ri or remaining 4 percent of the prorams sret waf:h of Advanced Pocessng for Quad -
p ). de rdeviated from PROUST's expecations their effort in developin MicPROUST Quadrprocessors-never type an so drastcally it could not analyzeaddress twice. Ask us for them at all In these cases no bug in IBMbrochure with tips on how to report was generated. REFERENCES ilfovEshare two peripherals (or two are not wa suffiieny satisfied 1. Fosdic L D and L I. OswreiL Datecomputers) with MAC wtPRUTsacrctomk t '* Sf the pr,SWTCH. Toal satisfaction or with PIOUSrs accuracy to male it Flow Analysis in Softar Riabit" Cow.SWl refund o generally available to students. The pit* SiwW 8. voL 3. 1976. pages cOmpL
99.so false-alarm rate should be lower and 305-330. tTralnsthe fraction of prorams that PROUST 2. Harandl. M. T 'Knowlede'.ased Pro- and W-ag ram Debuggin. A Heuristic ModeL' Pn-aeshoid be h-he. ceedings of the 1983 SOFFAIR. 1-2-3.When part of a program cannot be 3 ,. .--m ype Program Debug- faster
. analyzed. PROUST should try to ging: An Aid for Nov Proramme" Ief determine why that part Of the pro- r ,W JoW of Mm-Mi Stanin 16. before
gram canxx be analyzed and y to 1982. pages 379-392. intertaccount for the unanalyzed code 4. Shrtf. E.H. CNpuivr Me"Once this IS doneeexpectaPROUST Cm 0N New Yark Amercan But be
Order tol free 1-800-547-3303 to succeed on 80 to 85 percent ofthe EJsvier Publishing Co. 1976.programs it analyzes. At t ste 5. Minsk. M. "A Framework for Represent- ~thoa
0 1 ter will make it available t students on Ing Knowledge' The PppMM of Cmptta
F i n sline Viit Wntn ed. New YrlL McGraw price o-Frend Hal .19.8415 SW Canyon Court CoNCJSlON 6. lohnson. W L "intention-Based Diag- and tu
noss of Pfrrmming Error" 'Yae Univer virtatSuite 00 PROUST is capable of high-quality sity Department of Comouter Science.Portland. Oregon 97221 analysis of bugs in novice programs. 1984.(503) 297-2321I" I Y T E APRIL 1985
,.5 . PROUST
ponent that failed to match the pro-gram must be an IF statement The Ustdng2: A cone imalienvnatai of the Bad Input Test pam.Error-Pattern slot has the value(IF . WHILE); this indicates that a WNE V01< 0 00WHILE statement ws fond when an Maw
_rk I nald df -la rewIF statement as epected. These stcondr ons are both met in the ENWHILE4or4F example so the action IF Val <o > M THENpart of the rule is activated. The ac- ..uon part of this rule consists of a Bugslot the filler of this slot is a descrip-con of the bug associated with theplan difference. The bug in ts (Dekw WHLE-orIFcase is a WHILE-for-IF confusion. Simmett IFPROUSTs bug analyses of student &Q FWHLE) Iprograms consist of bug desrpons Bug (WHILE.r4F C (u ,MRsuch as this. When PROUST presnts 04wnK Hscoft))
its findings to the student it takes F 7: T* WHILE.04F bug ride by PR o v d pimeach bug description and generates &&f / tmfau4 Wtof *RW o fgi I W thean English-language tanslation for it kde t of is p.and. if appropnam_ generates data il-lustrating the presence of the bug.
TEST RESULTS (PROUST has been tested on large aPa pouw iip ,uwmptuts n wom em Nnumbers of beginners' programs. Vwe @M n* sonde gr ft awount d min New H~ for a da. NM Sncg reallassigned a class of novice program- cwm be e mn ft u rm nmegiej Wpm Yawivigrem shouidmers the Raia Problem (an elabot- ft bfm ig sducd ham n o .don of the Averaging Problem). which ich mep ri w '
is shown in figure 8a. Z m be r d ra& dWe modified the Pascal compiler I e number d lid M"p o kmk aninvolid dmew mW have been red in)
our students were using so that it 4 ft modum avnot d ren IM MOon any neOWwould save copies of every syntac- Thepm-en **Ad 'dfmt ud em user tyM 9ms a a trilv a n signa-tcally correct prgram that they corn- ing e endd inpt 00o n i lu ete g in e ecaulor Am,mg wift' mepiled. This allowed us to examine not uA V&VA a nongaft 6nd n eud to NS, Uwn it is ,id inpu tMonly the final solution the studentshanded in. but also every inter-mediate version of their proarn'.Since the first versions are lilkely to be loW numer d eat 206the buggiest this let us test PROUSTunder the most difficult conditions N at S wii bug 163 ( epossible Nube at progiam raceiving fu ante 161 (79 perci
Figure 8b shows the results of run- Taw nume ot bug& s5nin PROUST on the Ra*11 tlPmoem. Bug$ reco le 0=40. SM3 %4 poem K)There are 206 different attempted l se 9 (6 esolutions to the Rainfall Problem in Nuaner at p im in p u s 35 (7the test set. Of thse. PROUST was Nu mbe bdiqable to derive a complete understand- TOW nu mb er 1 (d7ing of 79 percent of the programs. Bup dleed frwm w*= 70 ('3 pinceiidentifying 94 percent of the bugs. a up 'U mxogni: s0 (26 pewS)percentage far higher than people are F o 19able to achieve. The chart also in- Numer d pogrmap POUSr r d naU s w 9 (4 pit=dicates that 6 percent of the bugswere not recognized and 55 were Figure 8: (a) The Rainfa PmbLm %a ine to a das of. ,ovice pgmn tofalse alar. Bugs are counted as not tM the rffEuiW of PROUST. (b) This sh the rmu of running PROUST onrecognized if they are either misdiag- f R aif Pmb,.
APRIL 1969 • BY T 9 "r
PROUST
_ ic R U Tf~ predkmt matches the program. When potnS~~~~ince PROUST first ma . e . en- othis happens PROUST must look for gr'am -busat account for the mismatches Error-P
gennates a possible of the plans In this section we (IF .Vvwill dics one of these mismatches WHILE
implementation and in cn.ton w e WHE-f4F IF saeexample in figure 2a and show how conditi,
then matches it it leads to the discovery of a bug. WHILEThe bug In the WHILE-for-IF exam . --. part of
pie is discovered in processing the - tion parM,__________goa._nefheplas__. slot-tht
that PROUST suggest for implement- - non ofit is performing Ing this goal is the so-called Bad in plan d
put Loop Tog plan. This plan cons= case isanalysis by synthesis of a WHILE stmenth teM the PRous-a. input to see tf it is out of range an prograr-
error message inside the WHILE loop. such asprocess that it went through in sek%- an Input subgoal that rereads the in- M find:ing the Serntnel-ProceRadAWhile put if it is out of range and a test to each btplan. It first substitutes all paten see If the exit condition for the main - an Engivariables In the goal expression that loop has been satisfied. and. if ahave bindings Since ?New has Val as Listing 2 illusmtes a correct Imple- tustratira binding, the subgoal expression mentation of ti plan (solving thebecomes (Input Va. PROUST then Averaging Problem). - TEST Iretrieves plon on the plan The Bad Input Loop Tot plan PROUS"that Implements Input. One such plan matches toe WHILE-forF example of - numberis the READ PLAN. which employs a figure 2a in all but one respect there assigne'.Pascal Reed sttement to input the Is no test for the exit conditon of the mers d Ivalue. This plan matches the Reed main loop. such as IF VW c > 99999 - on of tst tements in the program TH-EN ... - where an IF sttement is show
This example shows how PROUST is expected a WHILE tmtement ap- I;* manalyzes programs by predicting the pears tnsteud. PROUST his thus en- our sruplans that might be used and then countered a Oa dffmm ie. a dif- would crallm these predlcn By selecting ference between the expected plan ically ccfrom a range of different plans and and the code. When PROUST en- piled. T'subplans for each goal. PROUST is counters plan differences it does not only .htable to generate a variety of dfferent give up on the plan: instead It tries handedways of implementing each goal. to find a way of interpreting the plan mediate
. Snce PROUST first generates a pos- differences as bugs. Since d-sible implementation and then In most cases plan differences are the bugmatches it against the program it is explained by means of buo res Each under t.performing analysis by synthesis. in bug rule has a test part which ex- possibligeneml. generating plan hypotheses amines the plan differences to see Figureand matching them against programs whether the rule is applicable and an . ning PRCis rather more complex hua the action pam which explains the plan There ascenario presented here. for more In- differences. solutionformation, see reerence 3. Figure 7 shos the bug rule that is the test
invoked to explain the plan dif- able to c.31647 IDENTpYiN BUGS ferences in the WHILE-for4F exampie, ing of 7
When the Serifner c-PPc Read- The rule is written in slot-filler not- derify! WhdO Plan was matched against the tion: one set of slots constitutes the ' percen
program in figure Ia. the plan test part of the rule and another set able tomatched exactly. Since there were no constitutes the action part In the - dicatesmatch erroM there must not have WHILE-for4F rule the test part con- were ncbeen any bugs in that particular plan. sists of a Statement-Type slot and an Y false ala:It Is frequently the case howeve, that Error-Pattem slot The Statement- recoraznone of the plans that PROUST Type slot indicates that the plan com-
I Yr T I APIUL I049
PROUST
PROUSTsubstiuts "Ille, is a list of five items: Sentnel- PROUST simply replaces ?nput with_____ ____ ____ ____ Proc9 sReadWhila Sentinel-R ad- the variable name ?New PROUSTProcest-While Sentinel-Read- assums that the process of match-any obl~cb whoseProcass-Repea. Sentinl-Prcice ing the plan aganst the program will
Reed-Repa. and Bogus-Cbunter- determine what the value of ?Now is= [,
values are already Cor dolLoo E t Fie 6 shows how the Sentinel- I m.name of a plan. PROUST selects the Process-Read-While plan is matched 7Zw Uf
f plan fo th it.,emnl against the program example in figure2W OR:2kown into the NN I, fi."
Procesa-Read-Wh This wil be Ia. Matching starts with the WHILE , amSSVE11
PROUSTs initial hypothesis of how loop. The pattern in the plan for the . mqim PI & To-goal expression. the program implements the goal WHILE loop ir(WHILE (< > New -AK2Sentinel-orarolled-nput 99999) ... ). There are two WHILE NCB ow
Justasknownvaluesofobjectswere loops in this progranm: WHILE Valobjects whose values are already substituted into the goal expression < > 99999 DO ... and WHILE Valknown into the goal expression. At (Sentinel-Controlled-Input ?New <a, 0 DO ... PROUST tries tothis point the only information avail- ?Sentinel). these same substitutions match each pattern against each ofable about ?New and ?Semnnlis must now be performed on the these statements (WHILE (< > I
what appears in the problem descrip- selected plan. b see what subdtitu- ?New 99999) ... ) matches WHILEtion. There the value of 'Sernl is dions must be made PROUST ex- VK 99999 DO .... provided j -.
listed as 999,but the value of ?New amines the Form slo of the deflntion that Vl is substitued for New. . , , .V ais not listed Therefore the value of of SernWl ontraled-7Anut(Senlne- (WHILE (< > ?New 99999) .) 000006mI?Sentinel is substituted into the goal Contrled-Input .lnput ?Stop). The does not match WHILE Val < a 0 DOexpression. but ?New is left un- Form slot klcates which pat-ai ... because the stment has a <- 11,AMaW,changed. The resulting goal expes- able names am used in the plans that test instead of a <> te. and --. 0 Wx
sion is (Sentinel-Controlled-Input implement the goal. By comparing because it ta against 0 instead of -- w,?New 99999). the Form slot to the goal being 99999. Therefore PROUST selects 0-.IC di
PROUST must now mtrieve from its analyzed. PROUST determines that WHILE VAW <> 99999 DO ... as .programming knowledge base plans each occurrence of .Anput in the the match for the plan pattern. Since a1"that could be used to implement the selected plan should be replaced by Val must be substituted for ?New so U .goal Sentinel-Controlled-Input. It the value of ?N Each occurrence that the pattern matches. Val is memo.,,,.retrieves the filler of the Inuancs slot of ?Stop should be replaced by the recorded as the binding for ?New b.ew ' ,of the defnition of SentineWCon- value of ?Sertnel or eem Because Aftrw any component of the plantrolled-Input shown in figure 4. This the value of ?ew is not known, that has ?New in it will have Val sub- ?tCS-" a
stituted for ?New. I W' - M
The next plan component that ! Or -0.-- PROUST matches against the program
vA=d V11 is (BEGIN ... ). There are several dif- a OTUferent BEGIN statements in the pro- A "Woo,111c
SftJCt'S P011 gram that could be matched against W" LsU 4, uthis pattern. However. in the plan tern- MW oo" O,.s
wk -E) (yaw. t plate the (BEGIN ... ) pattern ap.R~emo V l). ((5UBGO AL (hW ?bWA)" 0 o ,W*LE Vii< 31-99 O 0 (WHILE (.co 'np 9 pears inside of the WHILE pattern
SEGI 1 (BEC,* that was lust matched. This means am S,. ts"-v-< 0- that the BEGIN statement that this UM f:
16014 n(SUSA (np pattern matches must be located in- MUS Wpm;W000 invldSiw. to ~r side of the WHILE Val < > 99999 Cm mC t4. C118 Va l DO ... satement. Thereform there Kl 5,1,0 Doe,
Sur" Su + A N is only one BEGIN staement that has a "MM 'C P9.
Casn:. CauM+I; an appropriate match. I sew,,ay iswrRI(4 'ER va". r' > 000e When PROUST tries to match the m p " (CRem vI r.N1. o PI N (SUBGOAL (input ?New)) com- a ,
ENM ponents, a different type of process- i(Rw V1) ing is required. These plan com- VO** ,01
ponents are goals: to match them "'m ", c..
FIgum 6: This Ahoww Sentinel-ProcesRead-While , is m against the program. PROUST must S 4,0wotars * ipop in v I. go through the same plan-selection
• .- .. .. ......... .... .. ... ... ;.. .: ,,.: ,:,. .,'
-- ~T cat f. of-----
PROUST
problem descriptions Plans are MainLoop:.. New. etc. These slots Controlled-input goal. This plan is astereotypic methods for implement- serve various functions only some of simplified version of the one PROUSTing goals. A large part of wriing Pro- which we4will discuss here The most actually utses Plans are also definedgraims consists of identfying goals imipomnt slots are the Instances and in trms of slots and fillers. The mostthat must be satisfied and selecting Inswicet slots. The Ins cs slot important slot is the Template slot.plans to implement these goalL list the various plans in PROuST's which describes the form the PascalSimilanly. PROUST retrieves plans knowledge base for implementing this code implementing this plan shouldfrom its knowledge base for each al goaL This slots filler is a list of fl take. Plan templates consist of Pascalreferred to in the problem descrip. items each of which is the name of statmenta subgoals and labels. Thetion. It compares these plans to the a plan. The InsanceOf slot indicates Pascal statements are written in liststudents program to detnine which the class to which this goal belongs. notation rather than ordinary Pascalfits the program best. The goal clas in this case is Read& syntax for example the form (WHILE
Figure 4 shows PROUST's definition P.c -which is the class of all goals ( c> Input 'Stop) ...) in Pascalfor the Senol-Co tiled-Input goal. that involve reading a sequence of syntax would appear as WHILE In-The oal definition contains a series values and processing then put < > ?Stop DO .... Symbolsof slots: InstanceO. Form. MainSeg- Figure 5 shows a plan. the Serifnel- that are preceded by question marksment etc.. together with fillers for PmcmsRead-While plan. This is one are pattern variables: these are sub-each of these slots: Read&Proces of the instances of the Sentir - stituted when the plan is used. "New
is substituted by a Pascal variable con-tamining the input data. and ?Stop is
(MMIwnPmv Am .. sulostud by a consnt. the sentinel(Puins.bs 7 v value The ? stmement is a "wild(Ohmwn'o gkofto . makid~ra ?Now ?e3u'V card' pattern that can be substtuted(mneow pui-vtw ?No (c - Me 0 by an arbitary sequence of Pascal
4W (Ou* (Avmw 7N)"D . statements: this is just a placeholder... . in the plan. Subgoals am indicated by
Figure 3: T1vAw ao Pnle &lst110 be PROUST's D (SUBGOAL ...) forms in the tem-plate' these ae poals that must in turn
___be implemented using other plans.
MATCHING PLANSP064)Ouw SOONWLet's look at how plans and poals are
Form0111_6_ ?_ used to understand a program. TheG plan in listing I has been imple-
MaVus m, e. rnented correctly. You will see howN wespt *'Mftw=1 0 bw* PROUST hypothesizes a plan that theOmuCaiva~ T program might use and then matcheslftft1&S this plan against the program. In this
S• case the match succeeds because theS ,i OI-P U. plan is implemented correctly. In the I
kpmcouu m~oa-ed. oop)m- ) next section we will examine whathappens when plans fail to match an(
Figure 4: 1*~ ddgm of * #WL Seinel-Controlled-Input in PROUMts because the students code has bugs. plus~, 'The first stm. before any analysis of And
goals and plans takes place, is to letsparse the students Pascal program whiThis results in a parse tree All subse- mc
(.o ...,.,, ,- ,"-,quent analysis of the program is per-CA~nnnm Vftm formed on the parse tree rather thanT& ((5I uoo. (en 7 on the original program text.(WL.E (<c P ?• M When PROUST analyzes a program.
MEGNit selects poals from the problem?" description one at a time Let's sup-(SUBAo. OGA ("Mi 7If)P pose that the goal that is selected first
is (Sentinel-Controiled-Input ?NewFigure 5: A pla kor ipkm&q4 e 9W Smntineiol-CO0I0d-nput ?Sentinel). PROUST substitutes any
14 BYtrg.A• 19 lq*lI 216
- , . . .: -" . - ", - +* + _ , +
PROUST
mon bugs to see if itcan explain the Goal statemntnsconsist of a namediscrepancies Listing 1: Yetmotlir wW w ofatype of goal. followed by alist of I 1
PRtousrs Pinosin Ui9IIUI the UIFw VIamM for th arguments. ith fom(AverageAm%*g Pmlm ?New) for example Average is a typm
DESCR~fMSof goal (to compute an average). andProblem descriptions in PROUS cortke steagueto h ol5SW of rwgwamminia galsI and sets of WHILE V 00T is arueto the goal.
muaojc rgamiggaste BEI compute the average of ?Newthe principal requirements that must d MNX rasur'); Arguments to goal expressions canbe satisfied sets of data objects are R"Vlytakrea variety of formns. They can be - .Sthe data that the program must obe= predicates or even other goalWHILE Valc), 009
runpulate BEGIN expressions. In the expression (Input-The first step in translating an Sia:. Surnf Validgibon ?Now ' -?New 0)). one
English-anguage problem statement Cauet:0 Coat.1: argument is an object (?Nqw. and theinto PROUSrs problem-dlescription Wnr SM gw'); other is a predicate ?New < = (Iinlanguage is to make the various goals PAW VdLS)unto amsadoprtrthat are mentioned in t problem BGNprecede their arguments, which is why -
staemnent explicit Recall that the text WMW *nw ,, wv .f the -C- precedes the ?New and 0 inof the Averaging Problem is the RS.MIX % the expresson (< =0).if goals arefollowing: END; nested. as In (Output (Average
ft a -program that reads in a se- ?Now). the outer goal refers to thequeneofposiivenumbrs.value computed by the inner goaL.
quenc ofpuitverube sop
ptgs e is ieadn expe GThus this goal requires that the pro-the average of these numbers. Do Igam output the average of ?New.
______________ in this example PROUST's problemnot include the in the___BsoNa descriptions are a reasonable approx-
ar dei X U SI M ?matlon of the original Engishlan.
Sltosto this problem operate on Define-Goal statements. problem descriptions describe whata sequence of input data let us cal Object names are preceded by the proram must do but not hothis sequence Neow me following question maums. There ar o obect they ar supposed to do it. PROUSTgoals can be extracted from the prob- defined in the Averaging Problem must analyM each individual progamlem statement description. eratinel and ?Now e and dermine how it is intended to
adof Now qson-mark notation Is used fre- satis the problem requirements.sTe ein tanse atin vae alu queny in artificialiinteigence (Al,stoping hn a sentnele ve. programs: it indicates that the vat- PROGRAMMnIG K MLedeSP Uretat ondition able is not a literal value but is a Programming knowledge in PROUST
0 akae s t aethe codton Nowl :e 1) S uao ae n prtr
0 ais never t e parameter that must be substituted Is frame-based (see reference 5). Inwhen the data structuire is used. For frame-based systems knowledge isCopuet e .theat thr~e New exampl the input-da m object ?New organized into frames, each of whichO hwill be substuted with the name of corresponds to a Particular concept
ftw must now take these goals and the Pascal variable that the student that the system "know aboutuse them to generate a problem uses for storing the input daa. The Frames are similar to records In rela-description for PROUST Each data object ?Swtinel has the value 99999: tional databases. although the opera-object that the goals rife to is named wherever ?Senel appears In the tions that can be performed onand decmad Each goal extracted problem description it can be sub. frames are somewhat different.from the problem statement is re- stituted with Knowedge in frames is organized intocorded in the Problem desipn Objects can be ether constant- slots which function as record fieldThe resulting problemn descption is valued or variablevalued. In this ex- names. and fillers. which are theshown in figure 3. ample ?Sentinel is a constant with values assigned to each slot
Lik all the data structures that we the value and ?New s a The two kinds of programmingdiscuss in this article problem variable In PROUS's general prob- knowledge that we will consider heredescriptions are in list notation and lem-desciption an g objects can are goals and plans (other types ofevery statement and expression is have a variety of properties asso- programming knowledge are i.enlosed in parentheses me name of dared with them, however we will not cussed in reference 6). Goals aret Program is indicated with a use any such properties in this sim- problem requirements that appear inDefine-Program statement Objects ple example
APIIL 1011 * SYTIE 65 ii
9999. i mtp'ms:it ndictestha thevar- POGRAJ NOWEDG
• ae u t.the-------- Ne a -l i s- .]iem .au .u is a amn nweg nPOS
PROUST
Data-flow analysis checks for dear hand out to students. mon buganomalies in the pattern of data To understand the studeng pro- discrepardefnon oruseof dam a ICRO- grams. PROUST also needs to knowgram. It can determine when a vari- how to solve the problem. Solutions PROUSable is defined and never ue PRO UST to a given programming problem may DEsciFfwhen a variable is never defined. be implemented in a variety of dif- ProblemHowever. if there are no anomalies in Pferet was, Sppose that there was sst of prcdata flo. oam-flow analyss will not THE IBM PC only one way to test input for validity daa objedetec any bugs. Neither example in mi-PROUST is a subset of de in a Pascal program. namely. to insert . the princthe preceding section has dau-flow M larger Implementation of a WHILE loop at l top of the main be satisfi-dnes. th is b eho woul.d nt i caplee of dealing w loop. such as in figures la and 2a. the datadetect the bugs aimited =ige of novie pmins and Once PROUST knew that a program a
You might also try analyzing the is oved 9 up o hanle only tse must validate input, it would know to m The fir
structure of the proge am itset f to sene o ample solutons to the Averagng look for such a loop, as well as for the English-la'whether it suggests the preerry of and abinal Problem provided with it sentinel test that must follow. How- into PROIbugs You could build a library of MkPo-PROUSr runs in Gold Hill Coin- ever. there are several ways of lanjuagetemplates for common bugs. such as pumis Inc. Golden Commnon nsp validating input. Listing I shows a that are rmissing sentinel tests or WHILE an IBM Personal Computr with 512K iop that tes input in a different way. rtement
statements inplace ofIFstatemen, p re availablefor Instead of there being one input of the Aand then match these templates i 1 1- 9 fromIvalidation loop. there are two: one is following.dowloadin from BYTFnr Liminrsagainst the program to identify the The telephone number is (6031 at the bottom of the loop and thebugs, The problem with tf approach 924.9820. e - other precedes the loop. No adi Wite a .
is that you have no way of koing ains diecons on how to run Micro tional sentinel tes is required when quence c
where to match the bug templam in PROUST this method Is used. because as soon p
the progam. For example the as Input is validaed, control flows to the averaWHILEfor-IF eample has three dif the main exit test of the WHILE loop. not ind..
;erent WHILE loops How could you nia (see the text box Mlro-PROUSr Therefore. without kowing what averagetelt which W14ILE loop ready shoul for the IBM PC" above for more infoe' method the programmer is using for p that.be an IF statement or if any of them maton). Mico-PROUST is capable of validating input -PROUST cannot tell Solutions tshould be an IF statement, You could recognizing the kinds of bugs ta are whether to look for a sentinel test a sequencitry to maim the bug template more described in this article. however, within the body of the loop. In figure this sequespecific by making it apply only when there are a variety of tricky bugs that la it is an error not to have such a sen- goals can hthere are two loops with the same exit PROUST can identify but Micro- tinel test, but in listing I it is not. lem staten-test. one inside the other. But that PROUST cannot. (If you are interestd PROUST needs knowledge about pro-would make the template too specfc: in PROUSrs full diagnostic capabili- gramming so that it can understand * Read sucit would not apply to other cases ties. consult reference 3.) how each student designed and im- stopping •where WHILE statements appear in- PROUST's analysis of programs is plemented his or her solution. Once 9gagesurstead of IF statements. based on knowledge of the program- It understands the programmer's in-
All of these approaches to debug- Ming problem. Students may solve tentions. it can then use knowledge < 0oisuteging attempt to identify bugs without the problem in a variety of ways and about common bugs to identify them * Couteany understanding of what the pro. their program may have a variety of in the student's program.gram is supposed to do. and any such bugs. but they are all trying to solve PROUST analyzes programs by syn- Ve must rapproach does little more than make the same problem. Knowledge of the thesis When PROUST examines a use them •guesses as to what bug is involved, in problem makes the variability of program it looks up the correspond- descriptionorder to do better. a debuggin sys- novice solutions more manageable It ing problem description in its library. obiec:t that 6tern has to be able to infer the pro. also provides important information it makes hypotheses about the and declaregrammers intentions and relate them -about the programmer's intentions methods programmers may use to from the p,to the code lb proide PROUST with des :p- satisfy each requirement in the prob- 1 corded in tr
tions of the programming problems. lem description. Each hypothesis is a The resultin,PROUSIs APPwAca we devised a problerii-description possible correct Implementation of shown in fi!_PROUST is written in T. a dialect of language Ae described each problem the corresponding requirement. If Like all th-eLISP The full system contains roughly in this language and provided one of these hypotheses fits the stu- discuss in15.000 lines of LISP code and runs on PROUST with a library of the descrip- dents code then PROUST infers that descriptionsa VAX-I 1/7 50. A stripped-down ver- tions. Each problem description in the requirement is implemented cor- every stater.sion called Micro-PROUST has been PROUSrs problem-description lan- recty. If PROUSIs hypotheses do not enclosed in pdeveloped in conjunction with guage is a paraphrase of the English- fit the student's program, then the progra,Courseware Inc.. of San Dlegm Califor- language problem statement that we PROUST checks its database of com- Wrie-Progr
183 Y T ' AL 11t9
+ . . i.?? i . . . - . . . . . . ... .. -. . .. .: - , . . . , . - , , , , ;
PROMS
~. liately _ ment arnd does not understand howxethe the corol flowin a WHILE loop Iipt for wa As e~long a th body of the I PRO" k~ k" OuU When loop is straight code. the student 2 WA Sumn CouMa %%L AS FMAL.IMnMe hurso; ro -ni Hevr.1Vthebody -3 BEGIN
-"re - d the loop conft anthestudent ~5 Courwf 0.* 5-& thinks that thusshd bewittenl 6 WO Vain tom'* when as WHILE statements to ensure that ri PAR ).
!r the-n they repeat when the body of the a WHILE Val UU0~rhn~loop donst wilreferto this mis- 9 BEGIN
ogram ccptohencefcthasthe WHILE- 10 WHL NWam0 00,but for-IF misconception. PROUST's out-
))/2or 12 VSN Ind we iry. ri21 2talm themiconception into ac- UED39as - count and explains it to the student 1 WIE V- z91100
5. 5 The bugsIn figureslI&and 2&lfus- 16 BEGINie pro. amethe following points.First. bugs 7Sei-Sun~
* input- hequently cannot be detected If Isu Caat *M COMas.1,ltdon't kutnow what theprogralmisrip. 19
is loop ~ ponedto do, Bothodfthe progrnm 21 __
otveshown run no mate what input is 22 IMositive, reed: to deteine that thereis a bug 23 IFCoua-0uIMc~ ontrol you mut recognize that the poans 24 VIMN Nd odrse)
DHow- output different results than they 25 TM EIvthteshould Bs suchi as these are not 26 AQ :a SfLrrcauW
inu.27 - bAuuI 71mg wnPV*Q).input- uwsal: the mising sentinel-tst bug a END;
current occursin Is entOfnoice Pro- -. 9 EEIn this g pamme%' solutions to the Averaging
nriff- cton evifcte programmerne Px&ca
Aatrater cnase In uson ha nor ic We~ 2:g (a e lnow your popuee w i ip it ac m iNwiitlprobaly r not unedwy p o tet In) TMUS More in quese it-~e
pu e-team f beaueh e or ms apects E Va- 3oMM 00 ... ~ i!s bg diferetfntion ni thrammrtet
D ways:g ouheu cam thqeto, eo hwl iu e ro)pune ism Incorrec a d w ti happf en req ir
bug in -i suggesting bugs that might haoe edge about what the output shouldIcure. if AT NTVE1 caused the faulty behavior (see refer- look ftI. Since the WHILE-for-IFex-
* med by IS 15a DM N pN4M DEBUGING once 2). This approach trasdebug- ample fals to test the input for validi-3 e value '6 b support our claim that debugging ging as similar to medical diagnosis ty after the first positive value is read
re. Thus ' require ktnowledge of the program- (see reference 4). The faulty behavior it appears that this program is miss-average . ~mes Itentions, we will examine the can be thought of as the sypiptoms Ing an input-validation test. it is only2-2. principal alternatives to intention- of the progrm, and the bugs can be after Inspecting the code that it
based debugging and show why they thought of as the diseases. There are becomes clear that the bug is not inas. the fall short. The methods we have con- two problems with this approach: A the input-validation tes but in the sen-
the sen- sidered are analysis of 10 (Inputilout- prorans symptoms cannot always tinel test-U in the put) behavior. analysis of dae flow, be determined and these symptom Another debugging approach youinstead . and recognition of pattern of buggy cannot always be related to the bugs. might try is date-flow analysis (se
nt prob- code. The bugs In the progrms in figures reference 1). This is the approachxo At the Debugging by analyzing 1/0 be- la and 2& affect the output of the pro- many erro-hecing compilers use.
o somat e&-havi Involves determining when te gram only occasor~aily: recognizing WMW
APWI9S.3Y5 tM1
I.t
PROUST
grammers intentions assists debug- Vite a program that reads in a se- bug. if you type 99999 immediatelyin4, we will present two examples of quence of positive numbem stp- after typing a nonpositive value the
"buggy" programs and discuss why ping when 99999 is read Compute program will continue to prompt foralternative approaches to automatic the average of dse number Do data after the 99999 is read. When 'debugging fail to identify such bugs. not include the 99999 in the aver- the program finally does terminatThen we will describe how PROUST age Be sure to relt any input that the average will be incorrect. For ex- -
ammna ngzes such proTa pnauy we is not positive s ample suppose that you input,.= ,.' will present some statistics showing 999.instead of terminatingi when'"-PROUSTs performance on large The studers progr'am must compute the 99999 is read. the program re-
-"":numbers of studenw solutions to a the iveage of a series of poitv quests another input. If th user thentypical assignment In an introductory numbers, It must ensure that the in- entered another 99999. the programprganigclass.This will help P- put to the program Is in fact poii would not print the average as 5. but
port our claim that PROUSTs ap- The input terminates when a specific Instead would print (5+99999)2. orproach is adequate for the majority value-99999-is read. Values such as 50002.of novice programmers' programs. this. which signal the end of inputL are The program interprets 99999 as
called smtii wvuum data when the sequence 5. -5iExAMPLES OF PROGRAM BuGS Figure Ia shows a sample solution 99999 is read because when the pro-
0 -Here is a simple programming prob- to the Averaging Problem. This pro- gram reads the -5. it enters the input-lem called the Averaging Problem: gran works except for the follcwing validation loop, which starts with line- _ __1 I0. WHILE Val < w 0 DO This loop
is intended to iterate until a positive-, 1ua ,al - value is typed in: 99999 is positive.
I . -. IAM Avwe(w W4M, ouW); so when the 99999 is read. control2 V, REAL Su Count. Vop. vgR-3 BEGIN leaves theE~LUEU iptvi dat lo. Hw4 a M ever the program was written with the5 Cam:m a. assumption that when the input-.. e wIMN 'nenw vsk:' ); validation loop is exited, the current7 11011 Val value of Val is valid input data. In thisa WnILE Val 911o case. Val is not valid data: it is 99999.
the sentinel value. The loop never-.- -W E - 0eless processes 99 as If it were12 BEGI N , data. To guard against this case ther -
-13 Reg Va should be a test for the sentinel after1 EN; : -the input-validation loop.i- s Sum :. a, + VOL Figure Ib is PROUSTs output de-16 Court ; Court +1; scribing the missing sentineest bug.17 wmn Enie o'm The error is described in two ways:1s 9go Vl First it is described in English: ten_. 20 FECN >0THEN PROUST generates an example of21 Wrain( 'No ese m ") data that causes the program to fail. "22 ELSE BEGIN Now look at the program in figure..- v23 Avg:- Suou 2a. This is another solution to the
. .he evenige W nWM Av)o Averaging Problem, and the bug in25- END; this program is also fairly obscure If* 4 '28 END. you type a positive value followed bya negative value the negative valuewill be included in the average Thus
Rj s If you type -2.2.99999. the averagewill be 2. but if you type 2. -2,
Yors uol.mn yor progif winl U it a W a 99999. the average will be 0.•JUnlike the example in listing Ia. the7o m ie. ef Isomng uamyourpmuun: programmer has not left out the sen- -7,
____I tinel tet but has wrtten the t mi theFigure 1: ) Oe w p mmer's aMoaib.pt If * Awwq form of a WHILE statement instead
pPl. PROUST ovio the bW lhrkiq im th prm i i omwe EV of an IF sttement. The student prob-.N.s r8 W, Ol di Wratiug te ar, ably has a misconception about to.... distinction between the two stm-
M IYTEL•AMRIL19S5
* Ki:
I
7--
A.R.T-I.F.I.C.1.A'L I.N.T.E-L.L.I.G.E.N.C.E
PROUSTBY W. LEWIS JOHNSON AND ELLIOT SOLOWAY
An automatic debuggerfor Pascal programs
"PROUSI! Program Undemander for vwWft of bugs In beglinnu pro- the program is supposed to do. theyStudents) is a edg dys- gra If a programmng problem is only analyze what the progam actual-tm that finlds nonsyntactc bugs in ass to a clas of 200. the ly does wee references 1.2. and 3).Pascal programs written by novice students will wrlme 200 diferen pro- Figuring out how a program Is sup-p p.mr When students =on- gram (assumilng that they do not posed to work is riot easy: to do it apile a program successulD. PROUST chst). There is variability both in their debugger requires Information aboutis automnatically Involsd to analyz It programs' designs and bugs. Somie the programming problem and knowi-PROUST reports any bugs that are In ---tug such as missing variable hi- edge about how to write programsthe program to the studem tiafizations an accidental omissions Nevetheless. identying the program-
- PROUST is not merely a tool that that am be wil recognied mid cor- mers intentions is worth the effort.helps programmers find bugs. nor is rected. Other bugs result when the because this knowledge makes itit confined to a narrow dass of bugs. programmer tails to reaon through possible to identify more bugs as wellsuch as uninitialized variables. It is the Interactions between corn- as to understand their causes.designed to find ary bug in motponenta In isolation. each piece of 1b show how knowledge of the proobegmner. programs. PROUST is cur- the program may appear correct. but lMudretly capable of coe* identhying when combined the program doe t w mws m w,,m 1 28. Y*S i,.all of the bugs in 70 percent of work Still other bugs result from New Ham. CT 06520) Is a ,wswchthe program that students write m isconceptions about programming. , Yak He An a BA., fromwhen we assign them moderately The code may appear orect to the Priuw Uxkwsdy ada Ph.D tm Yakecomplex programming problems. programmer. but it dosn't do what Umws4 His ilk or tilWd in-When PROUST fids a bug. it does he or she ope for mosm he or Wp. oa ,n vmgbiurq. mmW.jiiwnot simply point to the lines of code she does not understand Bugs result- ad vnsirm. Dr. iM An b"th.a wwrng: instead it determines ing tram misconceptlons .rehemoat purum m h iR arifuI iat .at
S '"how the bug cn be correctd and serious: students stand to Went the Yak sh 1978.suggests why the bug a in the fitrt most from having such problems EM Sue (D n of Computepla. Our aim Is to build an Wtruc- pointed out to them. Sliria. Yak UmwRr. New His". CT•oal srowe around PROUST that ff a debugging system is to cope 06520) is im pmfu et Yak Heasigns programming problems to with the various types of erroi that Ima LA. In pi wWdWaW a P.D. i w-uWdern rsds their work. and gives programmers make it must under- puhar scunc I th Umwhftty ofthemhelpful h sggeion stand what the programmer is trying maisachsm i AMst. Dr. Suwqe
In designing PROUST we found It to doL Debugging systems usually b@@s a pw at Y d Ie * q sluiknecessary to deal directly with the don't concern themselves with what cputiMw wmmnp of pmmmu.
APILI *IYTE IM
• ~~~~~~~~~~~~.................,....'.......... ,+,_ • . . . ......... ................ ... . .", ,.'.
Micro-PROUST Code Page 2
2. PROUST/Micro-PROUST: From BYTE Magazine
Micro-PROUST Code Pg
1. IntroductionIn this document we present the inner workings of Micro-PROUST. Our intent is to enable
those who so are inclined to see at a nuts and bolts level how a system like PROUST actually
works. We reprint here a paper on PROUST/Micro-PROUST that recently appeared in BYTE
Magazine that should provide a good overview of the operation of the system. Next, we present
the design document that was used to code to Micro-PROUST; the actual implementor of Micro-
PROUST found this document thorough and comprehensive. The third document is a
preliminary comparions of the costs/benfits and techniques employed by PROUST and Micro-
PROUST. The actual LISP code follows these papers.
Micro-PROUST was written for the IBM PC, in Golden LISP. This version of LISP is
available from Golden Hill LISP, Inc., Cambridge, Mass. Micro-PROUST requires 512K to run.
The source code for Micro-PROUST is available on diskette from us for the cost of the diskette
and handling; those interested should write to the Cognition and Programming Project, Yale
* Computer Science Department. The source is also available on the BYTE network; please refer
to the article on PROUST that appeared in BYTE for information on how to download the code;
that article is reproduced elsewhere in this document.
We are currently porting Micro-PROUST to the VAX in order to convert it to Franz LISP.
Thus, we plan to distribute the source to Micro-PROUST on magnetic tape; again, if you are
interested in receiving Micro-PROUST on this medium write to the address given above.
As noted expressly in the code itself, we, nor the actual implementors make no promises for
Micro-PROUST. While we are pleased with Micro-PROUST as a demonstration vehicle, we do
not guarantee that it is bug free. We would, of course, be interested in receiving bug reports.
Moreover, their is no additional documentation for the code that is not included here; that's all
there is. Good luck!
ABSTRACT
PROUST is a system that can identify, for a class of moderately complex introductory looping
assignments, the non-syntactic bugs in novices' programs. PROUST is a 15,000 LISP program
and runs on a VAX. Micro-PROUST is a program meant to capture the essence of PROUST.
Micro-PROUST is a 1500 line LISP program and runs ,L an IBM PC (with 512K). In this
document we present the inner workings of Micro-PROUST. Our intent is to enable those who
- . so are inclined to see at a nuts and bolts level how a system like PROUST actually works.
. ." - . . . .-
Micro-PROUST Code Page
Table of Contents1 Introduction. .. ... .... ..... ..... .... ..... ..... .... I2 PROUST/Micro-PROUST: From BYTE Magazine. .. .. .. ..... ..... .... 23 Design Document: Micro-PROUST .. .. .. ..... ..... ..... ....... 34 PROUST/Micro-PROUST: A Preliminary Comparison .. .. .. .... ..... .... 45 Micro-PROUST Implementation: The LISP Code .. .. ... ..... ..... .... 5
Micr-PROUST Code Pg
3. Design Document: Mlicro-PROUST
7,
Design for Micro-PROUSTW. Lewis Johnson
Elliot Soloway
Cognition and Programming Project
Department of Computer Science
Yale University
P.O. Box 2158 Yale Sta.
New Haven, Ct. 08520
(203) 436.0606
0A
*_. -, . . . . m . 4 . .. . +
23. April 1985 1
1. Introduction
This document describes the design of Micro-PROUST, a stripped-down version or
PROUST [1, 2]. Micro-PROUST is a knowledge-based system which identifies a certain class of
non-syntactic bugs in novice programs. It uses a single, uniform mechanism for analyzing buggy
programs, unlike the full PROUST system, which employs various reasoning techniques in order
to understand students' programs. The following are included in this description of
Micro-PROUST:
e sanple programming problems and solutions which Micro-PROUST should be able to* .handle;
* the design of Micro-PROUST; and
* a description of the knowledge bases required in order to make Micro-PROUST runon the examples given.
This design has been constructed with a Common Lisp environment in mind. Modifications
may be required to get this system to run in some other environment.
1.1. Overview of the system
Micro-PROUST analyzes programs using an analysis-by-synthesis approach. The system takes
as input a description of a programming problem, and a program. The problem description is a
list of goals which the program must satisfy. Micro-PROUST uses the problem description to
try to build an implementation model for the program. It does this by using a database of
programming knowledge to suggest ways in which the goals in the problem description might be
implemented. A separate knowledge base of bugs is used to ideitify bugs given the
implementation model.
The following knowledge bases are required:
* a knowledge base of goals, indicating how these goals might be implemented usingplans;
* a knowledge base or plans; and
* a rule base of rules for identifying bugs.
The system itself has the following main modules:0• a lexer and parser for Pascal;
23. April 1985 2
" a goal selection and implementation mechanism;
* a plan matcher;
- a bug rule applier; and
* a bug description generator.
2. Test examples for Micro-PROUST
2.1. Problems for Micro-PROUST to analyze
Figures 2-1 and 2-2 show two different programming problems which Micro-PROUST should
be able to handle. The first, the Average Problem, is extremely simple. The second, the
Rainfall Problem, is an elaboration of the Average Problem.
Read in numbers, taking their sum, until the number 99999 is seen. Report theaverage. Do not include the final 99999 in the average.
Figure 2-1: The Average Problem
Noah needs to keep track of rainfall in the New Haven area in order to determinewhen to launch his ark. Write a program which he can use to do this. Your programshould read the rainfall for each day, stopping when Noah types 099999", which is nota data value, but a sentinel indicating the end of input. If the user types in a negativevalue the program should reject it, since negative rainfall is not possible. Yourprogram should print out t he number of valid days typed in, the number of rainy
- -. days, the average rainfall per day over the period, and the maximum amount ofrainfall that fell on any one day.
Figure 2-2: The Rainfall Problem
2.2. Programs for Micro-PROUST to analyze
2.2.1. Example 1
This example, shown in Figure 2-3, is shown in Figure 2-3. The output which Micro-PROUST
should generate is shown in Figure 2-4.
2.2.2. Example 2
0 Here is another example averaging program.
)::. . / :"::- :-. -: : :; . : •:: . " : . : " -:.: :::::::-:" : : : ,:::.i _i:: -;;:--- p,!'" % :
23. April 1985 3
1 PROGRAM Averagel( input, output );2 VAR Sum. Count. New: INTEGER;3 Avg: REAL;4 BEGIN5 Sum := O;6 Count := 0;7 Read( New );8 WHILE Ney099999 DO9 BEGIN
10 Sum := Sum+Nev;11 Count := Count+l;12 New := Nev+113 END;14 Avg := Sum/Count;15 Writeln( 'The average is . avg);16 END;
Figure 2-3: Averaging program #1
1. It appears that you were trying to use line 12 to read the next input value.Incrementing NEW will not cause the next value to be read in. You need to use aREAD statement here.
2. You need a test to check that at least one valid data point has been input before line14 is executed. The average is not defined when there is no input.
3. You need a test to check that at least one valid data point has been input before line15 is executed. The average is not defined when there is no input.
Figure 2-4: Output for averaging program ,#1
!i
"" ~ ~ ~ ~ ~ ~ ~ ~ ~ . * .. ".. ".....'....... ...... ...... ,,,., ...... .. -_, .. ,, , . ..,
23. April 1985 4
I PROGRAM Average2( Input, output )"2 VAR Sum. Count, New: INTEGER;3 Avg: REAL;
4 BEGIN5 Sum :0;6 Count := 0;7 New := 0;8 WHILE New099999 0O9 BEGIN
10 Read( New );11 Sum := Sum+Nev;12 Count := Count+1;13 END;14 IF Count=D THEN15 Vriteln( 'No data entered' )16 ELSE17 BEGIN18 Avg := Sum/Count:19 Writeln( 'The average Is '. avg );20 END
* 21 END;
Figure 2-5: Averaging program #2I. You're missing a sentinel guard. When your program reads the sentinel, it processes
• " it as if it were data.
Figure 2-6: Output for averaging problem #2
S
.. . . . . . . ., . . . .. .
. . .. '** ~ ~ ' -. * * .. , " -.,-. .-. , ' , ..- . .. .- . .
23. April 1985 5
2.2.3. Example 3
Here is a solution to the Rainfall Problem.
PROGRAM NOAH (INPUT OLTPUT);
VAR
RAINFALL. LARGEST, SLIM. COJNTI.
CDJNT2. AVERAGE, RAINYDAYS REAL;
BEGIN(* INITIALIZE VARIABLES *)LARGEST :=0;SLM :=0;CO)ITI :=0;COUNT2 :=0;
AVERAGE :=0;RAINYDAYS :=0;
(. READ THE RAINFALL AND CHECK FDR ERROR VALUES *)WRITELN ('ENTER RAINFALL. WHEN YOU ARE FINISHED ENTER 99999');READLN;READ (RAINFALL);WHILE RAINFALL <> 99999 DO
BEGINWHILE RAINFALL <0 DO
BEGINWRITELN (RAINFALL :8, 'IS NOT A POSSIBLE RAINFALL. TRY AGAIN.');
WRITELN ('ENTER RAINFALL');
READLN;READ (RAINFALL)
END;IF RAINFALL > LARGEST
THENLARGEST : RAINFALL;
IF RAINFALL > 0THEN
COLI4T2 := COUNT2+ 1;COUNTI := COUNTI + 1;SUM := SLIM + RAINFALL;READLN;READ (RAINFALL)
END;
AVERAGE :S 5LJ,/CD)J 2L•
WRITELN (COUNTI :8. 'VALID RAINFALLS WERE ENETERED.);WRITELN ('THE AVERAGE RAINFALL WAS'. AVERAGE :8. 'INCHES PER DAY.');
0"
2!- --
23. April 1985 6
WRITELN ('THE HIGHEST RAINFALL WAS'. LARGEST :0:2. 'INCHES');WRITELN ('THERE WERE'. CCJNT2 :0:2, 'RAINYDAYS IN THIS PERIOD.')
END.
Micro-PROUST's output should look something like this:
1! You're missing a sentinel guard. If a sentinel value is inputimmediately folloving a negative value, your program viii process It astf it were data.
2. You need a test to check that at least one valid data point has beeninput before line 50 is executed. The average is not defined whenthere is no input.
3. You need a test to check that at least one valid data point has beeninput before line 46 is executed. The average is not defined whenthere is no input.
4. You need a test to check that at least one valid date point has beeninput before line 51 is executed. The maximum is not defined whenthere is no input.
S
23. April 1985 7
2.2.4. Example 4
Here is another example Rainfall Program.
PROGRAM RAINFALL ( INPUT,OUTPI/T );
VARRAIN. DAYS. TOTALRAIN, RAINDAYS. HIGHRAIN. AVERAIN: REAL;
BEGINDAYS := 0;TOTALRAIN := 0;RAINDAYS 0:;HIGHRAIN : 0;REPEAT
WRITELN ('ENTER RAINFALL');READLN;READ (RAIN);
WHILE RAIN <> 99999 DOBEGIN
DAYS := DAYS + 1;"DTALRAIN := TOTALRAIN * RAIN;IF RAIN > 0 THEN
RAINDAYS := RAINDAYS + 1;IF HIGHRAIN < RAIN THEN
HIGHRAIN RAIN.END;
UNTIL RAIN = 99999;
AVERAIN := TOTALRAIN / DAYS;
WRITELN;WRITELN ( DAYS:O:0. 'VALID RAINFALLS WERE ENTERED');WRITELN;WRITELN ('THE AVERAGE RAINFALL WAS',AVERAIN:0:2.'INCHES PER DAY');WRITELN;VRITELN ('THE HIGHEST RAINFALL WAS' .HG.RAIN:0:2. 'INCHES');WRITELN;WRITELN ('THERE WERE',RAINDAYS:O:0.'IN THIS PERIOD');
END.
The output from Micro-PROUST should look something like this:
1. You used a KILE statement at line 19 vhere you should have used an IF.0, P
2. You need a test to check that at least one valid data point has beeninput before line 35 Is execuled. The overage is not defined whenthere Is no Input.
............ ................ ..
23. April 1985 S
3. You need a test to check that at least one valid data point has beeninput before line 30 is executed. The average is not defined whenthere is no input.
4. You need a test to check that at least one valid date point has beeninput before line 37 is executed. The maximum is not defined when
there is no input.
5. Your program does not perform an input validation.
23. April 1985
2.2.5. Example 5
PROGRAM TESTI (INPUT, OUTPUFT);VARS. N. MAX. AVE: REAL;COUNT. RAINY: INTEGER;
BEGINSJM:=O;"
COUNT:sO;
RAINY:=O;MAX:=O;WRITELNC'ENTER RAINFALL');READLN;READ(N);WHILE N<>99999 DO
BEGINIF N<O THEN
WRITELN(N:O:2.' IS NOT A POSSIBLE RAINFALLTRY AGAIN');ELSE
BEGINCOLUT: =COLUT41;
S:--SUM+ ;IF N>O THEN
RAINY :-RAINY+ ;IF N>MAX THEN
N:=*AX;END:
WRITELN('ENTER RAINFALL');READLN;READ(N)
END;WRITELN;IF COUNT=O THEN
WRITELN(COUNT:0,' VALID RAINFALLS WERE ENTERED.');ELSE
BEGINAVE :- -SUM/CO*4T;
WRITELN('THE AVERAGE RAINFALL WAS ',AVE:O:2,' INCHES PER DAY.');WRITELN('THE HIGHEST RAINFALL WAS '.MAX:O:2,' INCHES.');WRITELN('THERE WERE ',RAINY:O.' RAINY DAYS IN THIS PERID. ')
ENDEND.
PROUST's output:
You ire using a counter update instead of a running-total update atline 22. You must add the new-value variable to SUM. not add I to It.
The assignment at line 26 is backwards. This line will ssign toN; you need to assign to MAX.
. ., . . . . -
-. . . . . - . , . •- . ... . ... .. .. . . i
23. April 1985 10
2.2.6. Example 6
PROGRAM TESTI (INPJT, OUTPUT);VAR
SL. N, MAX. AVE: REAL;COJ, , RAINY: INTEGER;
BEGINWRITELN('ENTER RAINFALL');READLN;READ(N);WHILE N099999 DO
BEGINIF N<O THEN
WRITELN(N:0:2.' IS NOT A POSSIBLE RAINFALL.TRY AGAIN')ELSEBEGIN
SL4 :--"S+N;CODJT :=COUNTI;IF N>MAX THEN
MAX:=N;IF N>O THEN
RAINY :=RAINY+I;
END;WRITELN('ENTER RAINFALL');READLN;READ(N)
END;WRIT ELN;IF CODLT=O THEN
WRITELN(CDJNT:O,' VALID RAINFALLS WERE ENTERED.');ELSE
BEGINAVE:USLM/COLJNT;WRITELN('THE AVERAGE RAINFALL WAS *.AVE:O:2.' INCHES PER DAY.');WRITELN('THE HIGHEST RAINFALL WAS ',MAX:0:2,' INCHES.');WRITELN('THERE WERE ',RAi]NY:O,' RAINY DAYS IN THIS PERIOD. °)
ENDEND.
PROUST's output:
1. You did not initialize a sum.
2. You did not initialize a counter.
3. You did not, initill1U a maximum computation.
4. You did not initialize a counter.
. • ° -" - . . " . . o , . .. . , . • -° . . _
23. April 1985 11
3. Top-level organization of Micro-PROUST
The top-level processing is as follows.
1. Take as input a problem description, and a file name containing the student'sprogram.
2. Parse the file, generating a parse tree.
3. Load the goal agenda with the problem description. (The goal agenda is described inSection 6.)
4. Retrieve plans for realizing each goal.
5. Match against the plans against the program.
6. If a plan matches, add it to the list of plans that have been matched so far.
7. Otherwise apply bug rules in order to explain the errors in matching the plans.
8. When the goal agenda is empty, report the bugs to the student.
The following is a list of the main routines in Micro-PROUST. More detailed descriptions of
some of these modules will appear in subsequent sections.
" (MPRa5IT filename problem) - this is the top-level routine of Micro-PROUST.filename is the name of the student's program, and problem is the problemdescription.
" (PARSE filename) - parse filename, and return a pointer to the root of the parsetree.
" (INIT-AENDA problem) -- initialize the goal agenda.
" (PROCESS-NEXT-GOAL) - select a goal from the agenda, retrieve plans for it, match theplans against the program, and identify bugs.
" (REPORT-DJOS) -- describe the bugs which have been found to the student.
The calling hierarchy of these routines is as follows:
MPROST
-. p
PARSE INIT-AGENDA PR:CESS-NEXT-(DAL REPOWi<-, S
These following global variables are used in this process:
23. April 1985 12
e .PARSE-TREE* - the parse tree
9 *AGENDA* - the goal agenda
e .ACTIVE-GOAL* - the current goal
e *ANALYZED-GOALS* - the goals which have been analyzed so far
& *BX-REPORT* - the bugs which have been found so far.
4. The parser
You will have to build a lexer and parser for Pascal. You may borrow the one in PROUST,
but it is written in T, not Common Lisp, so you would have to translate it. Assuming that you
write your own, it should contain the following routines:
" (PARSE filename) - parse the program contained in the file named "filename".Generate a syntax tree for the program, and return the parse tree node for the rootof the program.
" (LEX-INITIALIZE fi lename ) - open the file and initialize the input stream to thebeginning of the file. Initialize the lexer. Return T if successful.
" (LEX-GETTOK) - get a token. Return the token type, and set *TOK-VAL* to thetoken value. Set *TOK-LINE* to the line number in the program which the tokenappears on. Token types and token values are discussed in Section 4.1.
The calling hierarchy is as follows:
PARSE
LEX-INITIALIZE LEX-GETTOK
I will not discuss here the method for constructing the Pascal parser; there exist various books
on compiler construction which discuss how this can be done. The method that we used in
Proust was to modify the Unix ymcc program to make it generate Lisp code. Note that it is not
necessary to construct a complete parser for Pascal; in particular, there is no need to make the
parser handle procedures or complex datatypes. Therefore the parser should be fairly simple.
Whatever method you use for implementing your parser, make sure that it generates parse trees
such as those described in Section 4.2.
4
1 PFMJ? NOAH- (I?'JT *aJTMM23 VAR45 RAINFALL. LA RT, am,) iT1.6 03,JT2, AVE8a, PAINYDAYS EAL;789 BEIN
10 (, INITIALIZE VARAaES )11 LAET :=;12 SUM :=0;13 Ca1l :=o;
14 KJ2 :=.
1516 AVERAE =O;17 RAINYDYS :=O;
18 (* FAD THE RAINFALL AND oEO( FOR E VALUES *)19 FTrN ('ENTER RAINFALL, *0 YUJ ARE FINIMSE ENTR 9M');20 FEADLN,21 READ (RAIFALL);22 *LE RAIWALL < 999 DO23 BEGIN24 *rLE PAINFALL <0 M25 BEGIN25 WTELN (RAINFALL :8, 'IS NIT A PIBLE RAINFALL, TRY AA.IN.);27 WRraN (ENTER RAINFALL');28 FEADLN;29 EAD (RAINfALL)30 EWD,31 IF RAINFALL >LAM
THIEN
33 LARMST - AINFALL;34 IF RAINFALL > 035 THEN4
36 CanT2 := Q3.T2 + 1;37 C "J=T1 Ca)JhT + 1,38 SY = SJM + RAINFALL,39 FADLN40 RAD (RAINFALL)41 END,4243 AVERA E = ,/(CXLI4445 WITELN (CJT "8, 'VALID RAINFALLS W BENET). ');46 wf J4 ('THE AVSRDaC RAINFALL WAS', AVRAGE :8. 'IO PER DAY.');47 RTE.N ('TiE EO-EST RAINFALL WAS'. LAT :0:2, 'DOB');48 TELN ('fmlB W, ', JT2 :0:2, 'RANYDkYS IN Mn-5 ). ')49 END
Figure 2: An example solution of the Rainfall Problem
. - . . ." •
3
Noab needs to keep track of rainfall in the New Haven area in order to determinewhen to launch his ark. Write a Pascal program that will help him do this. Theprogram should prompt the user to input numbers from the terminal; each inputstands for the amount of rainfall in New Haven for a day. Note: since rainfall cannotbe negative, the program should reject negative input. Your program should computethe following statistics from this data:
I. the average rainfall per day;
2. the number of rainy days.
3. the number of valid inputs (excluding any invalid data that might have beenread in);
4. the maximum amount of rain that fell on any one day.
The program should read data until the user types 99999; this is a sentinel valuesignaling the end of input. Do not include the 99999 in the calculations. Assume thatif the input value is non-negative, and not equal to 99999, then it is valid input data.
Figure 1: The Rainfall Problem
in terms of its intended function, e.g., outputting the maximum, or checking for invalid input.
PROUST also generates an example of input data which will cause the program to perform
incorrectly, to ensure that the programmer sees that the intended function has not been properly
realized. In this case the suggested input sequence is 5, -5, 99999.
4. Application of Intention-Based Diagnosis in PROUSTPROUST's methods for analyzing bugs based on intentions has been discussed in detail
elsewhere [6, 3. 5, 4]. We will focus here on some of the key features of PROUST's approach.
Then, In the next section. we will compare the way that these features are realized in PROUST
with the way that they are implemented in Micro-PROUST.
PROUST bases its analysis of each program on a description of the problem that the student is
working on. PROUST is intended to be used in an introductory programming course, where the
students are expected to complete a series of programming assignments. PROUST is supplied
with a description of each assignment that the students will be working on. Each problem
description indicates the type of data that the program must process, and the primary goals that
must be achieved by the program. They indicate what the programs must do, but not bow they
should do it. The problem descriptions frequently leave out some details, which the programmer
is assumed to know to fill in. The problem descriptions thus supply essential information about
2
errors in the programmer's intentions, or as errors in the realization of those intentions.
It is intuitively obvious to most programmers that a good understanding of the intended
function of a program is necessary in order to debug a program accurately. Some bugs may be
identified without reading the code, but frequently a person must read a program carefully in
order to diagnose bugs and suggest an appropriate correction for them. Nevertheless, automatic
debugging systems tend to analyze program behavior, without reference to underlying intentions
[8, 1, 2, 7, 11]. Such methods can fail when the program runs, but generates incorrect results.
PROUST is unique in its reliance on an explicit description of the intentions underlying
programs.
3. An illustration of intention-based diagnosisIn order to illustrate how knowledge of intentions is needed when debugging programs, we will
discuss an example buggy program and show how it is debugged. The example is a solution to
the problem shown in Figure 1, which we will be refer to as the Rainfall Problem. This problem
requires that a series of inputs be read, which signify the amount of rainfall per day. The end of
input is signaled wben the user types 99999; we will refer to this value as the eentinel value.
The program must perform various computations on these data, such a-v finding the average and
the maximum. It must also ensure that the data that is entered is valid, i.e., negative daily
rainfall must be rejected.
Figure 2 shows an actual student solution to the Rainfall Problem. This program has several
bugs. If the user types 99999 without first entering rainfall data, the program divides by zero at
line 43, and then prints out meaningless results at lines 46 and 47. In addition, the test for
invalid input, starting at line 24, has a bug. If the user types 99999 immediately after an invalid
value, the 99999 will not be recognized as the signal of input termination. Instead, the 99999 will
be processed as data We claim that knowledge of the intended function of this program is
needed in order to debug the program. In particular, we need to know what range of inputs the
program is supposed to handle, and what results it should generate for these inputs. For
example, if we did not know that 99999 should not be processed as data, we would not be able to
determine that the program behaves incorrectly when 99999 is input after a negative input.
PROUST's analysis of the program in Figure 2 is shown in Figure 3. This analysis makes
frequent reference to the intentions underlying the program. It describes each buggy line of code
1. Introduction
As a first step in developing tools that can aid novice programmers when they are learning to
Program, we have designed, built and classroom tested a program called PROUST that can
identify the non-syntactic bugs in novices' programs. Currently, PROUST operates on a class of
moderately complex looping programs in Pascal that are typical assignments in an introductory
programming course. PROUST provides students with a list of the non-syntactic bugs in their
programs and suggestions about the misconceptions that they may be laboring under that are
responsible for the bugs. PROUST can correctly identify approximately 75% of the bugs in the
students programs.
PROUST is a 15,000-line LISP program which runs on a VAX 750 with several megabytes of
memory. As such, PROUST cannot run on a personal computer. In a project sponsored by
Courseware, Inc. we undertook to design a micro version of PROUST that would be able to run
on an IBM PC. Our purposes in undertaking this project were twofold. First, PROUST is a
very complex program; we believed that it would be instructive to strip PROUST down to its
barest essentials, so others would be able to see more clearly how PROUST works. Second, we
wished to demonstrate the feasibility of developing an Al-based system for a persona] computer.
To these ends, our project has been a success: in this paper we briefly describe the architecture
Of MicrO-PROUST. However, Micro-PROUST as it stands is not powerful enough to use as an
educational tool. We will discuss in Section 7 what will be required to expand Micro-PROUST
sufficiently to make it "a useful product, while at the same time staying within the space
limitations of personal computers.
The organization of this paper is as follows. First, we briefly describe the architecture of
PROUST, and talk about the features of PROUST that have been incorporated into Micro-
PROUST. A comparison of the two systems is made. We conclude by discussing the prospects
of building a product version of Micro-PROUST that will perform at an acceptable level in a real
educational setting.
2. Intention-Based Diagnosis
The key idea underlying PROUST's approach is intention-based diagnosis. That is, PROUST
identifies the non-syntactic bugs in a program by determining what the program is intended to
do, and then relating these intentions to the actual code. Bugs then become apparent either as
Table of Contents1. Introduction 12. Intention-Based Diagnosis 13. An illustration of intention-based diagnosis 24. Application of Intention-Based Diagnosis in PROUST 35. PROUST and Micro-PROUST 7
5.1. Goal decompositions 75.2. The goal database 105.3. Plans 105.4. Plan-difference rules 11
6. Additional Comparisons of PROUST and Micro-PROUST 137. Scaling Up Micro-PROUST 148. Concluding Remarks 16
Micro-PROUST: Knowledge-BasedDebugging on a Personal Computer
W. Lewis Johnson
Elliot Soloway
Departrrcnt of Computer Science
Yale University
P.O. Box 2158 Yale Sta.
New Haven, Ct. 06520
(203) 436-0606
9 May 1985
The research described in this paper was co-sponsored by the Personnel and Training ResearchGroups, Psychological Sciences Division, Office of Naval Research and the Army ResearchInstitute for the Behavioral and Social Sciences, under Contract No. N00014-82-K-0714,Contract Authority Identification Number 154-492. Approved for public release; distributionunlimited. Reproduction in whole or part is permitted for any purpose of the United StatesGovernment. The development of Micro-PROUST was sponsored by Courseware, Inc., SanDiego, Ca.
-. Jww~~w~~w '--~- - -. -. - -.
* 2Micro-PROUST Code Page 4
4. PROUST/Micro-PROUST: A Preliminary Comparison
0'
U
S
U
I,
S
0
I
0
- .1 .C-.C:i*r>.i:.i.j.iY!*!;.:j~
* 23. April 1985 i
(DPS LOOP-INPUT-VALIDATIONINSTANCES(B-INPUIT-SKIP-GUAg)BAD>-INPUT-LOOP-G
23. April 1985 18
INIT-AGENDA PROCESS-NEXT-GDAL
GET-NEXT-GQAL INSTANTIATE PROCESS-PLANS
7. The goal database
In order to process each goal, PROUST must look tbe goal up in the goal-plan database, in
order to determine how the student might have implemented the goal. Information about goals
is stored on the property list of the goal. The following properties are used:
INSTANCES - a list of plans which can be used to implement the goal
* NAME-PHRASE - a string indicating in English the function of the goal.
7.1. The DPS macro
The following macro is used to construct the goal knowledge base, as well as other knowledge
bases.
9 DPS( var sloti filler1 slotf fllerf ...) - adds properties sloti, lot, etc. to theproperty list of var. DPS does not evaluate its arguments.
Example:
(DPS FID,SPECIES CANIS-FAVLIARISAGE 8SEX MALE)
(PUT 'FID 'SPECIES 'CANIS-FAMILIARIS)(PUT 'FIDO 'AGE 8)(PUT 'FIDO 'SEX 'MALE)
7.2. Example gqal database
The following database is required in order to handle the examples described in Section 2.
(DPS SENTINEL-CONTROLLED-LOOPINSTANCES(SENTINEL-READ-PROCESS-WHILESENTINEL-PROCESS-READ-WHILESENTINEL-READ-PROCMS-REPEAT)
NAME-PHRASEginput processing')
0 " " ' - . . " . . , J • , . -
23. April 1985 17
(MAX17KPi (NEW . (*VAR* NEW SENTINEL-CONTROLLED-LOOP)))(OUTPUT (VAL . (VAR* MAX AIMUJ)))(GUARD-EXCEPTIOON (CODE . (*VAR* OUTPUT: OUTPUT))
(PRED (= (*VAR* CONT COJNT) 0)))(GJARD-EXCEPTION (CODE . (*VAR* UPDATE: AVERAGE))
(PRED. ( (*VAR COUT COUNr) 0)))))
Note that some variables are bound to an expression which contains a *VAR* form in it. These
are used to refer to variables defined by other goals. For example, (*VAR* NEW
SENTINEL-CONTROLLED-LOOP) refers to the variable NEW in the SENTINEL-CONTROLLED-LOOP goal.
6. Processing the goal agenda
During processing of the program the goal agenda is stored in the variable *AGENDA*. The
goal currently being processed is in the variable *ACTIVE-GOAL'. The list or goals that have
already been analyzed is called 'ANALYZED-GOALS*. The processing of goals in
Micro-PROUST is extremely simple; the program simply starts with the first goal in
'AGENDA', processes each goal in order, one at a time. This continues until *AGENDA* is
empty.
After a goal has been matrhed, and a plan has been chosen, the goal and the plan are stored in
*ANALYZED-GOALS*. This is discussed further in Section 10.3.
The following routines are used to manipulate the goal agenda:
e CINIT-AGENDA problem description ) - sets *AGENDA* to be the list or goalscontained in the problem description
" (PROCESS-NEXT-GOAL) -- get the next goal and process it. This calls GET-NEXT-COAL toget the next goal to process, then passes this to INSTANTIATE. PROCESS-PLANS is calledin order to match the plans to the code.
...- . (GET-NEXT-GOAL) - removes the goal at the head of *AGENDA*, and stores it in*ACTIVE-COAL*. Returns *ACTIVE-COAL*.
- (INSTANTIATE goal) - instantiates a goal. Returns a list of plan instantiations. See• Section 9.
" (PROCESS-PLANS plaos - match the plans against the dbde. See Section 10.
The calling hierarchy of these routines is:
i°......... . . . . . .
.. '-
23. April 1985 16
S. Problem descriptions
The problem descriptions for the two problems will appear as follows. These problemdescriptions are a list of goals which will have to be satisfied in the student's program. For the
sake of simplicity we are assuming that every goal that will be realized in the program will have
to be included in the problem description.
Each goal is a list whose CAR is the type of goal which is required, and whose CDR is a list of
variable bindings. Each goal has a specific set of free variables associated with it, not all of
which may be listed in the bindings list. For example, SENTINEL-CONTROLLED-LOOP has two free
variables: Nev, which is the new-value variable, and STOP which is the stop value. Only STOP is
mentioned in the SENTINEL-CONTROLLED-LOOP goals that appear below. If a variable does not
appear in the bindings list, it remains free, and must be bound during the process of matching
the goal against the program. In other words, Micro-PROUST determines the binding of NEW in
SENTINEL-CONTROLLED-LOOP when examines the student's program and discovers which Pascal
variable in the program corresponds to NEW.
(DEFINE *AVG-SPEC* '((SENTINEL-CONTROLLED-LOOP (STOP . 99999))(COUNT (NEW . (*VAR* NEW SENTINEL-CONTROLLED-LOOP)))(AVERAGE (NEW . (*VAR* NEW SENTINEL-CONTRLLED-LOOP)))(SU14 (NEW . (*VAR* NEW SENTINEL-CONTROLLED-LOOP))
(TOTAL . (*VAR* SUM AVERAGE)))(OUTPUT (VAL . (*VAR* AVG AVERAGE)))(GUARD-EXCEPTION (CODE . (*VAR* OUTPUT: OUTPUT))
(PRED. (= (*VAR* COJNT COUNT) 0)))(GUARD-EXCEPTION (CODE . (*VAR* UPDATE, AVERAGE))
(PRED. ( (iVAR* COUN'T COUNT) 0)))))
(DEFINE *RAINFALL-SPEC* '((SENTINEL-CONTROLLED-LOOP ((*VAR* NEW SENTINEL-CONTROLLED-LOOP) 99299))(LOOP-INPUJT-VALIDATION ((*VAR* NEW SENTINEL-CONTROLLED-LOOP)
(< (*VAR4 NEW SENTINEL-CONTROLLED-LODOP) 0)))(AVERAGE (NEW . (*VAR* NEW SENTINEL-CONTRLLED-LOP)))(COUNT (NEW . (*VAR* NEW SENTINEL-CONTROLLED-LOOP)))(OUTPUT (VAL . (,*VAR* AVG AVERAGE)))(UARD-EXCEPTION (CODE (*VAR* OUTPUT: OUTPUT))
(PRED . (= (VAR UNT COJT) 0)))(OUTPUT (VAL . (*VAR* COUNT COUN)))(SUM (NEW . (*VAR* NEW SENTINEL-CONTROLLED-LOOP)) #
(TOTAL . (*VAR* SLI AVERAGE)))(GUARDED-COJNT (NEW . (*VAR* NEW SENTINEL-COTROLLED-LOP))
(PRED .( (*VAR* NEW SENTINEL-CMNTROLLED-LOOP) 0)))(OUTPUT (VAL (*VAR* GUARDED-COJNT CUNT)))
• j . ? " . ... .: - -" * - -. - " " " 'I - - l "
'-7 I7 K. " a. ..
23. April 1985 15
BEGIN a BEGIN-END blockCASE a CASE statementCASE-PART a branch of a CASE statement
C1 CONST-LIST a list of constants referred to by a CASE-PARTWRITE a call to WRITEWRITELN a call to WRITELNREAD a cal Ito READREADLN a call to READLN
an assignment statementSTATEMENT-LIST a list of statements; used in REPEAT and CASE statementsWHILE a WHILE statement.REPEAT a REPEAT statementIF an IF statement
< relational expressions
- AND logical expressionsORNOT- arithmetic expressions
DIVMOD
stringsnumbersidentifiers
Parse tree nodes are structures containing the following fields:
* NAIE -- the name or the parsetree node
" PARENT - the parent or the node in the parse tree
* CHILDREN - children or the nodeS
* LINE - the line number where the code appears in the student's program
" MARK - T or NILrindicates whether or not the statehment has been matched yet.
*.. -. ., . - - - . -. . - ,.. . - : , - • . , -,....., .. . , .- ., , . - . ., - .- . . . ., : . .:
23. April 1985 14
4.2. Parse tree nodes
Generally speaking, there is a node in the syntax tree for each syntactic statement, expression
and subexpression in the program. Each parse tree node is labeled according to the principal
keyword, operator, or value in the corresponding statement or expression. The following
example shows a fragment or Pascal text and the parse tree that is generated for it.
WHILE N<O DOBEGINWRITELN( N. 'IS INVALID. PLEASE REENTER' );READ( N );
END;
WHILE
< BEGIN
N 0WRITELN READ
N 'IS INVALID, PLEASE REENTER N
Note that I have chosen to use as names of the parse tree nodes the token values such as N and
0, rather than the token types, TOK-IDENTIFIER and TOK-MJIBER. I also name nodes for operators
using the actual operator: the top-most node denoting the expression NWO, for example, is not
10K-LESS-THAN. Check the Common Lep manual: you mar have to thente thio.
In the case or statements, the name or the parse tree node is the principal keyword in the
statement. This means that a parse tree node for a WHILE statement is named WHILE, and the
parse tree node for an assignment statement is named :=. There is no parse tree node
corresponding to the keywords "HEN, DO, or END, so these do not appear in the tree.
Here is a list of the kinds of parse tree nodes which are used in Micro-PROUST:
PROGRAM the root node for the parse treePROG-HEADER the I/0 header of the program
S DECLS the declaration part of the programCONST-DECLS constant declarlionsVAR-DECLS vartiblo declarationsCONST a constant declaration
" VAR a variable declarationID-LISI a list of Identifiers
......................................... . .. . -
23. April 1985 13
," 4.1. The lexer
Lexers are also describ.td in detail in compiler construction texts. I leave the details of the
lexer design to the impl,.entor. However, I should point out that there may be ways to take
advantage of the Lisp READ function when constructing the lexer for Micro-PROUST. After
all, READ processes text -nd identifies numbers and atoms, which is a lexical analysis process.
In principal you could lex your Pascal programs by repeatedly calling READ on the Pascal
program, and looking at what READ returns to see if it is a number, an atom, or an S-
expression. Note, however, that to do this will require definition of read macros for special
characters such as commas, semicolons, and operators. Otherwise if expressions such as A B will
be lexed as a single atom rather than as A, +, and B.
Lexical tokens are denoted using two values: the token type and the token value. The token
type is a code indicating the type of token which has been encountered. These codes are Lisp
atoms. Thus we might have the following relationship between tokens and token types:
Token Token Type
BEGIN TOK-BEGINUNTIL T0K-UNTILC TOK-LESS-THAN
TOK-NOT-EQ• ; TDK-SEMICDLDN
•, 10K-COMMA* TDK-MULTIPLY
TK-MINJSI-pascal-variable TK-IDENTIFIER
4.75 1DK-NPJMBER'hello worId' 10K-STRING<end of file> TOK-E0F
N Note that in the case of identifiers, numbers and strings, the token type is simply
OK-IDENTIFIER, TK-NUMBER, and TOK-STRING, respectively. In these cases the token value is the
actual token, i.e., the name of the identifier, the actual number or string. In other cases the
token value is undefined, since the token type is sufficient to describe what kind of token it is.
'U
0.o
Bug Report
1. You're missing a sentinel guard. If a sentinel value is input* immediately following a negative value, your program will process it as
if it were data.
Try the following data in your program to see this:
5 -5 99999
Other bugs:
2. You need a test to check that at least one valid data point has beeninput before line 50 is executed. The average is not defined when
* there is no input.
* 3. You need a test to check that at least one valid data point has beeninput before line 46 is executed. The average is not defined whenthere is no input.
4. You need a test to check that at least one valid data point has beeninput before line 51 is executed. The maximum is not defined whenthere is no input.
Figure 3: PROUST's output for the example in Figure 2
the problems, without predisposing PROUST toward Epecific types of solutions.
When a student submits a program for analysis by PROUST, PROUST retrieves the
*appropriate problem description from the problem description library. These problemdescriptions give PROUST a start at understanding the intended function of the program.
PROUST must still go through a considerable amount of effort in order to understand how each
* .student program is supposed to work. However, given a description of the problem, and
* . knowledge base of facts about programming, PROUST is able in most cases to identify the
* student's intentions, and use the intentions to find the bugs.
Program analysis is performed in PROUST using an analysis-by-synthesis process. PROUST
synthesizes different ways of solving and implementing the assigned programming problem.
* PROUST must have enough programming knowledge that it could write the program itself.
After PROUST synthesizes a possible problem solution, it compares the hypothesized solution to
the student's code. If there is a match, then it is likely that the synthesized solution fits the
student's intentions. If there is a mismatch, then either the student's intentions do not match
the synthsized solution, or else there is a bug in the realization of those intentions. PROUST
4 6
then uses its knowledge of bugs to determine if the mismatches result from bugs. If so, these
bugs are reported to the student.
Synthesis of possible problem solutions involves two steps. First, PROUST synthesizes
alternative goal decompositions for the program. PROUST's problem descriptions consist in
part of high-level descriptions of the goals which must be satisfied in solving the problem. Goal
decompositions are the relationships between the goals in the problem statement and the goals
which are actually implemented in the student's program. The more complex the programming
problem is, the more reasoning about goals the programmer has to do in order to put them in aI
form that can be implemented in code. The goal decomposition records the additions,
modifications, and deletions to the original set of goals which are listed in the problem
description
The second step in synthesizing possible solutions is to select programming plans to implement
the goals which result after goal decomposition. Programming plans are stereotypic methods for
accomplishing programming tasks. Expert programmers make extensive use of programmingIplans in writing and understand~ing programs 110]. In PROUST the possible plans that the
student might use to implement a goal are all matched against the program, to see which fits the
code best.
When a plan fails to match the code exactly, PROUST makes a note of the differences between
the plans and the code. It then uses a database of plan-difference rules to explain the plan
differences. These plan-difference rules suggest bugs which could cause the match failures. The
bugs that the plan difference rules identify are then reported to the student.
* To summarize, intention-based diagnosis in PROUST consists of the following steps:
* retrieving the appropriate problem description,
* hypothesizing goal decompositions for the program,
* hypothesizing plans to implement the goal decompositions,
0 matching the plans against the program, and
o using plan-difference rules to explain the plan mismatches.
7
5. PROUST and Micro-PROUST
- Micro-PROUST goes through nearly the same process that PROUST does in analyzing buggy
programs. Some of PROUST's analysis steps have been eliminated, but the resulting mechanism
still retains most of the essential features of PROUST. The features of PROUST which were
eliminated are those which require substantial amounts of code to implement, and which are not
necessary for analyzing most novice programs. In order to highlight the similarities and
differences between PROUST and Micro-PROUST, we will describe step by step the knowledge
and processing required by the two systems to analyze solutions to the Rainfall Problem.
5.1. Goal decompositions
The main difference between PROUST and Micro-PROUST is that whereas PROUST bases its
analysis on problem descriptions, and generates goal decompositions for each program,
Micro-PROUST bases its analysis on hand-coded goal decompositions written by us. These goal
decompositions are organized into a library, just as PROUST's problem descriptions are
organized into a library. When Micro-PROUST analyzes a program, it retrieves the appropriate
goal-decomposition description, and uses it to understand the program.
Micro-PROUST assumes that every solution to a given programming problem will have the
same goal decomposition. This assumption is untenable for harder programming problems, but
it may be tolerable if the programs are small.
In order to understand the effect of assuming a unique goal decomposition per problem, let us
compare PROUST's problem description for the Rainfall Problem with Micro-PROUST's goal-
decomposition description for the same problem. Figure 4 shows, in a stylized form, PROUST's
description of the Rainfall Problem. This problem description consists of two parts: a set, of
objects which the program manipulates, and a set of goals that must be satisfied. Objects are
the quantities of data that the program should manipulate. Two objects are defined in this
example: ?Dai lyRa in, the series of rainfall amounts, and ?Sentinel, the sentinel value. Object
• names are indicated by a preceding question mark. The goals are requirements that the program
must satisfy. For example, Average is the goal of computing the average of some set of values;
Output is the goal of outputting a value to the terminal. Goal names appear in italics. An
English paraphrase of each statement in the description of the Rainfall Problem, one line at a
U time, is shown in Figure 5.
. ................ ... ... ...
. . ....... .... .. ........ o . . . - - . . o _ - - . . . L , . . , . : _ . -
8
Define-Program Rainfall;
Define-Object ?Dai lyRain ObjectClass Seolortieasurement;Define-Object ?Sentinel Value 99999;
Define-Goal Sentinel-Controlled-Input( ?D9 I lyRa in, ?Senti nel );Define-Goal Input-Validation ?Dai lyRain, ?Dai lyRain < 0);Define-Goal Output( Average ?Dai lyRain ) );Define-Goal Output( Count( ?Do i IyRain ) );Define-Goal Output( Guarded-Count( ?DeilyRain, ?Doi lyRain >0) );Define-Goal Output( Maximum( ?DailyRain ) );
Figure 4: The problem description for the Rainfall Problem
* This problem is called "Rainfall".
* Define an object called Dai lyRa in; it is a scalar measurement, i.e., a non-negative realnumber.
* Define an object called Sent inel, whose value is 99999.
* Generate successive values of Dai lyRa in by reading them from the terminal, stoppingwhen Sentinel is read.
o Test Dai lyRain for validity, by ensuring that Di lyRain < 0 is never true.
* Output the average of Dai lyRain.
0 Output a count of the number of values that Dai lyRain takes.
* Output a count of the number of values in Dei lyRain for which Doi lyRain > 0 is true.
a Output the maximum of DailyRain.
Figure 5: A line-by-line paraphrase of Figure 4
Figure 6 shows Micro-PROUST's goal-decomposition description for the Rainfall Problem.
There are a number of differences between this description and PROUST's problem descriptions.
For example, there are no object definitions; object processing was dispensed with in
Micro-PROUST. As a consequence, Micro-PROUST must assume that all students will attribute
the same properties to the data being processed. For example, PROUST's description of the
Rainfall Problem indicates that the object ?Dai lyRain is a Scalmrteasurement, i.e., it is a non-
negative real number. PROUST's knowledge base includes a description of SealarMessurement,
specifying that objects of this type must be nonnegative and real. In Micro-PROUST there is no
knowledge base of types of objects All relevant facts about the objects being processed are
incorporated into the goals which are listed in the goal decomposition, or else are omitted. Thus
the requirement that ?Da i lyRe in must be non-negative is enforced by the InputValidation goal
a which checks each input of ?Doi IyRa in for validity. The fact that ?Dai lyRin should be a real
number is omitted; if a student declared the input variable to be an integer, Micro-PROUST
* would fail to detect the error.
The most significant difference between PROUST's description of the Rainfall Problem and
Micro-PROUST's description is that several goals have been added to Micro-PROUST's
S""description which are absent from PROUST's description. A Sum goal has been added to
compute the sum of the inputs, and three Guard-Exception goals have been added to check for
boundary conditions, such as division by zero. These goals are added in order to fill out the goal
decomposition. PROUST would add these goals automatically as needed, relying upon its
knowledge about goals. In Micro-PROUST's descriptions every goal must be made explicit.
Furthermore, Micro-PROUST assumes that every goal listed must be explicitly realized in theprogram using some plan. It is possible to solve the Rainfall Problem without summing the
inputs, and without checking for division by zero; Micro-PROUST cannot understand such
solutions because they do not fit the given goal decomposition.
Sentinel-Controlled-Input( ?New, 99999 )Input-Validation( (?New in goal Sentinel-Controlled-Input).
(?New in goal Sentinel-Controlled-Input) <0 );Average( (?New in goal Sentinel-Controlled-Input) );Count( (?New in goal Sentinel-Controlled-Input) );Output( (?Avg in goal Average) );Guard-Exception( (?Output: in goal Output),
(?Output: in goal Output) = 0 )"Output( (?Count in goal Count );Sum( (?New in goal Sentinel-Controlled-Input).
(?Suin in goal Average) )"Guarded-Count ( (?New in goal Sentinel-Controlled-Input).
(?New in goal Sentinel-Controlled-Input) > 0 );Output( (?Count in goal Guarded-Count) );Maximum( (?New in goal Sentinel-Controlled-Input) )"Output( (?Max in goal Maximum) );
* Guard-Exception( (?Output: in goal Output).(?Count in goal Count) = 0 );
Guard-Exception( (?Update: in goal Average).
(?Count in goal Count) = 0 );
Figure 6: Micro-PROUST's goal decomposition for the Rainfall Problem
. . . . . . . . . .
10
5.2. The goal database
PROUST and Micro-PROUST both have knowledge bases of programming goals. Each goal in
Micro-PROUST's knowledge base is also in PROUST's knowledge base. However,
Micro-PROUST's knowledge base contains less information about each goal. All knowledge
needed in PROUST in order to construct goal decompositions has been removed, since
Micro-PROUST cannot construct goal decompositions automatically. What is left are the names
of plans which implement the goal, and an English phrase describing the goal. Figures 7 and 8
show the same goal, Input-Validation, as they appear in PROUST's and Micro-PROUST's
databases, respectively.
Input-Validation
Form: Input-Validation (?Val . ?Pred)Name phrase: 'input validation"Main component: Guard:Instances: BAD INPUT SKIP GUARD
O BAD INPUT LOOP GUARD
Figure 7: A goal in PROUST's knowledge base
Input-Validation
Name phrase: 'input validation"Instances: BAD INPUT SKIP GUARD
BAD INPUT LOOP GUARD
Figure 8: A goal in Micro-PROUST's knowledge base
5.3. Plans
There is a close relationship between plans in Micro-PROUST and plans-in PROUST. Every
plan in Micro-PROUST's knowledge base is also in PROUST's knowledge base. However,
Micro-PROUST's plan knowledge contains less information about each plan, and the plans
cannot be used in as wide a range of cases. These points wiU be illustrated via a specific
example, the BAD INPUT LOOP GUARD PLAN, which is an implementation of the goal
Input-Validation. This plan checks input data for validity, and repeatedly rereads the data until
it is valid.
Figure 9 shows Micro-PROUST's version of the BAD INPUT LOOP GUARD PLAN. Like all
plans in Micro-PROUST it consists of Pascal statements to match against the program, and
pointers indicating where the plan should match. The Pascal statements consist of a WHILE loop
... ..... ... ...Ux - . . .. , , i ...:. .. i: - " , , ; ' ; . " , " -- ' , -' " . " . , , ,' - " i " " " : : . - : "_ _.
) 11
containing a WRITELN statement and a READ statement, followed by an IF statement testing for the
sentinel value. The pointer indicating where to match the plan is at the top of the plan
template; it indicates that the plan should be found in the part of the plan implementing the
goal Sentinel-Controlled-Input which is labeled Process:. In other words, the plan should be in
the part of the loop that processes the input data. Note that this plan is quite specific; it will
only work in sentinel-controlled loops, and even then it will not match if a READLN statement
appears in the program instead of a READ statement.
BAD INPUT LOOP GUARD
Template:(in component Process: of goal Sentinel-Controlled-Input)
Guard: WHILE ?Pred DOBEGIN
WRITELN( ?* )'Input: READ( ?Val )
END;InternalIGusrd: IF ?Val <> ?Stop THENProcess:
Figure 9: Micro-PROUST's BAD INPUT LOOP GUARD PLAN
Figure 10 shows PROUST's renditioD of the BAD INPUT LOOP GUARD PLAN. The main
difference between the two plans is that PROUST allows subgoals to be inserted into the plan.
These subgoals become part of the goal decomposition that PROUST constructs for the
program. The subgoals can be implemented using different plans, thus increasing the variety of
code that the plan can match. Instead of referring specifically to the goal
Sentinel-Controlled-Input within the plan, PROUST's plan refers to a generic class of goals
called Read & Process. This class denotes all goals which involve the inputing and processing of
data.
5.4. Plan-difference rules
When a plan fails to match the student's program exactly, the differences between the plan
and the code must be explained. By explaining a plan difference we mean suggesting a bug
which would produce the detected plan difference, as well as misconceptions which can cause the
bug. PROUST and Micro-PROUST both use plan-difference rules to explain plan differences.
These rules are test-action pairs, where the test part examines the plan differences and the action
indicates what if any bugs these plan differences suggest. There is a correspondence between
............... .: . :---"-_;. '?.:.
* 12
BAD INPUT LOOP GUARD
Variables: ?VoI, ?PredTemplate:
(in component Process: of goal Read O Process)spanned by:
Guard: WHILE ?Pred DOBEGIN
subgoal Output DiagnosticC)Next: subgoal Simple Input(?Va I)
END* - Process: ?** .Posterior goals:' Sentinel Guard((?New from goal Read 8f Process),
(?Stop from go al Read & Process))
Figure 10: A plan for implementing Input-Validation
plan-difference rules in the two systems, although the tests and actions of the rules tend to differ
in certain respects.
Si-To see how plan-difference rules are used in the two systems, we will examine how they explain
one of the bugs in the example in. Figure 2. This program uses the BAD INPUT LOOP GUARD
* to implement the goal Input-Validation, but there is no test for the sentinel value after the W'XLE
loop at line 24. PROUST discovers the match failure when it is processing the goal
" Sentinel-Guard, a subgoal of the BAD INPUT LOOP GUARD PLAN. The plan-difference rule
" which accounts for the natch failure in PROUST is sbown in Figure 11. The rule checks
whether the sentinel guard is the only plan that is missing, or whether the input step is also
missing. If the input step is missing, there is no reason to complain about the sentinel guard
being missing, since the missing input is the more important bug. If the input step is present,
the rule checks to see whether there are sentinel guards elsewhere in the loop which might serve
the function of the missing sentinel guard. When no other sentinel guards are present, the rule
' indicates that the missing sentinel guard is a bug, and it may have been omitted inadvertently
by the student.
IF no plans implementing Sentinel-Guard can be matched,* AND the input step of either BAD INPUT LOOP GUARD or the
main loop was found.AND no sentinel guards appear later on in the loop,THEN the sentinel guard may hove been omitted by mistake.
Figure 11: Rule for recognizing missing sentinel guards
V,.
13
The corresponding rule in Micro-PROUST, shown in Figure 12, is much more direct. It simply
checks to see whether the missing plan component is labeled InternalGuard:. If so, it may have
been inadvertently omitted. The sentinel guard in the BAD INPUT LOOP GUARD PLAN is
labeled InternaIGuard:, as ran be seen in Figure 9. Therefore the rule applies. Because
Micro-PROUST's rule is simpler, it will apply in some cases where it should not. If the senLinelis tested in an unusual but correct way, Micro-PROUST is likely to indicate that the sentinel
test is buggy. Micro-PROUST's rules are not sensitive to correlations between bugs, so it cannot
detect when one bug might be the cause of the other.
IF a plan component of type InternalGuard: cannot be matched,THEN it may have been omitted by mistake.
Figure 12: Micro-PROUST's rule for missing guards
Some plan-difference rules in PROUST not only explain the plan differences; they also correct
them. For example, rules which identify when BEGIN-END pairs are missing insert the missing
BEGIN-END pairs into PROUST's internal parse-tree representation of the code. Subsequent
analysis of the program will then proceed as if the BEGIN-END pairs were present in the student's
program. If PROUST did not insert the BEGIN-END pairs, it might misunderstand the intended
data flow of the code, and signal bugs which are really side-effects of the buggy block structure.
Micro-PROUST, on the other hand, makes no attempt to correct bugs. It therefore is more
likely to signal more bugs than are really present in the program.
6. Additional Comparisons of PROUST and Micro-PROUST
In Figure 13 we present further comparisons of PROUST and Micro-PROUST along a number
of key dimensions. PROUST has been under development for some 4 years, and is the successor
to MENO, an earlier version of our bug identification system 1g]. In contrast, Micro-PROUSTwas not a research effort but could draw directly on our experience in building bug analysis
systems. PROUST is faster than Micro-PROUST as long as enough memory is available.
However, PROUST needs two megabytes of memory to run comfortably; if a VAX is heavily
loaded, PROUST slows down substantially, and Micro-PROUST is then faster. The difference
in size of the two programs is dramatic; Micro-PROUST is only I0% of the size of PROUST! Inthe next section, we address the natural question: can Micro-PROUST be scaled up to the level
of PROUST's performance, and still have acceptable time and space characteristics?
14
PROUST Micro-PROUST
Cost: - $450,000 - $25,000
Time: 4 years 2 months
Coverage: 2 programming 1 programming assignment
assignments
Bug Catalogue: - 50 - 10
Size: 15,000 lines of LISP 1500 lines of LISP
Machine: DEC VAX 750 (4 Meg) IBM PC (512 K)
Run time: .5 - 3 minutes -90 seconds
Performance: 75/ of bugs unknown
correctly identified
Figure 13: Fact Sheet: PROUST and Micro-PROUST
7. Scaling Up Micro-PROUST
We will now examine some of the issues which we expect will arise whe.n Micro-PROUST is
scaled up to approximate PROUST's performance in finding bugs. We will focus on two issues:
the problems involved in expanding Micro-PROUST's knowledge bases, and the limitations that
Micro-PROUST's simplified architecture impose.
In order for Micro-PROUST to cover a wide range of novice programs, its knowledge bases will
have to be greatly expanded. In PROUST, 4000 lines of code are needed to specify goals, plans,
and plan-difference rules. We have seen that Micro-PROUST's knowledge bases correspond
closely to PROUST's. Since Micro-PROUST's knowledge is simplified, the same knowledge
units would take up less space in Micro-PROUST than they would in PROUST. On the other
hand, Micro-PROUST's plans are not as general as PROUST's, since they cannot contain
15
subgoals. This will probably mean that more plans will have to be added to Micro-PRO1UST
than appear in PROUST. It is clear that Micro-PROUST's knowledge bases will be sizeable, and
will press against the space limitations of the IBM PC.
It should be possible to organize Micro-PROUST's knowledge bases so that space limitations
are avoided. Only a fraction of Micro-PROUST's knowledge need be available at any one time.
For example, when a particular goal is being processed, the only plans that need be in memory
are those which implement that goal. It therefore should be possible to store Micro-PROUST's
knowledge on disk, and retrieve knowledge only as needed. Micro-PROUST's speed would be
reduced because of this, so it is hard to say whether the resulting system would be fast enough to
use in the classroom.
The more troubling problems with Micro-PROUST stem from the reduced power of its analytic
techniques. Micro-PROUST assumes that all solutions to a given programming problem will
have the same goal decomposition. It is prone to misdiagnosis of novice bugs. These
shortcomings may limit Micro-PROUST's effectiveness, or may necessitate enhancements of
Micro-PROUST's diagnostic capabilities.
The effect of restricting the goal decompositions of programs depends on the complexity of the
problem. The more goals there are that must be satisfied in a program, the more ways there are
that these goals can be combined. The range of possible goal decompositions therefore increases
rapidly as problem complexity increases. Our empirical studies of novice programs indicate that.
40% of novice solutions to the Rainfall Problem fail to conform to Micro-PROUST's goal
decomposition for this problem. Micro-PROUST cannot avoid making frequent analysis errors
as long as its model of students' intentions is faulty this often.
Even if Micro-PROUST's goal decomposition is correct, there may still be cases where
Micro-PROUST misdiagnoses bugs. As indicated earlier, Micro-PROUST does not correct bugs
when it finds them; therefore the presence of some bugs may cause Micro-PROUST to
misdiagnose other bugs. Furthermore, unlike PROUST, Micro-PROUST has no way of choosing
between alternative interpretations of the code. It does not notice if more than one plan can
match the same lines of code. Instead, Micro-PROUST simply chooses the first account of the
code that it comes across. Micro-PROUST's accuracy will stuer because of this, but the extent
of the performance degradation is hard to predict. Empirical evaluations of Micro-PROUST will
- - - -- - -. - - - - - - - - - - - - -
16
be Deeded to determine exactly how accurate its analysis can be expected to be.
8. Concluding Remarks
As a demo, Micro-PROUST unquestionably allows one to quickly see tbe potential for
computer-based enhancement of learning. However, a~s a product, it is still unclear whether or
not Micro-PROUST can ever be even approximately as effective as its parent, PROUST, running
on a large machine. However, we believe that Micro-PROUST's knowledge can be expanded
without running into space limitations. The resulting system should be reasonably effective, at
least on simple programming problems- Further work will be required to determine how
effective Micro-PROUST's approach can be, and whether or not it will result in a viable
educational tool.
17
References
1. Fosdick, L.D., and Osterweil, L.J. "Data flow analysis in software reliability". ComputingSurveys 8, 3 (1976), 305-330.
2. Harandi, M.T. Knowledge-Based Program Debugging: a Heuristic Model. Proceedings of the1983 SOFTFAIR, SoftFair, 1983.
3. Johnson, W.L., and Soloway, E. "PROUST: Knowledge-Based Program Understanding".IEEE Transactions on Software Engineering SE-11, 3 (1984), 267-275.
4. Johnson, W.L., and Soloway, E. Intention-Based Diagnosis of Programming Errors. Proc. ofthe Nat. Conf. on Art. Intel., AAAI, 1984, pp. 162-168.
5. Johnson, W.L. and Soloway, E. "PROUST: An Automatic Debugger for Pascal Programs".Byte 10, 4 (1985), 179-190.
6. Johnson, W.L. Intention-Based Diagnosis of Programming Errors. forthcoming, YaleUniversity Department of Computer Sci., 1985.
7. Lukey, F.J. "Understanding and Debugging Programs". Int. J. of Man-Machine Studies12 (1980), 189-202.
8. Shapiro, E.. Algorithmic Program Debugging. MIT Press, Cambridge, Mass., 1982.
9. Soloway, E., Rubin, E., Woolf, B., Bonar, J., and Johnson, W. L. OMENO-II: An Al-BasedProgramming Tutor". Journal of Computer-Based Instruction 10, 1 (1983).
10. Soloway, E. and Ehrlicb, K. "Empirical Investigations of Programming Knowledge".IEEE Transactions on Software Engineering SE-1O, 5 (1984).
11. Wertz, H. "Stereotyped program debugging: an aid for novice programmersm . Int. J. ofAlan-,Mfachine Studies 16 (1982), 379-392.
.,.-. ,.:..,...,-,-.- . . ... .. ..... . . .. . . . . ., . .
Micro-PROUST Code Page 5
5. Micro-PROUST Implementation: The LISP Code
Micro-PROUST Code Page 12
there are none left to try.(defun plan-match (plans)
(coed ((null plans) 0)((ins-status (car plans)) (plan-match (cdr plans)))
(t (list-plan (car plans))
(cond
((match-s-plas (car plans)) (car plans))
(t (plan-match (cdr plans)))))))
Recursively try to match each line of the plan by calling match-component.
If all the components match, return T. else block the plan and return nil.
(defun match-a-plan (plan)
(cond ((match-component plan (ins-address plan))
(and exec-out (foraue chek-vindov OT'St))
(coed ((equal (incf (ins-address pis))
(length (ins-matches plan)))
(cond (exec-out
(forest t USPlsn 'a matched codel (ins-name plan))))
t)(t (match-a-plen plan))))
(t (setf (ins-status plan) t)(and eec-out
(forest t O'SNatch errors in plan 's.0 (ins-name plan)))
0)))
Call context-nodeset to get a list of possible modes end pass this list
along with the plan component to nrefer. xlbel, or smatch, depending on
what type of match instruction it is.
(defun match-component (plea address)
(lete ((plan-linme (get-plan-element plea address))
(aodeset (context-nodeset (caddr plan-line) plan)))
(case (car plan-line)
((refer) (urefer pla-line plan address))
((label) (alebel plan-line plan address))
((match) (xsmtch plea-line plea address)))))
Get the plan-line for match-composeat
(defsa get-plan-element (plea address)
(aref (get (ins-snme plan) 'template) address))
Contezt-nodeset
Conteit-nodeset eses the third argmest in a plan component to enostruct
a list of nodes which can be matched. The third argument is a list of zero.
one. or two elements. Context-modeset-1 creates a list of nodes based on
the first element if it exists and context-sodeset-2 modifies this list of
nodes based on the second element if it exists. See the Spec for element
descriptions.
(defs contest-nodeset (context plan)
(context-nodeset-2 (cdr context) plan
(context-modeset-I context piss)))
Get a list of nodes based on the first element of the contest descriptor
or return the list of the highest level begin block for a nll context
descriptor
(defmn context-nodeset-I (context plan)
(coed((null context) (get-begin-block (node-children oparse-trees)))
Micro-PROUST Code Page 1
(and exec-out (forest plan-window 01m0 (aref taplt i))(and Caret (ins-matches plan) i)
(and eiec-out (forest chek-window 8T'%)))))(and cisc-out (any-key)))
List-goal lists the goal name in the goal-wiadow.(defun list-goat (goat)
(and exec-out (send goat-window :clear-screen))(and exec-out (format goat-window OCurreat Goal Name: -a* (car goat)))(and exec-out (any-key)))
Any-key prints out a message sad waits for a carriage return to continue.(defun any-key 0)
(cond (exec-out(format cisc-window 9'IEnter Carriage Return to Continue -- 0)(read-lin*excic-window))(t(format t OlEnter Carriage Return to Continue -6)(read-I ins))))
Put is a function from older lisps that I was used to using.(detain put (x y z)
(setf (get I Y) Z))
DPS (vanl sloti fit lent slot2 filler2 . .. ) adds properties sloti. slot2.etc.to the property list of vanl. It is used to build all of the propertylists.
(defacro DPS (want &body slot-fill)(cond ((oddp (length slot-fill))
(error ODPS: Bad number of argueetsg))(t (DPS1 vanl slot-fill))))
Auxiliary function to OPS(detain DPS1 (wart slot-fill)
(coed ((null slot-fill) t)(t (proga (put vant (car slot-fill) (cadr slot-fi II))
(DPS1 wart (cddr slot-fill))))))
Load the Hatch groupContains the following functions and their supporting functions:
plan-match. match-a-plan. match-compoment. cootezt-modeset. irefen.xlabel. imatch. get-candidates, sod match-stat.
Hatch sub-group of Micro-Proust NATCH2.lspWrittena by Bret Wallach 10/24/84
This section of code follows the Micro-Proust design spec fairly well.Refer to it for further details.
Defies a match-frame(defstruct match-framet
(code@0(bindings 0)(errors 0))
High level Natch functions.
Try to match each unblocked (ins-status, is oil) plan until one matches or
Micro-PROUST Code Page 10
;modes so they are not matched apeis later.(defus close-goal (goal plan)
(proga(push (cons goal plan) eamalyzed-goalse)(mark-stats plan)))
Rark each node as matched unless the fourth argument of the piea lime is Tor the first argument is a Refer or Label command.
(defun mark-stats (plan)(let* ((tplt (get (ins-mie plan) 'template)
(modes (ims-matches plan))(a (length nodes)))
(do*
((- i Ws)
(coed ((equal (car (aref tapit i)) 'match)(setf (node-mark (car (aref modes i))
(not (car (cdddr (oref tapit i)f))(t 0)))))
If none of the plans uork for a goal, declare it missing(defun missing-goal (goal)
(and exec-out (format t 0'Goal 'a is sissingO (car sacti ve-goole)))(setf ebug-reporte (append ebug-reporte (list (list (car eactive-goale))))))
Report the bugs
For each bug call report!. Report! determines if there is a reportingfunction defined for that type of bog and calls it if it exists.
(defus report-bugs ()(foreat t a-I-1 -*eeceeeg Reports*$*** 5
(sapc Oreportl ebug-reporte)(format t 0-I-1 oseeEad of Report**C**ec-1@ 12)t)
The car of a bug is the bug name. If it has m 'report-fun property.retrieve it and call it with the rest of the bug as an argument. Seethe spec for details.
(defun report! (bug)(let ((ut-fumc (get (car bug) 'report-fun)))
(cond (bvg-func (foreat t * i(funcall bug-fuac (cdr bug)))
(t 0))))
Utilities
List-plea lists the plan components, of plea in the plom-windov.(defun list-plan (pla)
(and exec-out (send plan-window :clear-screen))(sod evec-out (send chek-windov :clear-screen))(and exec-out (foreat plan-window OInlm-nose: '98 (ins-name plea)))(late ((tapit (get (ins-nmeo Plan) 'template))
(nodes (ins-matches Plan))(a (length modes)))
(do*
((0 i M
Micro-PROUST Code Page 9
(process-next-goal)(coed (exec-ovt
(any-key)(send estandard-output* :set-size 80 25)(send *standard-outpute :clear-screen)(with-open-file
(ons prog :direction :input :element-type 'strin-char)(pparse))))
(report-bugs))
Initialize the agenda
Reads the problem file into the global variable *agendee. Also initializes*active-goals*. eanelyzed-goalss. *beg-report*.
(defu. init-agenda (problem)(progn
(with-open-file(ous problem
:direction :inpvt :element-type 'string-char)(setf *agenda* (read ous)))
(sett *active-goale 0)(setf *analyzed-goalse O)(setf ebu-reporte 0)))
Process the goals
Pops a goal off the top of *agenda*, instantiates the goal, processes thegoal and repeats until there are no goals left. It also call list-goalfor each goal which lists the goal and bindings in goal windov.
(defve process-next-gol ()(cond
(,egendee
(list-goal (car *agende))(progs (process-plans (iastaetiete (get-nset-goal)))
(process-next-goal)))(t t)))
Pops a goal off the top of *agenda*.(defun aet-%ext-goal 0
(setf eactive-goale (pop ea*geds*)))
Processes each plan returned by instantiate sntil one of the@ matches theprogram code or none of then matched end the mismatches can't be explained.
(defu process-plans (plans)(let ((good-plan ()) (new-plans plans))(do 0
((or good-plan (nell new-plans)))(setf good-pla (plan-match plaes))(coed ((evil good-plan)
(setf nea-plas (explain-misaetches plans)))(t 0)))
(cond (good-plan (close-goal (car *active-goals) good-plan))(t (missing-goal eactive-goal*)))))
Close the goal
If the goal had a pla that matched. remember it sod mark all the matched
".. . .. "
Micro-PROUST Code Page 8
;; Title-page
Prints title page in beginning of program
;;(defun Title-page )* (format t
NICRO PROUST
A PASCAL Programming Tutor
Designed By:
Elliot Soloway A V. Lewis Johnson.. Yale University
Implemented on the IOB PC By:
Bret Wallach. Advanced Processing
Leszek Izdebski. Coursevare. Inc.
Parser calling functions
This function displays the program file on the screen (using pparse).
and parses the file using the function parse. Doe to a bug in OCLISP.
I vas unable to specify a larger initial stack group. As a result. I
create a special stack just for parsing.
(defun parse-coll (filename)(format t *'ILexing *as filename)
(with-open-file(ous filename direction :input :element-type 'string-char)
(pparse))
(stack-group-preset *no 'parse fileae)(format t 0RParsing "ao fileme)(funcall see nil)(and exec-out (any-key)))
*; Display the program on the screen.(defun pparse )
(do ((s (read-line ous 0 t) (read-lime ous 0 t))
(i 1 (* i 1)))((equal x t))(format t m''d 'a i a)))
(setf so* (make-stack-group 'ea :regular-pdl-size 3800:special-pdl-size 3800))
This function initialized the goal agende, processes the goals, and reports
the errors found.(defa oproust (problem)
(imit-agoda problem)
. . . . . .. . .
Micro-PROUST Code Page 7
:- (any-hey))
(t (format t $'Unable to parse filel?l?')
(foreat t 0'SPlesse fix syntax errors and try again.*)
(any-key)))))(send *standard-outpute :set-size 80 25)
(do-question))(dribble)
(exit)))
(defun do-question 0(send *standard-outpute :clear-screen)
(forst t *Your options are:6)(format t 81 0: Run Proust oa EXANPLEA (average probles)')(formt t O'S 1: Run Proust on EXAMPLEI (average problem)')
(forent t O'S 2: Run Proust on EXANPLE2 (average problem)')
(forest t 01 3: Run Proust on EXANPLE3 (rainfall problem)*)(format t 9' 4: Run Proust on EXANPLE4 (rainfall problem)')(forest t 0' 5: Run Proust on EXANPLES (rainfall problem)')
(forest t 'S 6: Run Proust on EXANPLER (rainfell proble)')(exec-ovtput)
(format t '1 8: Exit.')
(format t 'Enter option: ))
(defun exec-output 0
(coend (exec-out(format t ' 7: Disable execution output (currently enabled)'))
(t(foret t B'1 7: Enable execution output (currently disabled)'))))
5 .This function filters out reader errors that would othervise cause the
program to bomb.(defue safe-read 0
(multiple-value-bind (what err)(ignore-errors (read))
(cond ((nall err) what)(t (format t a'Input error, please re-enter "')
(safe-read)))))
This function filters out reader sad string function errors that wouldotherwise cause the program to bomb.
(defun safe-string-reed 0(multiple-value-bind (what err)
(ignore-errors (string (rend)))
(cond ((null err) what)(t (foret t ' Inpmt error, please re-enter.5'O)
(safe-strinmgread)))))
This function filters out reader @nd string function errors that wouldotherwise cause the program to bomb.
(defn safe-p-read 0(multiple-value-bind (what err)
(ignore-errors (read))
(coned ((and (null err)(integerp whit)
0- what 0)(4- what 8))
what)(t (forest t e'%Inpnt error, please re-enter.5'9)
(safe-p-read)))))
"-"" " -"p- ""-" " ' +"' " """"" "" - " " .+" ."" ", '* " -.*-"" " "+ '"" .i," ' " ""+.''' . + ..
Micro-PROUST Code Page 8
1.3 MPROUST.LSP
Mtaproust.Isp.. icro-PROUST calling functions NPROUST.LSPWritten by Bret Wallach of Advanced processing on 10/23/84
for Courseware. lee.
Welcome to Nicro-PROUST. This code follows the desigm specificationwritten by V. Lewis Johnson fairly well, so refer to that Spec whem
- . necessary
Authors do not guarentee the performance of this program is may way norwill they accept responsibility for say problems resulting from the usof this code.
This is the top level function. It sets up four windows. Exec-viedow isa two line window at the bottom of the screen used by any-key to wait fora CCR) before proceeding. Plea-vindow contains the plan currently beingmatched, chek-window contains a T for etch component of the plan thatmatched, and goal window contains the current goal and a list of initialbindings. This function asks for the program file and a problem descriptionidentifier It then calls parse-call to parse the program and sproust to
* do the analysis assuming it was possible to parse the program.(defun an-proust 0)
(let ((exec-window (make-window-stream *top 23 :height 2))(plan-window (ake-window-stream :top 12 :height 11 :left 3))(chek-window (make-window-stream :top 13 :height 10 :width 3))(goal-window (make-window-stroe -top 3 :height 3)))(close-all-files)(send *standard-outpvts :clear-screen)(delete-file (merge-pathass msysoot-datm ddev))-I:'>(dribble (merge-pathasses msysout.dst9 ddev))(do-question)(do ((p (safe-p-read) (safe-p-read)))
* ((equal p 8))(cond ((equal p 7)
(setf ezec-out (not ezee-omt)))((and (setf prog (car (aref efiles p)))
(setf q (cadr (aref efiles p)))(multiple-value-bind (ig err)
(ignore-errors (close (open prog :direction :input)))err))
(format t 0-9 ile 'a not fomed. 1 prog)(any-hey))((multiple-value-bind (ig err)
(ignore-errors (close (open q :direction :input)))err)
(forest t a-vile 'a Not foved.* q(any-hey))(t(parse-call prog)(cond (eparse-treec
(coed (exec-ost(send *standard-outpute :clear-scrien)(send 4steadard-output$ :set-size 80 8))(t(format t al'nalyzing program for errors ...
(sproest q)
Micro-PROUST Code Page 5
(NLNTIPLE-VALUE-BIHD(F AB8C D)(%SYSINT #X11 0 0 0 0)(0- (LSM (LOGAID A #XOocO) 6)))
-(WHEN (OR (NOT (BOIJNDP S$NENORY-ALLOCATED-Ps))* . (NOT *NENORY-ALLOCATED-Ps))
(ALLOCATE #X8OO 3. 2. T) ;allocate, all OS son but 32K
* - (SETO *NEHORY-ALLOCATED-Ps T))
(load 'lisplib\\defmac.lsp8)(load 1 ispl ib\\defstruct. lspw)
(LOAD Olisplib\\DRIBBLE.Ispl) *DRIBBLE function
- -~-~ - -~ ~ .-- ~- K
Micro-PROUST Code Page 4
(IF (PROBE-FILE (FIRST W)(APPLY 'OPEN X)
(PROGN(FORMAT T "&Insert diskette for file 'A in drive -A.
Type any character when ready.9(NAMESTRINO (CAR W)(PATHNAME-DEVICE (CAR X)))
(READ-CHAR)(APPLY 'SAFE-FILE-OPEN W)))
its rather important that this is HERE. not eutoloadedFor closing all currently open files.
(DEFUN CLOSE-ALL-FILES0(NAPCAR '(LAMBDA (FILE-STREAM)
(PROGI (FILE-STREAM :PATHIANE)(FILE-STREAN :CLOSE)))
*OPEN-F IE-STREAMS.))
- . (SETO *DEFAULT-PATHNAME-DEFAULTS* (MERGE-PATHNANES (CD) GFOO.LSP8))
THE CCLISP toplevel help facility
(SETO *DEFAULT-IE-OPTIONSe'((E-CONNANDS (e\C-8 . (LAMBDA (&REST IGNORE) tB - bacitrace
- - (TERPRI T)(BACKTRACE)(TERPRI T)REFRESH))
(S\C-D . (LAMBDA (&REST IGNORE) CALT)-D DOS(FORNAT T 8*aGoing to DOS.. .)(DOS)REFRESH))
(#\C-G (LAMBDA WaEST IGNORE) Mo CLEAN-UP-ERROR(CLEAN-UP-ERROR)))
A \-L (LAMBDA (WEST IGNORE) I-CERSEN
(SEND *TERNINAL-IO* :CLEAR-SCREEN)REFRESH))
(#\C-P (LAMBDA (AREST IGNORE) tP(CONTINUE)))
(S\C-C .(LAMBDA WaEST IGNORE) t(STACK-GROUP-UNIND)))
(*ESC .(LAMBDA (BUF IGNORE)(LENGTH BUF)))
(1\RJBOUT . (LAMBDA (IGNORE IGNORE) <RUBOUT3, I CHAR1)
(DEFUN FIND-FUEC (81W)(LET ((lDX (I- (LENGTH BUW))))
6 (MEN (PLUSP loX)(DOTINES QI (LENGTH BUM)
* (IF (EQ *\V (CHAR BUF lOX)) (RETURN NIL))(DECF lOX))
(READ-FROM-STRING BUF NIL NIL :START (1* lOX)))))
(SETF *SINGLE-DISKETTE-DRIVE-SYSTEE.(EQ 1 (UNLESS *NUNBER-OF-DRIVES*
(SETF *NUNBER-OF-DRIVES*
Micro-PROUST Code Page 3
((NULL X) (NREVERSE RESULT)))))))"".(88 . IX
(LAMBDA (S &AUX (*READ-BASE* 15.))(READ S NIL NIL T)))
(92. A(LAMBDA (S)
(FUNCALL S :UNTYI 92.) put escape char back(DO ((STR (STRING (READ S NIL NIL 7)))
(BITS 0)
(I 0))(0)
(COND ((a (- (LENGTH STR) I) 1) 1 char left
(RETURN (CODE-CHAR (CHAR STR I) BITS)))
((STRING-EQUAL OC- STR :START2 I :END2 ( I 2))
(SETQ BITS (LOGIOR BITS 1)
I (. I 2)))((STRING-EQUAL §1-6 STR :START2 I :END2 ( I 2))
(SETQ BITS (LOGIOR BITS 2)I (+ I 2)))
((NAME-CHAR (SETQ STR (SUBSEQ STR I)))(RETURM (CODE-CHAR (NARE-CHAR STR) BITS)))
(T(ERROR OBad \§\#\\\g name: 'SO STR))))))
0-w--- (124. :61(LAMBDA (S)(DO ((CNT 0)
(CHAR (FUNCALL S :TYI) (FUNCALL S :TYI))
(LCHAR 0 CHAR))((AND (- CHAR 35.)(- LCHAR 124.)(ZEROP CNT)) NIL)
(COND ((AND (a LCHAR 35.)(a CHAR 124.))
(INCF CNT))((AND (m LCHAR 124.)(a CHAR 35.)(- CNT 0))
(DECF CNT))))))
Used by the #+ and - sacros(DEFUN 1#-FEATUREPI (F)(COND ((ATOM F)(NENBER F *FEATURES*))
((EQ (CAR F) 'NOT) (NOT (Il-FEATUREPI (SECOND F))))
((EQ (CAR F) 'OR)(DOLIST (I (REST F) NIL)(WHEN (Il-FEATUREPI I) (RETURN T))))
((EQ (CAR F) 'AND)(DOLIST (I (REST F) T)
(UNLESS (IS-FEATUREPI I) (RETURN NIL))))(T (ERROR *Bad #./- featre syntez: 'S" F))))
(DEFUN SHARP-NACRO (STREAM IGNORE LAUX X Y)(SETQ X
(ASSOC (CHAR-UPCASE (SETQ Y (FUNCALL STREAM :TYI)))*SHARP-SIGN-NACROSO))
(IF X(FUNCALL (COR X) STREAM)
(ERROR NIL gUadefimed \ ecro: 'CO Y)))
(SET-NACRO-CHARACTER 35. 'SHARP-MACRO)
Y,A SAFE VAY TO OPEN FILES
(DEFUN SAFE-FILE-OPEN (WREST X)
07
- -. . . . . -o.* .
Micro-PROUST Code Page 2
(IF (NOT (SYNBOLP (NTH 2 FRM))) FRI'(NACRO .(NTH 1. FRM) (.(NTH 2. FRM)) lame and arglist
(RPLACB .(NTH 2. FRN) macro's mrg(PROGN
pop off first eleet of erg list
(SETQ .(NTH 2. FRR) (CDR .(NTH 2. FRR)))
.NTHCDR 3. FRN)))))) splice in body
A simple DEFVAR macro
(DEFMACRO DEFVAR FRI
'(UNLESS (BOUNDP '.(CAR FeN))(SETQ .(CAR FRN) .(IF (> (LENGTH FRM) 1.)
(CADR FRN)
NIL))))
A simple DEFCONSTANT
(DEFMACRO DEFCONSTANT FRM
'(SETQ .(CAR FRM) .(CADR FRi)))
A simpel DEFPARANETER
(DEFNACRO DEFPARANETER FRR'(SETQ ,(CAR FRN) ,(CADR FRN)))
;;The Sharp sign macro character handlers.
(DEFCONSTANT *SHARP-SIN-NACROSC
(39. ;X'
(LANODA (S)(LIST 'FUNCTION (READ S NIL NIL T))))
(40.. ;#(
(LARBDA (S &AUX X)(FUNCALL S :UNTYI 40.)(SETQ X (READ S NIL NIL T))
(APPLY 'VECTOR X)))
(43. . :(LAMBDA (S IAUX (X (READ S NIL NIL T)))
(VALUES (READ S NIL NIL T) (NOT (Ig-FEATUREPI X)))))
(45. .-(LANMDA (S LAUX (X (READ S NIL NIL T)))(VALUES (READ S NIL NIL T) (Ie-FEATUREPI X))))
(46. . 6.(LANBDA (S)(EVAL (READ S NIL NIL T))))
(5. .:
(LANMDA (S) (COPY-SYNBOL (READ S NIL NIL T))))(66. ;08(LANDA (S &AUX (*READ-BASE* 2.))
(READ S NIL NIL T)))
(LARBDA (S LAUX (*READ-BASE* 10.))(READ S NIL NIL T)))
(7,. ;00(LAMBDA (S &AUX (*READ-BASE$ 8.))(READ S NIL NIL T)))
(83 ;IS
(LARBDA (S 1AUX (SPEC (READ S NIL NIL T)))
(EVAL (CONS (INTERN (STRING-APPEND NAKE-u (CAR SPEC)))(DO ((X (CDR SPEC) (Coon x))
(RESULT NIL (COLS '.(CADR X) (CONS (CAR X) RESULT))))
.T , Y ..
Micro-PROUST Code Page 1
1.2 THEINIT.LSP
ttttheinit.Isp
(C) Copyright Gold Hill Compters. a Division of Apiary. Inc. 1984
GOLDEN Common Lisp initialization file
(SETF *MONITOR-IS-COLOR* NIL*SINGLE-DISKETTE-DRIVE-SYSTENO NIL*NUNBER-OF-DRIVES. 2*BREAK-EVENT* '(LAMBDA (&AUX INPUT-EDITOR) (BREAK)))
(SETQ oBQ-LEVEL$ 0*BQ-COMMA0 (GENSYM)
*BQ--COMMA-AT* (GENSYM))
the famous back-quote macro(DEFUN BQ (X &AUX)
(COND ((NULL X) NIL)((ATOM X) (LIST 'QUOTE X))
((EQ (CAR X) 08Q-COMMA)(CADR ))
(T(DO* ((HOOK (NCONS 'LIST))
(Y HOOK (SlOC Y (9Q (CAR X))))(X X (CDR X)))
((NULL X) HOOK)(COND ((ATOM X)
(RPLACA HOOK 'LIST)
(SNOC Y (LIST 'QUOTE ))(RETURN HOOK))
((EQ (CAR X) eBQ-CONA-AT.)(RPLACA HOOK 'LIST.)(RPLACD Y (NCONS (LIST 'APPEND
(CADR X)(DQ (CDDR X)))))
(RETURN HOOK))
((EQ (CAR X) 'SQ-COMMAO)(RPLACA HOOK 'LIST*)
(RPLACD Y (NCONS (CADR )))
(RETURN HOOK)))))))
(DEFUN CONMA-NACRO (STREAM IGNORE &AUX X)(VNEN (<a *BQ-LEVELe 0)
(ERROR 'Coni not inside backqmote8))(IF (OR (EQ (SETQ X (FUNCALL STREAM :TYI)) 64.) is it go?
(EQ X 46)) or a 8.'*BQ-CONMA-AT*(FUICALL STREAM :UNTYI X) pot it back
(LIST *SQ-COMMA* (READ STREAM NIL NIL T))))
(DEFUN BQ-MACRO (STREAM IGNORE &AUX (a9-LEVEL* (I* BQ-LEVEL)))(BQ (READ STREAM NIL NIL T)))
(SET-MACRO-CHARACTER 44. 'COMA-MACRO)
(SET-MACRO-CHARACTER 96 'BQ-MACRO)
(MACRO DEFUACRO (FRN)
I ' - . . ' , , " , . . ' ' . . . . . ' . . ' . . • - . - - , . , . . - . . . ' - . . - . - . - . , . - . . . , - . . ,
I. The LISP Code
I.1 MPROUST.INI
*tttaproust muiload the lisp unit file
(load Ob theinit.Ispg)
default drive(setf ddev b:*)
default setting for execution output flag(setf exec-out t)
;;files(setf efiles'#
(6exampleaepasO inverage.prbO)(Oexamplel pusO Oeverage.prb*)(mexaaple2.pas moverage.prbO)(*[email protected] raimfel I.prbw)(mexample4.pgs* Oruimfall .prb)(OoxaupleS.pas* wrainfoll.prbO)
--- (8exuupler.pasO reinfall.prbO)
micro-proust code file* *(load Ob:files\\uproustw)
Micro-PROUST Code Page i
Table of ContentsI The LISP Code ............ .................................. 0
1.1 MPROUST.INI ............ ............................... 01.2 THEINIT.LSP ............ ............................... 11.3 MPROUST.LSP ............ .............................. 61.4 DEFMAC.LSP ........ ................................ .... 421.5 DEFSTRUC.LSP ........... .............................. 451.6 DRIBBLE.LSP ........ ............................... .... 49
II Sample Pascal Programs ........... .............................. 51' 11.1 EXAMPLE1.PAS ....... .............................. .... 51
11.2 EXAMPLE2.PAS ....... .............................. .... 5211.3 EXAMPLE3.PAS .............................. 5311.4 EX M LE A . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5
11.4 EXAMPLES.PAS.......... .............................. .5
11.6 EXAMPLEA.PAS. .. .. .... ..... ..... ..... .... .... 5811.7 EXAMPLER.PAS ....... ............................. .... 57
Ill Problem Specificatiorn ............ .............................. 58111.1 AVERAGE.PRB ........... .............................. 58111.2 RAINFALL.PRB ......... .............................. 59
0
9°
S, -
V
S,.
S . . . . -. r . .. .. .. . . -- - - - - 7- .- ..- . .
Micro-PROUST Code Page 13
((equal (caar context) 'at)(aref (ins-matches plan) (- (cadar context) 1)))
((equal (caar context) 'containing)(get-ancestors (list (node-parent (context-node context plan)))))
((equal (cear context) 'above)(above (context-node context plan)
(node-children (node-parent (context-node context plan)))))((equal (caar context) 'below)(below (context-node context plan)
(node-children (node-parent (context-node context plan)))))(t (get-begin-block (node-children eparse-treee)))))
-odify the node-list based on the second element of the context descriptorif it exists.
(defun context-nodeset-2 (context plan node-list)(cond
((null context) node-list)((equal (caar context) 'top)(list (car (node-children (car node-list)))))
((equal (caar context) 'bottom)(last (node-children (car node-list))))
((equal (car context) 'above)(above (context-node context plan) (node-children (car node-list))))
* ((equal (caer context) 'below)(below (context-node context plan) (node-children (car node-list))))(t node-list)))
Context-nodeset supporting functions
Context-node returns the list of nodes located in ins-matches (context].(defun context-node (context plan)
(car (aref (ins-matches plan) (- (cader context) 1))))
This function returns all of the siblings in Is that occur above thestatement represented by node.
(defun above (node Is)(cond
((nuIl Is) 0)((equal (car Is) node) 0)
*. (t (corns (car Is) (above node (cdr Is))))))
*." This function returns all of the siblings in Is that occur below thestatement represented by node.
(defun below (Node Is)
-V (coed((null is) 0)
*.. (t (cdr (member node Is)))))
This function returns the node of the airn begin block of the program(defun get-begin-block (nodes)
(coed((null nodes) 0)
. ((equal (node-name (car nodes)) 'begin) (list (car nodes)))(t (get-begin-block (cdr nodes)))))
This function returns a list of all direct ancestors of the nodes in nodes.It is used for the Containing descriptor.
(defut get-ancestors (nodes)
. . .. ... .. ,. . . , . , .
Micro-PROUST Code Page 14
(coed((null (node-parent (car modes))) modes)(t (get-ancestors (cons (node-parent (car modes)) modes)))))
Xmatch functions
This function calls get-candidates to modify the modeset crested byContext-nodeset and call imatch-frsoe to set-up end execute a match-stat.
(defum xatch (plan-line piss address)
(coed((equal (cadr plan-line) '(vars *))(setf (ins-matches pls) modeset)
t)(t(xaatch-frmee (cudr plan-line)
(get-cadidats (cedr plm-lime)(caddr ples-lime)modeset)
plan address))))
This function creates a match frame and calls match-stat for each possiblecandidate in candidates until one matches or they all do't match Thematch frame for each candidate the douse't match is pushed osat the
* partials list of the plan. If a candidate is watched. them may biediagsaccumulated during the matching process are added to the plan bindings.
(defun netch-frame (pattern candidates piss address)(coend
((null candidates)
(setf (ins-status plea) t)0)
(t (let ((at (make-astch-frase)))(setf (uatch-frame-code mt) (car candidates))
(coed ((match-stat pattera of)(setf (aref (ins-matches plan) address)
(list (car candidates)))
(coed ((metch-frame-bindings of)(setf (ins-bindiags plun)
(append (match-frame-bindings of)
(ins-bindings plan)))))
(t (push of (ins-partivls plan))(iatch-frame patters (cdr candidates)
plan address)))))))
Ct candidates functions
Cet-candidates first calls modify-nodeset which may add the children ofthe the contat-nodeset to nodes depending an the context descriptor. See
the Spec for further details. Get-cod-live filters out modes that havealready been marked or are the wrong type of ode.
(defve get-cendidates (stat des odes)
(get-cend-live (stat-table stat) (aodify-modeset des modes)))
This functio returns a list of nodes which are of the some statement type
as an element of stits sad have not been mrked as atched.
(defun get-cand-live (stats modes)(coend
J- - -. -. . . . . .--
Micro-PROUST Code Page 15
((null nodes) 0)((and (member (node-nome (car modes)) stats)
(null (node-mark (car nodes))))
(cons (car nodes) (get-cand-live stats (cdr nodes))))
(t (get-cand-live stats (cdr nodes)))))
This function returns a list of statements which are similar or identical tostat.
(defun stat-table (stat)(or (get 's-table stat) (list stat)))
Table of similar statements
(dps s-tableif (if while)
*while (if while)read (read :-)
:= (read A))
This function returns either nodes or nodes and the children of modes
depending on des (the context descriptor).
(defum mod ify-nodeset (des nodes)
(cond((and (equal (caur des) 'at)
(or (equal (camdr des) 'top)(equal (coadr des) 'bottom)))
nodes)((equal (caar des) 'containing) nodes)
(t (add-children nodes))))
This function returns nodes and the children of nodes
(delun add-children (nodes)(cond
((null nodes) 0)((atom nodes) (cons nodes (add-children (node-children nodes))))
(t (malpca *'add-children nodes))))
Xlabel
This function set ins-matches of the curret pla address to be the
current context-nodeset. It also inserts the label and nodeset into the
bindings list of the plan so it can be refered to later by other plans.
(defun xlabel (plan-line pil address)(setf (aref (ins-matches plan) address) nodeset)(push (cons (cadr plan-line) nodeset)
(ins-bindings plan))* t)
;Xrefor
This function retrieves a list of modes from the bindings list of analyzed
plans. It uses the second element of the plan-lies as the label.(delve xrefer (plea-line plan address)
(let ((war(cond
((null (cdr (cdedr plss-line)))(cdr (mapcm #'(lambda (i) (member (car (cdadr plan-line)) x))
(ins-bindings pila))))
[-.-
Micro-PROUST Code Page 18
(t (resolve-var-ref (car (cdadr plun-lime))(cadr (cdmdr plan-line)))))))
(setf (iref (ins-matches plan) address)(cond (war war)
(t (get-begin-block (mode-children eparsm-treee))))))t)
Hatch-stt
.;This function gets the matching started by calling match-parent(defen match-stat (pattern a-frame)
(let ((match-frame u-frame))(match-parent pattern (match-frame-code a-frame))
"*' (cond ((match-frame-errors a-frame) 0)(t t))))
Hatch-parent calls match-children for the children of the currentpattern and then compares the first element of the pattern with thenode-name. Note that we must attempt to match the entire pattern evenif there is a mismatch, since we have to construct a complete list ofmismatches for explain-mismatches All mismatches are adde4 to
S- ;match-frame-errors
*O (drefu metch-parent (pattern node)(let ((bl (match-children (cdr pattern) (node-children node))))
(coed ((not (equal (car pattern) (mode-name mode)))(push (cons (car pattern) (node-name node))
(natch-frame-errors match-frame))nil)(t bI))))
Ntch-children tries to match the children. Even if there is a mismatchit continues on to try snd find more mismatches. All mismatches are addedto catch-frame-errors. See the Spec for more details.
*: (d.f.n match-children (pattern node-list)(coed
((ad (null pattern) (null node-list)) t)((null pattern)
. (push (cons 0 (mopcar 'node-code node-list))
(match-frame-errors astch-frame))" . nil)
((equl pattern '((ever* ))) t)((null node-list)(push (cons pattern 0)
(match-frame-errors match-frme))nil)
" - ((atom (car pattern))(let ((bI (match-children (cdr pattern) (cdr node-list))))
(cond ((not (equal (car patters) (node-ame (car node-list))))(push (cons (car pattern) (node-name (car node-list)))
(match-frame-errors match-frame))nil)(t bI))))
((equal (car pattern) '(vare ?))(match-children (cdr pattern) (cdr node-list)))
((equal (car pattern) '(ewre a))(let ((cur-bind (copy-tree (match-frace-errors match-frame))))
(or (match-children (cdr pattern) (cdr node-list))(and (setf (match-frame-errors match-frame) cur-bind)
:2 S
- -M- . .. .. .. t- ------ r' .--
Micro-PROUST Code Page 17
nil)(match-children (cdr pattern) mode-list)
(and (setf (match-frame-errors match-frame) cur-bind)nil)
(match-children patters (cdr node-list)))))
((equal (caar patters) 'over*)(let ((binds (check-bindings (cader patters)))
(booll (eatch-childres (cdr patters) (cdr node-list))))
(cond (binds(and (match-children (list binds)
(list (car node-list)))
booll))(t (odd-bindings (codar pattern)
(node-code (car node-list)))(match-children (cdr pattern) (cdr node-list))))))
(t (and (match-parent (car pattern) (car node-list))(match-children (cdr patters) (cdr node-list))))))
Hatch utilities
This function seraches for var-ref in the bindings of the current piln.
and the bindings of the match-frame and returns the binding if found.(defun check-bindings (var-ref)
"" (coed ((equal var-ref ?) ?)((equal var-ref 's) '?)
(t (or (resolve-var ver-ref(ins-bindings plan))
(resolve-var var-ref(match-frame-bindings match-frame))))))
Add the bindings of var-nae to var-ref to the current match-frame(defun add-bindings (var-ref ver-nase)
(push (cons var-ref var-nse) (match-frame-bindings metch-frame)))
Find the pair (var . bind) in the *-list list and return bind.
(defun resolve-var (var list)
(cdr (assoc var list)))
Load the Instantiate group
Contains the folloving functions and their supporting functions:Instantiate. Instantiate-plan. Process-bindings-list. end
resolve-var-ref.Instantiate Sub-group of licro-Proust 13l 5lsp
Written by Bret Vallach 10/24/84
Define the plan instantiation structure
(defstruet ins(name 0)(bindings 0)matches(partials 0)(address 0)
(states 0)(bugs 0))
- 1'o
.%, *,
-7.N
Micro-PROUST Code Page 18
.;;Instantiate
This function returns a list of pin instantiations for the plan
'instances of the goal. The bindings list of the goal is first processedby process-bindings-list. Instantiate-plam is called to create a planinstantiation structure for each plan.
(dfum instantiate (goal)(let ((bindings-list (process-bindings-list goal)))
(cond (exec-out(format goal-window "5indings: s)(nopcar 'lins bindings-list)))
(setf eactive-planse (aapcer 'instantiate-plam(get (car goal) 'instsces)))))
This function returns either the the binding for variable bindings or thenode-line for label bindings. This is used to display a meaningfulbindings list in the goal-window.
(defum ties (bin)(cond ((stoa (cdr bin))
(format goal-window 0-s - a 0 (car bin) (cdr bin)))((node-p (cadr bin))(format goal-window O's -> line 'a 0 (car bin) (node-line (cadr bin))))(t(forest goal-window O's -3, 'a 0 (car bin) (cdr bin)))))
Process the bindings
This function processes the bindings list of goal and returns the boundbindings by calling the function process-biedigsp-i.
(defum process-bindings-list (goil)(process-bindings-I (car goal) (cdr goal)))
This function calls process-list for the binding specification of each
member of the bindings list. It conses thea all together and returnsthe processed bindings list.
(deftu process-bindings-I (goal-nnse goal-list)(coed
((null goal-list) 0)(t(cons (cons (cvr goal-list)
(process-list goal-mse (cder go#l-list)))(process-bindings-I gool-name (cdr goal-list))))))
This function substitutes the real value in for each (aware x y) triplein the list var- al.
(defun process-list (goat-mae var-val)(coed
((nell war-val) 0)((Ito ver-ml) var-vat)((equal (car ar-val) 'aware)(resolve-ver-ref (cadr var-val) (caddr var-val)))
(t(cons (process-list goal-name (car var-vat))(process-list psl-name (cdr var-vat))))))
This function returns the value of vatn which was bound in goil.(defum resolve-var-ref (var goil)
Micro-PROUST Code Page 19
(let ((est (resolve-vwr goal *anlyzed-goalss)))
(coemd ((eull inst) 0)(t (resolve-var varl (ins-bindings inst))))))
This function returns a piss instantiation structure for piss
(defue instantiate-plum (plan)(make-ins name plan
bindings bindings-list
matches (make-array (length (get pla *template))
initial-element 0)))
Utility to display a plan instaatiation structure
(defun list-ins (plan)(print (ins-ae plan))(print (ins-bindings plan))
(print (ins-matches plan))
(print (ins-partials plan))(print (ins-address plan))
(print (ins-status plan))
(ins-bugs plan))
Load the goal knowledge baseGoal Knowledge Base for Nicro-Proust GOALS.kbsTaken directly from Micro-Proust Design Spec 10/23/84
*;INSTANCES refer to possible plan naes.* NAME-PHRASE describes uhat the goal is doing. This is used during
bug reporting.
(DPS SENTINEL-CONTROLLED-LOOPINSTANCES (SENTINEL-READ-PROCESS-WHILE
SENTINEL-PROCESS-READ-VHILESENTINEL-READ-PROCESS-REPEAT)
NAME-PHRASE minput processing8)
(DPS LOOP-INPUT-VALIDATIONINSTANCES (BAD-INPUT-SKIP-CUARD
BAD-INPUT-LOOP-CUARD)
NAME-PHRASE "input vnfidation")
* (DPS AVERAGEINSTANCES (AVERAGE-PLAN)
NAME-PHRASE "enrage")
(OPS OUTPUTINSTANCES (WRITELN-PLAN)NAE-PHRASE "outputg)
S (OPS COUNTINSTANCES (COUNTER-PLAN)NAME-PHRASE countm)
*(DPSSUNINSTANCES (RUNNING-TOTAL)NAME-PHRASE gsve')
(DPS GUARDED-COUNT
%- %
Micro-PROUST Code Page 20
INSTANCES (GUARDED-COUNTER-PLAN)NAPE-PHRASE count)
(DPS MAXIMUMINSTANCES (MAXIMUM-PLAN)NAME-PHRASE 6amximumm)
(DPS GUARD-EXCEPTION
INSTANCES (GUARD-EXCEPTION-PLAN)
NAME-PHRASE 6boundary condition check@)
Load the plansPlan knowledge base for Micro-Proust PLANS.kbs
Takes from Micro-Proust desiga spec with sooe modificatioa.
A fourth element has been added to ame lines. If this element is T.
then the node which the statement matches is mot marked as being matched.If it is nil or non-existent, then the matched node is marked. Thisis only valid for PATCH instructions.
Some of the context descriptor line nmbers were in error is the Spec
and are fixed in this file.
(DPS SENTINEL-PROCESS-READ-WHILETEMPLATE*((MATCH (WHILE (c) (eVAR* NEW) (*VARe STOP)) ($VARe 1)) O)
* (LABEL MAINLOOP. ((AT 1)))(MATCH (BEGIN (*VAR* *)) ((AT 1)))
(MATCH (READ (*VAR* NEW)) ((AT 3) (BOTTOM)))
(LABEL NEXT: ((AT 4)))
(LABEL PROCESS: ((AT 3) (ABOVE 5)))
(MATCH (READ (eVAR* NEW)) ((ABOVE )))(LABEL INIT: ((AT 7)))))
(DPS SENTINEL-READ-PROCESS-WHILETEMPLATE*((MATCH (WHILE (co (OVAR* NEW) (*VAR* STOP)) (*VAR* ?)) 0)
(LABEL MAINLOOP: ((AT 1)))(MATCH (BEGIN (*VAR* a)) ((AT 1)))
(MATCH (READ (*VAR* NEW)) ((AT 3) (TOP)))
(LABEL NEXT: ((AT 4)))(MATCH (IF (<> (*VAR* NEW) (*VAR* STOP)) (*VAR* ?)) ((AT 3) (BELOW 4)))
(LABEL PROCESS- ((AT 6)))
(LABEL INTERNAL-GUARD: ((AT 6)))(MATCH (:= (*VAR* NEW) (eVAR* SEEDVAL)) ((ABOVE )))
(LAREL INIT: ((AT 9)))))
(DPS SENTINEL-READ-PROCESS-REPEAT
TEMPLATE*((MATCH (REPEAT (eVARe ?) (VARe NEW) (*VARe STOP))) O)
(LABEL MAINLOOP: ((AT )))(MATCH (STATEMENT-LIST (*VARe a)) ((AT 1)))
(MATCH (READ (eVAR* NEW)) ((AT 3)))
(LABEL NEXT: ((AT 4)))(MATCH (IF (0 (*VAR* NEW) (*VARe STOP)) (*VAR* 7)) ((AT 3) (BELOW 4)))
(LABEL PROCESS. ((AT 6)))))
• .,-., , .-,-........................................................................................................... ,...,. ,
Micro-PROUST Code Page 21
(LABEL PROCESS:) was changed from ((AT 2)) to ((AT 3)) so as toavoid a conflict between TEST: end PROCESS: during the explainmissing rules functions.
(DPS BAD-INPUT-SKIP-GUARDTEMPLATE((REFER (*VAR* PROCESS: SENTINEL-CONTROLLED-LOOP) 0)(MATCH (IF (*VAR* PRED) (*VAR* ?) (*VAR* ?)) ((AT 1)))(LABEL TEST: ((AT 2)))(MATCH (WRITELN (*VAR* *)) ((AT 2)))(LABEL PROCESS: ((AT 3)))))
(DPS BAD-INPUT-LOOP-GUARDTEMPLATE#((REFER (*VAR* PROCESS: SENTINEL-CONTROLLED-LOOP) 0)
(MATCH (WHILE (*VAR* PRED) (*VAR* ?)) ((TOP) (AT 1)))(LABEL TEST: ((AT 2)))(MATCH (BEGIN (*VAR* 0)) ((AT 2)))(MATCH (VRITELN (*VAR* e)) ((AT 4)))(MATCH (READ (*VAR* NEW)) ((AT 4) (BELOW 5)))(LABEL INPUT: ((AT 6)))(MATCH (IF (<> (*VAR$ NEW) (*VAR* STOP)) (*VAR* *)) ((AT 1)(BELOV 2)))(LABEL PROCESS: ((AT 8)))))
(DPS AVERAGE-PLANTEMPLATE#((REFER ($VAR* MAINLOOP: SENTINEL-CONTROLLED-LOOP) 0)
(MATCH (:- (*VAR* AVG) (/ (*VAR* SUM) (*VAR* COUNT))) ((BELOW 1)))(LABEL UPDATE. ((AT 2)))))
(DPS WRITELN-PLANTEMPLATE*((MATCH (WRITELN (eVAR* s) (*VAR* VAL) ($VARe)) 0)
(LABEL OUTPUT: ((AT 1)))))
(DPS COUNTER-PLANTEMPLATE((REFER (*VARe PROCESS: SENTINEL-CONTROLLED-LOOP) 0)(MATCH (:u (eVARe COUNT) (* (eVAR* COUNT) 1)) ((AT )))(LABEL UPDATE: ((AT 2)))(REFER (*VAR* HAINLOOP: SENTINEL-CONTROLLED-LOOP) 0)(MATCH (:a (*VAR* COUNT) 0) ((ABOVE 4)))
(LABEL INIT: ((AT 5)))))
(DPS GUARDED-COUNTER-PLANTEMPLATE#((REFER (*VAR* PROCESS- SENTINEL-CONTROLLED-LOOP) 0)
(MATCH (IF (*VAR* PRED) (*VAR* ?)) ((AT )))(LABEL GUARD: ((AT 2)))(MATCH (:s (*VAR* COUNT) (# (*VAR* COUNT) 1)) ((AT 3)))(LABEL UPDATE: ((AT 4)))(REFER (*VAR* RAINLOOP: SENTINEL-ONTROLLED-LOOP) O)(MATCH (:a (*VAR* COUNT) 0) ((ABOVE 6)))(LABEL INIT: ((AT 7)))))
(DPS RUNNING-TOTALTEMPLATE*((REFER (*VAR* PROCESS: SENTINEL-CONTROLLED-LOOP) 0)
(MATCH (:a ($VAR$ TOTAL) ( ('VAR* TOTAL) (*VAR* NEW))) ((AT 1)))(LABEL UPDATE: ((AT 2)))
............... . . . .
I.
Micro-PROUST Code Page 22
(REFER (*VAR* HAINLOOP: SENTINEL-CONTROLLED-LOOP) 0)(HATCH (-z (*VAR* TOTAL) 0) ((ABOVE 0))(LABEL 1111: ((AT 5)))))
*This plan is messed up. but works sufficiently for mow.*Both LABEL statements have been added for bug role purposes.*Problems are:
1. It will match IF count a 0 them eye a sue / count else writeln (Ca');* This is clearly backwards.
2. Usually whem the IF statement is missing, the VRITELN statement ismissing also. Therefore, bug rules explain the mnissimg IF. adding
* something to ebug-reporte. Then the WRITEIN is also mot matchedand more bug rules fire which should generate another error message.Two messages for one error is two much.
(DPS GUARD-EXCEPTION-PLANTEMPLATE#((REFER (*VAR* CODE) 0
(HATCH (IF (*VAR* PRED) (*VAR* ?) (*VAR* ?)) ((CONTAINING 1)) T)(LABEL EXCEPTION: ((AT 2)))(HATCH (WRITELI (*VAR* a)) ((AT 3)) T)(LABEL GUARD-ACTION: ((AT 4))
(DPS HAXIHUN-PLANTEMPL ATEW(REFER (*VAR* PROCESS: SENTINEL-COITROLLED-LOOP) 0)(HATCH (IF (), (*VAR* NEW) (*VAR* MAX)) (*VAR* ?)) ((AT 1)))(MATCH (:a (*VAR* HAX) (*VAR* NEW)) ((AT 2)))(LABEL UPDATE: ((AT 3)(REFER (*VAR* HAINLOOP: SENTINEL-CONTROLLED-LOOP) 0)(MATCH (:= (*VAR* MAX) (*VAR* HINVAL)) ((ABOVE 5)))))
*Load the Parse, groupContains the following functions and their supporting functions:*;Parse.Les-initialize and Les-gottok are not used. See parse Isp for furtherdetails.
;;Parse sub-group of NPROtDST PARSE ISPWritten by Bret Wallach 10/24/84
Only one week was allocated for the Parser and Iuxor sod there*were no compiler compilers or other such tools available. Asa result this is one of the sore slow. inefficient. sod kludgyparser/lexers in existence today. Vel. enough for excuses.
*This function uses read-tokiens to get a list of tokens and their linenumbers from the program file. It then sakes as array oat the listand stuffs it in the global variable sentence. The global variable
*s-ptr points to the current token as sentence. The function p-mmtchis then called to build the pars. tree from the tokens.
(defun parse (filteae(let* ((eine-numbetre 1)
(z (read-tokens fileame))(sentence (make-array (.(length a) 2) :fill-pointer 0))(s-ptr 0))
Micro-PROUST Code Page 23
(aapcar #'(lambda Wz (vector-r sk z sentence)) z)(vector-push *(nil 0) ses'.esce)(vector-push '(nil 0) Setetace)(setf eparse-trees (Car (p-eatch '*program)))))
The bieor
Unfortunately for vs. CCLISP version 0.S8 has a bog making it impossibleto restore the read table after altering it to define various characterssuch as + to be macro characters. As a result. I had to write ay ownread function.
Read-tokens opens the program file and calls reaid-tokens-I to work on it.(defun read-tokens (fileame)
(with-ope-file(otis filename direction input :element-type 'string-char)(read-tokens-i))
Read-tokens-I creates a list of consts (symbol . sline-aumbere) wheresymbol is gotten by calling read-pas and eline-munbere is the currentline in the file
(defun read-tokens-I 0)(do* ((syab (read-pas otis (0 0) (read-pns ous C)0)
(cs (list (cons syeb eline-oambers))(append cs (list (cons symb fline-number)))))
((equal syab ()) cs)))
Read-pins reads characters until it hits a mcrocharacter. It then callsRead-posl to process it.
(defun read-pas (stream eof-f eof-r)(setf (fill-pointer read-vector) 0)(do ((tchar (read-char stroea eof-f eof-r)
(read-char stream eof-f eof-r)))((assoc tchar break-alist) (read-pasi tcher))(vector-push tchor read-vector)))
Read-pasi either returns the symbol just read or processes the macro char.(defun read-pasi (tchar)
(cond ((equal (fill-pointer read-vector) 0)(foncoll (cdr (assoc tcher break-list)) tchar))
(t(unreiad-char tchar stream)(read-from-string read-vector))))
This array is used to build the symbols(setf read-vector (make-array 256 :elemenet-type *string-char fill-pointer 0))
;This ai-list contains all the special characters(setf break-alist '((#\ . gn) (13 . iga) (9 . gm) (12 . ign)
(10 . p) (I\+ - rem) (nil . edfos) (#\{ con)(e..rev) (6(.par) (').rem)(S-.rem) (S~.rem) (S'.dq)(ge rev) (IV .re) (Su.rem)V re) (A), rem) (S .rem)))
Character macros
IGI ignores the character. It is nsed for spaces, tabs. etc.
Micro-PROUST Code Page 24
(defun ign (char)(do ((x (read-char stream eof-f eof-r)
(read-char stream eof-f eo-r)))
((not (equal x char))(proga (unread-char x stress)
(read-pas stream eof-f eo-r)))))
Lp is called for a line-feed. It increments line-musbere(defun Ip (char) (incf elime-numbere) (read-pas stream eof-f eo-r))
;; Res returns the read character
(defun rem (char) (vector-push 9\\ read-vector)
(vector-push char read-vector)(read-from-string read-vector))
Par is the left-parenthesis macro. If a 0 follows immediately themignore everything until a) since it is a comment. Otherwise return \(
(detun per (char)(let ((n-char (read-char stream eof-f eo-r)))
(cond ((equal n-char 6\a)(do* ((ch W( x)
(x (read-char stream eof-f eo-r)(read-char stress eof-f eof-r)))
((or (and (equal n-char 0\0) (equal x A)
(equal z eof-r))(read-ps stream eof-f eof-r))))
(t (unread-char n-char stream)(vector-push \\ read-vector)(vector-push \( read-vector)(read-froe-striag read-vector)))))
Coo is the { macro. Ignore the comment(dee coo (char)(do ((a (read-char strem eof-f eof-r) (read-char strem eof-f eo-r)))
((or (equal x #\)) (equal a eo-r)) (read-pes strem eof-f eo-r))))
Dq is the single-qvote macro. It turns the ' into 8 and returns a string.(datv dq (char)(vector-push #\9 read-vector)(do ((0 (read-char stream eof-f eof-r) (read-char stream eof-f eof-r)))
((or (equal 1 *\,) (equal a eof-r))(proga (vector-push 0\s read-vector)
(decf (fill-pointer read-vector))(vector-push *0\ reed-vector)(read-from-string read-vet*or)))
(vector-push a read-vector)))
; Endftu returns 0 signifying the end of the file.
(dafm endfia (char) eo-r)
Parse functions
Define a parse-tree node
(defstruct mode
(name 0)(parent ()(children 0)
(liee 0)(mark 0))
Micro-PROUST Code Page 25
;; Debug Utility to list the node information
(defun list-node (z)(print (node-name ))(print (rode-parent ))
(print (node-children x))(print (node-line a))
(node-mark ))
Debug Utility to get the parenthesized PASCAL starting at parse node x.
(defun node-code ()
(cond ((null x) 0)((null (node-children )) (node-name a))(t (cons (node-name x) (mapcmr 'node-code (mode-children x))))))
..Parse matching
,. ... ... ,o. ... ,, o o , , , , , . , , , o , o ,, . , , , , , . , , , o , , ,
This is the starting parse matcher. It uses the global variable sentence
and matches it to the EBNF specified by -node. If g-node has no 'template. property and g-node is equal to the current token in sentence, then create
a new node with ame g-node @nd return. If -aode has a template thencall p-match-i with the template and try to match the template againstthe sentence If the match succeeds p-match-i will return a list of
.. children nodes If the 'parent property of g-node is nil. return that;;list of children, otherwise creste a new node with those children.
Otherwise return nil.
(defun p-match (g-node)(let ((tplt (get g-node 'templete))
(per-name (get g-node 'parent))(c-node 0)(line 1)
(par ()))(cond ((null tplt)
(cond ((equal -node (car (aref sentence s-ptr)))
(incf s-ptr)
(list (make-node name -nodeline (cdr (aref sentence s-ptr)))))
(t 0)))(t (and (setf line (cdr (aref sentence s-ptr))
c-node (p-mtch-I tplt))(coed ((and par-same (not (eq c-node t)))
(setq par (sake-node name (get g-node 'parent)
children c-nodeline line))
(mpcar *'(lambda (z)(setf (node-parent x) par))
c-mode)(list par))(par-name(list (make-node aoe (get g-node 'parent)
lime line)))(t c-node)))))))
This function tries to match each option of a template with the sentencetokens pointed to by s-ptr. If ay of thee match, return the children
crested in the process, else return nil.
(defu p-match-I (toplt Lase chil booll s-ptrl)(setq booll (mll (car teplt)) chil 0)
Micro-PROUST Code Page 28
(set? s-ptrI s-ptr)(do* ((x taplt (cdr x))
((car x) (car x))).(or (null x) (null y) booll) (or (snd booll (or chil booll))
(and (set? s-ptr s-ptrl) ail)))
(set? s-ptr s-ptrl)(aultiple-value-setq; (chil booll) (p-match-2 y))))
Option matcher
Thisfuncion riesto match a parse template against the current sentencetokens. If it succeeds it returns two values. The first is a list ofchildren created while watching things and the second is T. If it failsthe first value is undefined and the second value is nil.
(defun p-match-2 (tap &aux t-node p-node fbool)(set? p-node () fbool t)(do*((x tap (cdr )(y (car x) (car x)))
((or (null x) (null fbool)) (values p-node fbool))(cond ((null y) 0)
(($too Y)(cond ((set? t-node (p-atch y))
(set? p-node (append p-node (filt-t t-ftode))))(t (set? fbool nil))))
((equal (car y) '*opt*)(set? p-node (append p-node (filt-t (p-match (cadr y))))))
((equal (car y) '*ignore*)(set? fbool (not (null (p-match (cedr y))))))
((and (equal (car y) '*fumces)(funcall (cadr y) (car (are? sentence s-ptr))))
(set? p-node (append p-node(list (ake-node ame* (car (are? seateace s-ptr))
line (cdr ( ref sentesce s-ptr))))))(imc? s-ptr))
((and (equal (car y) '$pars)(set? t-node (p-match (cadr y))))
(aultiple-value-biod (q-nodes bool) (p-match-2 (cdr x))(coed (bool
(set? (node-children (car t-node))(append p-node q-aodes))
(set? I nil)(set? p-mode, t-node))
(t (set? ?bool nil)))))((equal (car y) 'efune) (set? ?bool ail))((equal (car y) 'soul*)(or (and (set? t-node (p-match-inI (cdr y)))
(set? p-node (append p-node t-oode)))(set? fbool WDl)
((equal (car y) '*smile)(or (and (set? t-node (p-match-mull (cdr y)))
(set? p-mode (append p-mode t-node)))(set? fbool ail)))
(t (error OPARSE: Bed BNF option-0)))))
Option matcher Utilities
This function filters out all T's which are introdeced by matches that
AD-A157 505 MICRO PROUST(U RLE UNIV NEW HAVEN CT DEPT OF COMPUTER 2/2SCIENCE W L JOHNSON ET AL. JUN 85 YALEU/CSD/RR-482N08014-82-K-8714
UNCLASSIFIED F/G 9/2 NL
EIEEIIIIEIIEEEEEEEEEEElll
11111 1 1.0 II 22
1.25
_'?"z .. '
1Iff1 ,__o lff
~MICROCOPY RESOLUTION TEST CHART
:o ." -o
Micro-PROUST Code Page 27
don't create any children.(defun filt-t (I) (if (eq I t) nil I))
This function is called by p-match-2 to take care of the souls templateoption. The algorithm used is explained in PARSE.DAT.
(defun p-match-mul (top &sox p q)(coed ((null (setf p (p-match (car top)))) (values 0 0))
(t (do 0((or ()- s-ptr (length sentence))(null (member (car (aref sentence s-ptr)) (codr top))))(values p t))
(incf s-ptr)(setf p (list (make-node name (car (are? sentence (1- s-ptr)))
children (setf q (append p (filt-t(p-match (car top)))))
line (cdr (aref sentence (1- s-ptr))))))(..pc $'(lambda (x) (setf (node-parent x) (car p))) q)))))
This function is called by p-satch-2 to take care of the *mulle template% option. The algorithm used is explained in PARSE.DAT.(defun p-match-mull (tip kIv p q)
(coed ((null (setf p (p-match (car top)))) (values 0 0))(t (do 0
((or (and (csdr top) (inf s-ptr) nil)(>- s-ptr (length sentence))
(and (cadr top)(null (member (car (aref sentence (1- s-ptr)))
(cadr tap))))(null (setf q (p-match (car top)))))
(progn (and (cadr top) (deef s-ptr)) (values p t)))
(setf p (append p (filt-t q)))))))
Load the parenthesized BNF for the subset of PASCAL that is needed.Written by Bret Wallach 10/23/84
This file contains the information necessary to parse and build
a parse-tree for the subset of PASCAL that Nicro-Proust is using.
Only one week was allocated for programming the parser. As a resultthere certainly are bugs in my PASCAL language definition.
Each time a parse ear completely matches. a parse-tree node is
,- ;built using the 'parent property as the nmen. If the 'parent- ;property is nil. then no new nodes are created and the children
nodes are passed along instead. See PARSE.LSP for additional
-,-, details.
; The following options are allowed for a match.
1. *ignoree means that the object most mitch, but don't create
a child node for it.
2. *opt* means try to match the object, but if it doesn't match.
skip it.
3. sfunce means apply the following lambda expression to the
Micro-PROUST Code Page 28
current tohes *ad if T is returmed. coasider it a matchuing the next takes as the mss of a mew child *ode.
4 *er* moes that this item most match *ad thee will be usedas the mod*-**@@ of the parent *ode or all the rest of thematched objects
5 *@@1*l is used to build the eapressios sub-trees. This is howit is uSSW
Step I Try ta match the first argument. If it matchesereate made a far it and go to Step 2. otherwise quit.
Step 2 Try to catch may of the elemeats of the secondarguceat and them the first argust apie. If theymatch create modes I aod z for bath catchesrespectively Nake I the parent made with a as theleft child aed z as the right child. Set a * .Go toStop 2 Else rotors a.
I emailii is used to simplify right recursive rules. For eample. thefolling .me teaplae~s for San with ail parent properties wouldhuiId Lhe so~ per"e sub-tree.
((wba \. see) (*be)) *so ::* obe* amSo I Olbn
(((eal. *be se))) ae ::- *be (0.0 obe)
The "ecoed argueet is the item to be repeated, aid the thirdarguimoat is a list of passible separators.
Notes for writing meu rules.Do mat use say left recursive tules. These will bomb the program.If a rule has a right recursive optioe. pot that aptiam first.
* . . *. Always create the rules ma they catch as much as possible.*opts is like 0 is EBUFouls is like 0) in EBNF*ells is also like ()in EBVF bet precedece is sot considered.
elprogram ::a OPROC.RANO aid (sprog-header] [adecls] osim-block Sed(dpi *program
template(((aigmaree PROGRAN) aid (*opt* aprog-header)(Ocpts sdoels) e~ain-block (aignore* *sod)))
parent PROGRAM)
*main-black ::a BEGINO eistatesents O uECINO(dps oasain-block
* templatet(((* ignore* BEGIN) *statements)((*ignore* BEGIN)))purent BEGIN)
Suid ::a *END; I END.8(dpi send
templatet(((*ignore* END) (oipaoa\j ((oigmaree END.)))parent nil)
S%
Micro-PROUST Code Page 29
*prog-header 9i(9 #pk-lisit 6)0 s;
(dps eprog-headertemplate(((*ignore* \() *ph-l it (*ignore$ ) (signoree ;)pa rent PROC-HEADER)
* aph-list ::a aid (4. oid)
(dps aph-listtemptlate(((*evil* sid(\))parent nil)
adecis ::x *coast-decls evar-dects I *coast-decls I *vor-decis(dpi adecis
template((econst-decis avar-decls)(acomst-doels)(awar-des))partent DECIS)
* coast-dects :: COISTO *coast-list*(dps acoast-dects
temptlate((OIST *const-tlist))parent COUST-DECIS)
*const-tist ::- eofiit {*coIIst)* (dpi *coast-Ilist
template(((*el* *conast 0)))parent nil)
*const ::z aid OzN ceupt *A*(dpi *coast
temptlate((*id (*ignore*a3) cexpr ('ignore. j)parent COUST)
abool-expr ::z 0expr sbool-op aexpr(dps sbool-expr
temptlate((sexpr (*per* abool-op) ceupr))parent nil)
abool-op ::z 'boot-ne I 'boot-ge I abool-le I(dpi ebool-op
templ ate((eboot-ne)0(boot-ge) (0bood-t)(*boot-eq) ('boot-It) (sbool-gt))parent oit)
aboot-eq ::z Ong*(dpi ahool-eq
temptlate(((aignoree \))parent\)
aboot-It ::a 8<9(dpi sbhad-It
template
-. - ...-..-(( *gnore* -- ~--;
Micro-PROUST Code Page 30
parent \)
(dps *bool-gttemplate(((signores \3)))parent \)
; bool-ne 0<>8
(dps sbol-netemplate(((*ignore* \<) (*ignore* \)))parent \<\>)
*bol-ge ::0 )2(dps obool-ge
template(((*ignore$ \) ('igore' \=)))parent \-\-)
ebool-le ::
(dps *bool-letemplate
((($ignore* \<) (*ignore* \u)))
parent \ )
eexpr ::= etere (§+§ etern 1 - sterm I ORO eterm)
(dps eexprtemplate(((mule 'term (\n \- OR))))parent 0)
sterm :* fact (e *fact I /" *efact I "DIV" *factSNOD" *tact I "AmD" *fact)
* (dps stern
template
(((*mule *fact (\s V DIV NO AND))))parent 0)
*fact ::9 0 'ezpr 9)0 I eid-or-mn I e-inws-fmcteu-plus-fact I 'not-fact
(dps *facttemplate
(((*ignore* \O seapr (*ignore* \)))('id-or-nun)(eu-minus-fact)('n-plms-fact)(enot-fact))parent 0)
;;'u-miovs-fact ::a 0-0 efact(dps 'u-mi ns-fact
template(((*ignore* \-) *fact))
parent \-)
eu-plus-fact :: fa efict(dps eu-plws-fact
template(((eignore' \.) 'fact))parent nil)
So
,.' ': ,€..','-." -. . . . . . . . . . . ..,".". .. '-". .". ..,." ". . . .... .-.". .... - . -: ,; , ", . .:":'" , , ,:".
Micro-PROUST Code Page 31
enot-fact ::z NOTO *fact(dps *not-fact
template(((*ignoree NOT) *fact))parent NOT)
; expr-list ::= eezpr-or-string {U*U 'expr-or-string)(dps *expr-list
template(((*eull* eexpr-or-string (\.))))parent nil)
*expr-or-string ::a eexpr tow-format] I stringvere string is predefined
(dps eezpr-or-str ingtemplate((eexpr (*opte eu-format)) ((*fumes (lambda (var) (stringp var)))))
parent nil)
*v-foreat ::a 0:0 eit 0:0 sint i 0:0 sit(dps su-format
templ ate(((ignoree \:) (signoree 'int) (signores \:) (ignowree 'int))((*ignore* \:) (signorei 'ut)))
parent nil)
.int is predefined(dps 'int
template(((*func* (lambda (var) (integerp vmr)))))
parent nil)
Svar-decis ::a OVARO evar-list
(dps evar-decistemplate(((*ignore* VAR) ovar-list))
parent VAR-DECLS)
*vr-list ::= *var fevar)(dps 'var-list
template(((*mell* *wat 0)))parent nil)
;; evar ::a oid-list 0:0 tver-type 0;0
(dps overtemplate(('id-list (oigoree \:) ever-type (signorae \;)parent VAR)
;var-type ::a mREALO I 8INTEGERe(dps ovar-type
template((REAL) (INTEER))parent nil)
'begin-block ::= 8END9 * statements ElD(dpe *begin-block
template
Micro-PROUST Code Page 32
(((*ignore* END))(*statements (sigmoree END)))
parent BEGIN)
*statements ::a eststoeet {0*0 *statement)(dpi *statements
template(((*evul* *statement(\))parent oil)
*semi ::a 0;6(dps *semi
temptlate(((*ignore* ;)parent oil)
estatement ::u *ass-statement I orF6 *f-stmtement * begim-block .(dpi *statement
template(('ass-statement) ((*ignore* IF) 'if-statememt)((*ignore* BEGIN) $begin-block)((*ignore* WHILE) 'rhi tm-statement)((* ignore* REPEAT) *repeat-statesent)((*i gnore* WRITE1 U) 'yr itelor-statement)((* ignore* WRITE) 'write-statement)(('ignore* READ) 'read-statoeet)((* ignore* READIN) 'read In-statement)((*ignore* CASE) 'case-statement) ('matilstatemeat))
parent nit)
(dpi 'gailI-statementtempl ate(0)parent nil)
'ass-statement ::= 'id O:ug ocapr(dpi 'ass-statement
temptlate(('id ('ignore' V:) (signor** \z) 'expr))parent :-)
'wite-statement ::a*'boot-capt OD0 'statementUdps 'uhi l-statement
template((eboot-expr (*ignore* DO) 'stetement))parent WHILE)
'repeat-statement ::=*'repeat-list OUTILm 'bool-expr(dps 'repeat-statement
temptlate(('repeat-list ('ignore' UNTIL) ebool-expr))parent REPEAT)
'repeat-list ::=*'statements(dpi 'repeat-list
template((*statements))parent STATENEIT-LIST)
Micro-PROUST Code Page 33
(dps *vr ito-statemetttemplIate(((*opt* *write-Iist)))parent VRITE)
(dps svr itel a-statementtemplIate(((*opt* *write-list)))parent VRITELN)
;*write-list ::= 0(8 0expr-list 0)0(dps eurite-list
template(((*ignore* NO) sexpr-list (cignores \))parent nil)
;;Cread-statement :: *reed-list(dps S read-statement
template(((*opt* eread-list)))parent READ)
Cread in-statement :: sreod-i st(dps C read in-statement
template(((*opt* Cread-list)))parent READLN)
*read-list ::= 8( Clist-id 0)0(dps *read-list
temp late(((signor.* \0) *I ist-id (*ignores,\))parent nil)
~*case-statement ::z Cexpr 80F8 sense-lI st [6*6 'END9(dps *case-statement
template((sexpr (signoree, OF)*case-list (*opt* *semi) (signor.. END)))
parent CASE)
*~case-list ::a* cose-port 9; scs-list I scas-partWde Cease-I ist
template((eas*-part (*ignore* \;) case-list) (Cease-part))parent nil)
seCase-part ::a Ccas*-canst 0:0n *statement(dps Cease-part
template((Ccase-const (signores V:) *statement))parent CASE-PART)
cest-coast ::a Cease-coast-I st(dps Cease-coast
Micro-PROUST Code Page 34
(('case-con st-list))parent COUST-LIST)
scmse-const-list ::a sid-or-sum 0.0 *case-comst-list I aid-or-mo(dps acmse-coast-list
template((aid-or-sum (*ignore* V.) 'case-comst-l ist) (aid-or-sum))parent oil)
aid-or-mum ::- sid I *eve(dps oid-or-mum
template((aid) ('sum))pureat oil)
aif-stoatet ::z abool-expr mTHENG astatement [aelse-pi(dps $i t-statament
templete((sbool-expr (*ignore* THEN) *statement ($opts eelse-p)))parent IF)
aalse-p ::a ELSE8 *statement(dps aelse-p
templete(((*ignore* ELSE) *statement))parast oil)
aid-list ::=*'list-id(dps sid-list
template((at ist-id))pirest id-list)
list-id !:xaid (0.0i aid)(dps list-id
template(((amvlla aid (\))parent oil)
aid is predefined(dps aid
template((('fame' (lambda (W
(and 0-w (char-opease (aref (striag x) 0)) #\A)(-c (chor-opease Caret (striag x) 0)) *\Z))))))
parent oil)
onem is predetesed(dps ones
template(((afuca (lambda (W (nmbmerp a)))))paeat oil)
Load the Explois mismatched grompContmas the following fuetioss and their svpportiug fuactioss:Esplmiasiseetes. evel-ealformed-rules. simgle-eual-malformed.
Micro-PROUST Code Page 352
i too-eve I-sealformed. evsl-s-oalforeed-rule. eval-sissing-rules. andsingl s-eva [-missinmg.
;;Explain Hismatches functioss EXPLAIN.LSP;;Writtes by Bret Wallach 10/23/84
Explain mismatches
;This function calls eval-malformed-rules @ad thea evel-aissing-rulesto try to explain mismatches in the plas. If one of those two functions~returns a plan (seaming that all mismatches for the plan are explaimed).the plan is set to unblocked, *ad the component address is increased by 1.
(defus explain-sismatches (plans)(lot ((new-plan
(or (eval-malformed-rules plans)(eval-sissing-rules pleas))))
(coed (new-plan(setf (ins-status mew-plan) 0)(mcf (ins-address new-plan))new-p lan)
(t O)
Use the salforaed roles to explain mismatches in the plans
Eval-smlforsed-ruleis call/ Single-Eval-Nal9formed for each plan.(defun eval-aalforeed-rules (plans)
(coed(plans (or (single-evel-walforaed (car plas))
(eval-malforeed-rales (cdr plans))))(t O))
;This function gets each match-frase from the partials slot of the plan;*j stemtistion smd passes it to item-eval-melformed so that the errorscam be explained. If the errors are explained the plea is raerned.
(delun single-eval-nalforaed (plan)(let ((partial (pop (ins-partials pla))))
(cond (partial(foreat t 5- Partial: 'a (match-frame-errors partial))(format t 0-9 Plan-nmae: 'a* (ias-some pla))(or (and (item-ewal-malformed pla partial)
(setf (aref (ins-matches pla)(ins-address plan))
(list (match-frome-cod* partial)))pla)
(aiNgle-ewal-selformed pla)))(t 0)
*This feateon applies each malformed rule to a match-frame until*the errors are explained or there are no rules left.
(defen itoo-evol-selforsed (plan match-frame)(do* ((z *malforsed-rulea@ (cdr x))
(I (car 0) (car W))((or (mull x) (eval-o-omforeed-rele plan match-frae y))(coed (I
(snd *ee-out(format t "Patch error explained by -a in pla 's.0
Y (ins-name pleMm)plea)
Micro-PROUST Code Page 36
(t 0)))))
;;This function makes sure that each part of a malformed rule is satisfied.;The bug rule action is performed if this is the case.
(deft evel-a-aalformed-rule (pls match-frame rule)(let ((explained-errors 0))(and (plan-component plan rule)
(expected match-frate role'(plan-test pis rule)(test-code)(z explained-errors (length (mitch-frame-errors match-frame)))
(action))))
Use the missing rules to explain mismatches in the plans
E.el-missing-rules calls Siagle-Eval-lissing for each pile.(defun eval-missing-rules (plans)
(coed(plans (or (single-eval-missing (car plans))
(eval-missing-roles (cdr plans))))(t 0)))
This function applies each missing rule to the plan-instantiation untilthe errors are explained or there are no rules left. If one of the
;;rules fires. the plan-coeponent is said to match the same thing as the; first plan component.(defun single-eval-missing (plan)
(doe ((z *missing-rules* (edr x))(y (car x) (car x)))
((or (null x) (evel-a-saissing-rule pil y))(cond (x (setf (aref (ins-setches pil)
(ins-address pila))(oref (ins-catches plea) 0))
(mad exec-out(format t 0I1latch error explained by -a in plan 's.0
7 (ins-nae plan)))plan) (t 0)))))
This function makes sure that each part of a missing rule is satisfied.;;The bug rule action is performed if this is the case.(defun eval-a-missing-rule (pla rule)
(and (plan-component plan rule)(pin-test plan rule)(test-code)(action)))
Explain Utilities
This function makes sure that the component that didn't match is referedto by a label statement is a later plan component. If there is no'plan-coaponent property (this is the label), then return T.
(defun plan-component (plan rule)(let ((cur-addr (+ (ins-address pile) 1))
(len (length (ins-matches plea)))(tmplt (get (ins-ame plan) 'templte))(label (get rule 'plan-cosponent)))
(coed ((null label) t)(t (do ((i cur-eddr (i i 1)))
Micro-PROUST Code Page 37
((or (equal i lee)(and (equal (car (aref tupit i)) 'label)
(equal (cadr (aref tmplt i)) label)(equal (ceder (caddr (aref taplt i)))
cur-addr)))(not (equal i len))))))))
This function analyzes the 'expected and 'found properties of thebug rule. If both properties exist. then a cons of the form(expected . found) is sought in the match-frame errors.If there is no 'expected property, but there is a 'found property.then there must be a cons of the fore (x . found) where x canbe anything. If neither property exists then true is returned.
(defun expected (match-fries rule)(let ((eiptd (get rule 'expected))
(fad (get rule 'found)))(cond ((and (null exptd) (null fad)) t)
((and (null exptd)(not (null (rassoc fnd (natch-frace-errors
match-frae)))))(incf explained-errors) t)(t (let ((arg (cdr (assoc exptd (aatch-froae-errors
match-frace)))))(coend ((or (equal fad arg) (member fad arg))
(incf explained-errors) t)(t 0)))))))
This function sakes sure the plan errors being explained are part ofa specified plan. If there is no 'plan property, return T.
(defun plan-test (plan rule)(let ((plan-nea (get rule 'plan)))
(or (null plan-nome) (equal plan-neae (ins-name plen)))))
This function executes the test part of the rule and returns its result.It returns T if there is no test function associated with the rule.
(defv test-code 0(let ((func (get rule 'test-code)))
(or (null func) (funcell fuac))))
This function fires the action part of the rule and returns T.(defun action 0
(setf ebug-reporte (append ebug-reporte(list (fencall (get rule 'action))))) t)
;Bug rules BUGS.LSP;;Vritten by Bret Vallach 10/23/84
This file contains the test action pairs and the report functionsfor the bug rules.
The variable explained-errors contains the number of mismatches thathave been explained by the bug rules. All aismatches have to beexplained before the action part of a rule will fire.
;;Utilities
;;Returns the node in the eparse-treeo that the bug is associated
Micro-PROUST Code Page 38
(defun bug-statement (bug)(match-frme-code (cdr (assoc 'statement bug))))
;;Returns the component label of the bug(defun bug-component (bug)(cdr (assoc 'component bug)))
;;Returns the goal label of the bug(defun bug-goal (bug)(cdr (assoc 'goal bug)))
;;hile-for-if rule
(defun while-for-if-action 0'(while-for-if (statement . match-frae)))
(dos while-for-if expected if found while action vhile-for-if-actionreport-fun report-vhile-for-if)
(defun report-vhile-for-if (bug)(format t'You used a WHILE statement at line "m where you should have used an IF
(node-line (bug-statement bug))))
;;Read-is-counter rule
(defun check-read-is-counter 0(let ((var (node-name (car (node-childrea (match-frame-code match-frame)))))
(incr (cadr (assoc 0 (atch-frame-errors mmtch-frsme)))))(and (equal (length (match-frame-errors match-frame)) 2)
(equal (car incr) '*)(equal (cadr incr) var)(equal (caddr ier) '1)(incf explained-errors)(inef explained-errors)t)))
(defun read-is-counter-action 0'(read-is-counter (statement matck-frame)))
(dps read-is-counter expected read found :ztest-code check-read-is-counter action read-is-counter-actionreport-fun report-reed-is-counter)
(defun report-read-is-counter (bug)(format tlit appears that you were trying to use line 'a to read the next imput
value. Incrementing 'a will not cause the next value to be read is. Youneed to use a read statement here.m
(node-line (bug-statement bug))(node-name (car (node-children (bug-statement bog))))))
;Sue is counter rule
(dfuN sum-is-counter-action 0(sum-is-counter (statesent . match-frae)))
Micro-PROUST Code Page 52
11.2 EXAMPLE2.PAS
PROGRAM Average2( INPUT. OUTPUT );VAR SUN. COUNT. NEW: INTEGER;
AVG: REAL;BEGINSUN := 0.COUNT :=0;NEW :=0;WHILE NEV<>9999 DO
BEGINREAD( NEW ).
SUN :a SUN.NEW;COUNT :=COUNT*I;
END,IF COUNT=O THENVRITELN( 'NO DATA ENTERED' )
ELSEBEGINAVG :=SUN/COUNT;WRITELN( 'THE AVERAGE I- '. AVG ).
ENDEND;
, .....-....-... ..... .. " - A ...
Micro-PROUST Code Page 51
U. Sample Pascal Prograsr
LI.1 EXAMPLE.PAS
PROGRAN Average (input.output);VAR Sum. Count. Nee: INTEGER;
Avg: REAL;
BEGINSum :a 0;Count :U 0;Read (New);
VHILE Nov<9999 DOBEGINSue := Sue*Nev;Count :a Count*l;Nov :a Now + I
END;A g :a Som/Count;WRITELN ('The average is I.svg);
END.
. , . . . . . . . . . .. .
,. - . _. - - ' ... . 7 1. . - _ - * o - - . - I -- .- . -.- , -, ,- .. " . r . ,. i
Micro-PROUST Code Page 50
(OTHERWISE (APPLY #'DRIBBLE-II ARCS))))
Micro-PROUST Code Page 49
1.6 DRI]BBLE.LSP
tttdribble. ispCopyright (c) Gold Hill Computers. Inc. 1994
The DRIBBLE facility (slurp):The only toplevel function in this file is DRIBBLE.
(DEFYAR eDRIBBLE-STREANe NIL) the DRIBBLE output strem(DEFVAR *DRIBBLE-TERMINAL* NIL) during DRIBBLE this is terminal
(DEFUU DRIBBLE (&OPTIONAL PM)'DRIBBLE vith a pathase argument start the dribble operation. with
no pathaae argument ends the dribble operation.*(CORD ((AND Pil (NULL eDRIBBLE-STREANe)) open dribble file
(SETO *DRIBBLE-STREAN* (OPEN P11 :DIRECTION :OUTPUT)*DRIBBLE-UNTYIC NILeDRIBBLE-TERNINALC eTERNINAL-10ceTERNINAL-10* *'DRIBBLE-TERN)
T)((AND (NULL PM) eDRIBBLE-STREAN*) close dribble file(SETO CTERNINAL-1O. *DRIBBLE-TERNINAL*)(CLOSE CDRIBBLE-STREAN*)(SETO *DRIBBLE-STREANs NIL))((AND (NULL PH) (NULL eDRIBBLE-STREAI.)) ;asked to close but not open(FORMAT T m"ADRIBBLE not in progress.'))((AND P11 CDRIBBLE-STREAN*) ;asked to open but already open(FORMAT T 'ADRIBBLE is already in progress.*))
(DEF VAR eDRIBBLE-UNTYI* NIL)
;This is the input stream headler during a dribble.(DEFUN DRIBBLE-IN (NSC &REST ARCS)
(CASE USC(:TYI
(CORD (*DRIBBLE-uUTYIe(PROGI eDRIBBLE-UNTYI*
(SETO eDRIBBLE-UNTYIe NIL)))(T
(LET ((HAR (SEED *DRIBDLE-TERNINALe :TYI)))(SEND CDRIBBLE-STREANs :TYD CHAR)CHAR))))
(:UNTY! (SETO eDRIBBLE-UVTYI* (CAR ARCS)));forward to the real stream.
(OTHERWISE(APPLY *DRIBBLE-TERNIMAL* NSC ARC))))
This is the output streas heandler daring a dribble.(DEFtES DIBBLE-O)UT WAEST ARCS)
(APPLY *DRIBULE-STREAN* ARCS)(APPLY eDRIBLE-TERNINAL* ARCS))
This is the stream for eTERNINAI-ID* daring a dribble.Depending os the message we decide to dispatch to the inputor output dribble streas.
(DEFIES DRISILE-TEUR (&REST ARCS)(CASE (CAR ARCS)
((:TYD :STRINO-OUT :LINE-OUT) (AMPY rO'RIBULE-MU ARCS))
......................
Micro-PROUST Code Page 48
(* OFFSET INITIAL-OFFSET) offset to structure elementsNANEDP vheter its namedPRINT-FUNCTION the print function or NILCONSER mave of the cosser or NILPREDICATE nmen of predicate or NIL
*The structure definition info is kept am the STRUCTURE-DESCRIPTOR property*of the structure name. It consists of a list:
* ( stot-alist type options)
(DEFNACRO DEFSTRUCT FRN(LET* ((SLOTS (NAPCAR '(LANODA (X) (IF CCONSP X) X (CONS, X)) (CDR FRN))
CS-MANE CIFE (CONSP (CAR FR!)) (CAR FR!) (CAMR FR!)))(OPTIONS (IF (CONSP (CAR FR!)) (CDAR FRN) NIL)(RESULT 1('.-ANE))(SLOT-AL 1ST))
(IF (STRINGP (CAAR SLOTS)) (POP SLOTS)) dump DOC string(NULTIPLE-VALUE-BIND (COlIC-KANE STRUCT-TYPE OFFSET KANEDP
PRINT-FUNCTION CONSER PREDICATE)(DEFSTRUCT-PROCESS-OPTIONS S-NANE OPTIONS)
(SETO SLOT-ALIST ;entries: (SLOT-KANE INDEX DEFAULT)(DO M( OFFSET (1+ M)
(SLOT SLOTS (CDR SLOT)(ALIST NIL (CONS (IF (COIISP (CDMR SLOT))
(LIST (CAMR SLOT) I (CADAR SLOT))(LIST (CAMR SLOT) M) ALIST)))
((NULL SLOT) (NREVERSE ALIST)
(PUTPROP S-KANE(LIST SLOT-ALIST Stitt of slots
STRUCT-TYPE type of structureOPTIONS options(+ OFFSET (LENGTH SLOT-ALIST) size of structureNANEDP)
'STRUCTURE-DESCRIPTOR)hook into to the type mechanism
(WEN KANEDP (SETF (GET S-KANE 'SUPER-TYPES)(CONS S-KANE (GET 'STRUCTURE 'SUPER-TYPES)
(DOLIST (SLT SLOT-ALIST) ;define accessors(PUSH COEF-ACCESSOR SLT COIC-NANE STRUCT-TYPE) RESULT))
(WHEN CONSER ;define make macro(PUSH (HAKE-STRUCTURE S-NAME CONSER NANEDP) RESULT))
(WHEN PREDICATE (PUSH PREDICATE RESULT))MWEN PRINT-FUNCTION (PUSH PRINT-FUNCTION RESULT))(CONS 'PROdN RESULT)
2. - N
Micro-PROUST Code Page 47
(DEFUN DEFSTRUCT-PROCESS-OPTIONS (STRUCT-NANE OPTIONS)(LET ((CONC-NAME (STRING-APPEND STRUCT-NANE \-)) set up defaults
(TYPE 'VECTOR)(OFFSET 1)
(INITIAL-OFFSET 0)(EXP-NANEDP) whether NANED/UNIANED specified(NANEDP T)
(PRINT-FUNCTION)
(CONSER (INTERN (STRING-APPEND 6MAKE-O STRUCT-NAE)))
(PREDICATE T))(DOLIST (OPT OPTIONS)
(CASE (IF (CONSP OPT) (CAR OPT) 'ATONIC)(:CONC-NANE
(SETQ COIC-NANE (CADR OPT)))(:TYPE
(UNLESS (MEMBER (SETQ TYPE (CADR OPT))
'(VECTOR LIST ARRAY-LEADER))(ERROR 'Illeal DEFSTRUCT type: 'SO OPT))
(UNLESS EXP-NAMEDP (SETQ NANEDP NIL))(SETQ OFFSET (UPDATE-OFFSET TYPE NANEOP)))
(:NANED(SETQ NANEDP T EXP-NANEDP T OFFSET (UPDATE-OFFSET TYPE NAMEDP)))
(:CONSTRUCTOR(SETQ CONSER (CADR OPT)))
(:PREDICATE
(SETQ PREDICATE (CADR OPT)))(:PRINT-FUNCTION
(SETQ PRINT-FUNCTION '(PUTPROP '.STRUCT-NANE.(CADR OPT)* :PRINT-FUNCTIOU)))
(:INITIAL-OFFSET (SETQ INITIAL-OFFSET (CADR OPT)))(ATOMIC
(CASE OPT((:CONSTRUCTOR :CONC-NANE)) just ignore(:NANED
(SETQ NANEOP T EXP-NANEDP TOFFSET (UPDATE-OFFSET TYPE NANEDP)))
(OTHERWISE(ERROR 'IIlegal DEFSTRUCT option: "S' OPT))))
(OTHERWISE
(ERROR 8IIegal DEFSTRUCT option: 'SO OPT))))(WHEN PREDICATE(IF (EQ PREDICATE T)
(SETQ PREDICATE (IF NANEDP(INTERN (STRING-APPEND STRUCT-NANE '-P'))
NIL))
(UNLESS NANEDP(ERROR OCan't have PREDICATE with UNNANED structure'))))
(WHEN PREDICATE(SETQ PREDICATE
'(DEFUN .PREDICATE (X).(IF (EQ TYPE 'LIST)
'(EQ (CAR X) -.STRUCT-NANE)'(TYPEP X '.STRUCT-ANE)))))
(VALUES CONC-NANE prefix for accessor macros or NILTYPE structure type
Micro-PROUST Code Page 48
(TYPE (CADR (CET STRUCT 'STRUCTURE-DESCRIPTOR)))(STRUCTURE-DESCRIPTOR (GET STRUCT 'STRUCTURE-DESCRIPTOR))(OPTIONS (DEFST-OPTIOUS (GET STRUCT 'STRUCTURE-DESCRIPTOR)))(ST))
'(DEFIACRO ANE X.(CASE TYPE
(LIST-'(LIST
DO ((S (DEFST-SLOTS (GET '. STRUCT 'STRUCTURE-DESCRIPTOR))(CDR S))
TEMP(RES .(WHEN (DEFST-NANEDP STRUCTURE-DESCRIPTOR)
'(NCOUS -.STRUCT))(IF (SETQ TEMP
(OR (GETF X (SLOT-NAME (CAR S)))(CAR (SLOT-DEFAULT (CAR S)))))
(CONS TEMP RES)(CONS NIL RES)))
((NULL S)NREVERSE RES)))))((VECTOR ARRAY-LEADER)
-'(LET ((.'.(SETQ ST (NAKE-SYNBOL 6VARN))(MAKE-ARRAY (OR (CADR (ASSOC 'LENGTH OPTIONS))
(PROGI(DEFST-SLOT-CUT STRUCTURE-DESCRIPTOR)(WHEN (EU TYPE 'ARRAY-LEADER)
(ERROROlo length for array lesder))))
.(WHEN NANEDP'(:NAED-STRUCTURE-SYNMI '.STRUCT))
.. (WHEN (EU TYPE *ARRAY-LEADER)* (:LEADER-LENGTH (LENGTH SLOT-ALIST)))
. (WHEE (OR (MENDER 'NAMED OPTIONS)(ASSOC 'NAMED OPTIONS))
* (:NANED-STRUCTURE-SYMDOL * .STRUCT))..(CDR (ASSOC 'RAKE-ARRAY OPTIONS)))))
DO ((S (DEFST-SLOTS (GET * .STRUCT 'STRUCTURE-DESCRIPTOR))(CDR S))
TEMP(OBJ (ICONS NIL))(RES NIL
(PROGN(SETO TEMP (GETF I (SLOT-NAME (CAR 5)) OBJ))(WHEN (AND (EQ TEMP OBJ) (SLOT-DEFAULT (CAR 5)))
(SETQ TEMP (CAR (SLOT-DEFAULT (CAR S)))))(IF (EQ TEMP OBJ)
RES(CONS (LIST '.(IF (EQ TYPE 'VECTOR)
'ASET 'STORE-ARRAY-LEADER)TEMP '.ST (SLOT-POS (CAR S)))
RES)))))((NULL S)(NREVERSE (CON '.ST RES))))))
(DEFUN UPDATE-OFFSET (TYPE NANEDP)(COND ((AND (EQ TYPE 'ARRAY-LEADER) *AMEDP) 2)
((OR (AND NANEDP (REQ TYPE 'ARRAY-LEADER))(AND (EQ TYPE 'ARRAY-LEADER) (NOT NAEP)))
1)(T 0)))
Micro-PROUST Code Page 45
1.6 DEFSTRUC.LSP
.ttdfstroc.lsp
Copyright (c) Gold Hill Computers. Inc. 1984
*;The DEFSTRUCT package
Notes: The DEFSTRUCT package is aot completely CONNO Lisp compatible yet.The accessor and contractors are mot fumctions as per COfNON Lisp but aremacros., this will be fixed. The slot asses is the structure constructor
;; are not keywords but just symbols. Thus for the structure:;. (DEFSTRUCT TURTLE HEADING X POS Y-POS)*; the make function would be:
(MAKE-TURTLE HEADING 90 X-POS 100 Y-POS 200).COMMON Lisp would have the slotasses be keywords. eg. :HEADING. This willbe fixed in the next release.
; The currently supported options are shoe below:
* (DEFSTRUC NANE-OR-OPTIONS &REST SLOTS); Options:
:CONC-NAME:CONSTRUCTOR:INITIAL-OFFSET
; : NAMED:PREDICATE:PRINT-FUNCTION:TYPE {VECTOR I LIST)
Accessor macros*; These macros take the object that is on the STRUCTURE-DESCRIPTOR;; property of the structure a@e.(DEFNACRO DEFS1-SLOTS X '(CAR .(CAR X))) returas structures slots
hard wired is DESCRIBE(DEFNACRO DEFST-TYPE X '(CADR .(CAR X))) returns type(DEFNACRO DEFST-OPTIONS X '(CADDR ,(CAR X))) returns all defstruct options
hard wired ia DESCRIBE(DEFNACRO DEFST-SLOT-CNT X '(NTH 3 *(CAR X))) number of slots (local?)(DEFNACRO DEFST-NANEDP X '(NTH 4 .(CAR ))) whether named structure
These macros take a slot descriptor. member of the DEFST-SLOTS list.(DEFMACRO SLOT-NANE X '(CAR .(CAR X))) mane of slot
hard wired ii DESCRIBE(DEFNACRO SLOT-POS X '(CADR .(CAR X))) structure position (local?)(DEFIACRO SLOT-DEFAULT X '(CDDR .(CAR X))) defalt form. returns a LIST
(DEFUN DEF-ACCESSOR (SLOT-D CONC-KANE TYPE)(DEFMACRO . (IF CONC-NANE
(INTERN (STRING-APPEND COUC-NANE (CAR SLOT-D)))(CAR SLOT-D))
X.(CASE TYPE
(VECTOR '(LIST 'AREF (CAR X) .(CADR SLOT-D)))(ARRAY-LEADER '(LIST 'ARRAY-LEADER (CAR X) ,(CADR SLOT-D)))(LIST '(LIST 'NTH .(CADR SLOT-D) (CAR X))))))
;;Returas the macro that will make the structure.(DEFUN NAKE-STRUCTURE (STRUCT MANE NANEDP)
(LET ((SLOT-ALIST (CAR (GET STRUCT 'STRUCTURE-DESCRIPTOR)))
• -' - '. -''" ,""'"... "/ '"-' " ' - ,' ." -' " ** ."'.. .7,,." "."' -p.. . " .". . . . . . . . . . .." ''-" ",-, ,"" • - -2 ',- - '
Micro-PROUST Code Page 44
(SETQ *VALLIST* (CONS PATH *VALLISTO)))(T(DEFNACRO-COLLECT (CAR PATTERN) (LIST 'CAR PATH))(DEFIACRO-COLLECT (CDR PATTERN) (LIST 'CDR PATH)))))
Micro-PROUST Code Page 43
(CORD ((0 STATE 0) (ERROR 08ad patters to DEFEACRO: 'SO EPAT))(T (DEFNACRO-PARSE-1 (CDR PATTERN) PATH I EPAT))))
((MEMBER (CAR PATTERN) '(&REST A ODY))(AND (EQ (CAR PATTERN) '&BODY)
(SETQ *DEFNACRO-& ODY-FLAGe T))
(AND (NULL (CDR PATTERN))
(ERROR 0Bad patter, to DEFNACRO: 'SO EPAT))
(COND (( STATE 1) (ERROR *Bad ptter. to DEFOACRO: 'SO EPAT))(T (DEFMACRO-PARSE-A (CDR PATTERN) PATH 2 EPAT))))
((EQ (CAR PATTERN) 'IAUX)(COND ((3 STATE 2) (ERROR @Bad potters to DEFEACRO: 'SO EPAT))
(T (DEFMACRO-PARSE-& (CDR PATTERN) PATH 3 EPAT))))
((z STATE 0)(DEFEACRO-COLLECT (CAR PATTERN) (LIST 'CAR PATH))
(LET ((PAIR (DEFMACR-PARSE-&
(CDR PATTERN) (LIST 'CDR PATH) 0 EPAT)))(WHEN (CDR PAIR) (INCF (CDR PAIR)))
(INCF (CAR PAIR))
PAIR))((= STATE 1)(COED ((ATOM (CAR PATTERN))
(DEFNACRO-COLLECT (CAR PATTERN)'(CAR .PATH)))
(T(AND (CAR (CDDAR PATTERN))
(PUSH (CAR (CDDAR PATTERN))
*OPTIONAL-SPECIFIED-FLAGS*))
(DEFNACRO-COLLECT (CAAR PATTERN)'(COND (.PATH
.(AND (CAR (CDDAR PATTERN))'(SETQ .(CAR (CDDAR PATTERN)) T))
(CAR .PATH))
(T .(CADAR PATTERN))))))(LET ((PAIR (DEFNACRO-PARSE-&
(CDR PATTERN) (LIST 'CDR PATH) 1 EPAT)))
(IF (NULL (CDR PAIR))
PAIR(INCF (CDR PAIR)))
PAIR))((3 STATE 2)(DEFUACRO-COLLECT (CAR PATTERN) PATH)
(VHEN (CDR PATTERN)(WHEN (OR (ATOM (CDR PATTERN))
(NOT (EQ (CADR PATTERN) '&AUX)))
(ERROR 'Bad pattern to DEFIACRO: 'SO EPAT))(DEFMACR-PARSE-1 (COOR PATTERN) PATH 3 EPAT))
(NCONS 0))((u STATE 3)(IF (ATOM (CAR PATTERN))
(DEFRACRO-COLLECT (CAR PATTERN) NIL)
(DEFMACRO-COLLECT (CAAR PATTERN) (CADAR PATTERN)))
(DEFMACRO-PARSE-& (CO PATTERN) (LIST 'CDR PATH) 3 EPAT))
(DEFUN DEFIACRO-COLLECT (PATTERN PATH)
(CORD ((NULL PATTERN))((ATOM PATTERN)
_** test of A keyvord here(SETO *VARLISTe (CONS PATTERN eVARLIST))
Micro-PROUST Code Page 42
1.4 DEFMAC.LSP
Copyright (c) Gold Hill Computers. Inc. 1384
MOTE: The &WHOLE option is sot yet supported.
(NACRO DEFNACRO (X) (DEFNACROl (CDR X)))
(DEFYAR *OPTIOUAL-SPECIFIED-FLAOS*)
whether &MOY was specified(DEFVAR eDEFNACRO-A500Y-FLACe)
;X is the cdr of the DEFNACRO for.(DEFUN DEFNACROI Wx
(LET (*VARLIST* CVALLIST* *OPTIONAL-SPECIFIED-FLACS* *DEFMACRD-ABODY-FLACe)* (LET ((PAIR (DEFMACRO-PARSE-&
(CADR X) (CDR eMACROARGe) 0 (CADR W)(BDDY (CDDR W)
(NACRD . (CAR X) (*NACROARG*).IF (NOT (AND (ZEROP (CAR PAIR))
(MULL (CDR PAIR))))((AND .(CONID ((EROP (CAR PAIR))
'(3 (LENGTH CNACROARGe).(I* (CDR PAIR))))
((NULL (CDR PAIR))C'< (LENGTH *MACROARGe)
.(I+ (CAR PAIR))))(T '(OR C (LENGTH eNACROARG*)
.(I+ (CAR PAIR)))(v (LENGTH *NACROARGe)
* -.-. (I* (CDR PAIR))))))(ERROR OVrong somber of ergs to macro: -SO
eMACROARO))))J DEFNACRD2 (IREVERSE $VARLIST$) (IREVERSE *VALLISTC)
COPTIONA-SPECIFIED-FLACSO BODY)))))
Put together the various bindings and the body.The VARS are bound sequentially since their initializations ay dependoa each other (in left-to-right fashion).
(DEFUN DEFNACRD2 (VARS VALS FLAGS BODY)'(LET* CO6FLAGS
NMAPCAR #*(LANBOA CX Y)CLIST X Y)) VARS VALS)(*XACROARIO . (IF (CDR BODY)
(PROGN . BODY)(CAR BODY))))
(IF (COWS *NACROARGIC)* (RPLAC9 *NACROARCC *NACROARCI a)
oMACROARGe))
* (DEFUN DEFMACR-PARSE-A (PATTERN PATH STATE EPAT)(COND ((NULL PATTERN) (CON 0 0))
((ATOP PATTERN)-'(COED ((), STATE 1) (ERROR 659d pattern to DEFIACRO: 'SO EPAT))U CT (DEFNACRO-COLLECT PATTERN PATH)
(ICONS 0))))((EQ (CAR PATTERN) 'AOTIONAL)
Micro-PROUST Code Page 41
sum-is-counter ssignment-bmckuvards))(setf emissing-ruless '(missing-exception-guord sissing-internat-guard
sssfg-guarded-counter))
Load the files before we start for smoother operation.(coed ((functionp 'make-window-stream) 0)
(t (load 9lisplib\\vstreaa.lsp6)));(coad ((functiomp 'dribble) 0)
(t (load 5lisptib\\dribbl*.lsp*)))
Some useful macros from CONNON Lisp(DEFNACRO VITH-OPEN-STREAN X
'(LET (.(CAR X))(UNWIND-PROTECT
(IF (CDDR X)'(PROGN .CDR W)(CADR W)
(CLOSE .(CAAR X)))))
(DEFNACRO WITH-OPEN-FILE X'(WITH-OPN-STREAK (.(CAAR X) (OPEN .CDAR X))
.CDR X)))
(a-proust)
Micro-PROUST Code Page 40
input before lime 'a is executed. The 'e is not defimed whemthere is no input.'
(mode-lie (or (car (bug-compontent bug)) *parse-tree))(get (bug-goal bug) 'name-phiase)))
;ANissing-intersol-guard rule
'(missing-iaternal-gumrd (component .(cdr (aso 'maimloop:(ins-bindings plan))))
(goal .(car *active-goals))))
(dps missing-internal-guard plan-component interimal-guard:action missing-internal-guard-actionreport-fun report-aissiog-interaa I-guard)
(defun report-missing-internal-guard (bug)(format t*You'r* missing a sentinel guard in the loop beginning at line 'a. When
your program reads the sentinel, it processes it as if it were date.*(node-liet (or (car (bug-component bug)) eparse-tre))))
;;Nissiog-guarded-comster rule
(defun missing-guarded-counter-action 0)(missinig-guarded-counter (component ..(cdr (assioc 'input:
(ins-bindis piss) )))
(dps missing-guarded-counter plan-comiponest process:piss bad-input-loop-gardaction missi ng-goarded-counter-ect ionreport-fun report-missing-guarded-counter)
(defun report-missing-guarded-counter (bug)(foreat tnYou'r* missing a sentinel guard. If a sentinl value is input immediately
following a negative vaice at lie* 'a. your program will process itas if it were date.*
(node-line (or (car (bug-component bug)) eparse-tree))))
K;iss-internal-guard report
(defu report-issinteral-guard (bug)(format t'Your program does not perform as input valideticam0))
(dps loop-input-validation report-fun report-miss-internal-guard)
;Rule list
(setf *malformed-rulese '(read-is-counter while-for-if
Micro-PROUST Code Page 39
(dps sum-is-counter found I plan running-total action sue-is-counter-mction% report-fun report-sum-is-counter)
(defy. report-su-is-counter (bug)(format t'You are using a counter update instead of a runniag-total update at
line 'a. You must add the value of 'a to the variable a. not add I to it.'(node-line (bvg-statement bug))
(resolve-var-ref 'new 'sentinel-controlled-loop)
(node-name (car (node-children (bug-statemet bug))))))
;;Assignsent-backwards rule
(defun assignment-backwards-test 0(and (equal (length (satch-frame-errors match-frame)) 2)
(equal (node-name (match-frame-code match-frame)) ':u)(equal (length (node-children (match-frame-code match-frmee))) 2)
(equal (caar (match-frame-errors match-frame))
(cdadr (match-frome-errors match-frame)))(equal (cdar (match-frame-errors match-fraae))
(caadr (match-frame-errors match-frame)))
(incf explained-errors)
(incf explained-errors)))
(defun assignment-backwards-action 0
'(assigmnent-backwards (statement . match-frome)))
(dps assignment-backwards plan-component update:
test-code assignment-backwards-test
action assignment-backwards-actionreport-fun report-assigment-backwards)
(defun report-assignment-backvards (bug)(format t'The assignment at line 'a is backwards. This lime will assign to 'a;
you need to assign to 'a.0(node-line (bug-statement bug))(node-nane (car (node-children (bug-statement bug))))(node-name (cadr (node-children (bug-stoatement bug))))))
;;issing-exception-guard-rule
(defv missing-exception-guard-action 0)'(missing-exception-guard (component . .(cdr (assoc 'code
(ins-bindings plan))))
(goal .(cdr (assoc 'gOal
(ins-bindins plan))))))
(dps missinr-exception-guard plan-component exception:action missing-exception-guard-actionreport-fun report-missing-uard-exception)
(defv report-missing-guard-exception (bug)
(format t.Yov need a test to check that at least one valid data point has bees
Micro-PROUST Code Page 53
1.3 EXAMPLE3.PAS
PROGRAM NOAH (INPUT ,OUTPUT);
VAR
RAINFALL. LARGEST. SUN. COUNTI.
COUNT2. AVERAGE. RAINYDAYS : REAL;
BEGIN(4 INITIALIZE VARIABLES 0)
LARGEST :=0;SUN :=0;COUNTI :=0;COUNT2 :=0;
AVERAGE :=0;RAINYDAYS :=0;(*READ THE RAINFALL AND CHECK FOR ERROR VALUES s)
WRITELN CENTER RAINFALL. WHEN YOU ARE FINISHED ENTER 9999');
READLN;
READ (RAINFALL);
WHILE RAINFALL <> 9999 DO
BEGIN
WHILE RAINFALL <0 DO
BEGINVRITELN (RAINFALL :B.'IS NOT A POSSIBLE RAINFALL. TRY AGAIN.');
WRITELN ('ENTER RAINFALL');READLN;
READ (RAINFALL)
END;
IF RAINFALL > LARGEST
THENLARGEST :=RAINFALL;
IF RAINFALL ' 0
THENCOUNT2 :=COUNT2 * 1;
COUNTI :- COUNTI + 1;
SUN :a SUN + RAINFALL;
READLN;READ (RAINFALL)
END;
AVERAGE :a SUN/COUNTI;
WRITELN (COUNTI :8. 'VALID RAINFALLS WERE ENTERED.');
WRITELN ('THE AVERAGE RAINFALL WAS', AVERAGE :9, 'INCHES PER DAY.');
WRITELN ('THE HIGHEST RAINFALL WAS'. LARGEST :0:2. 'INCHES.');
WRITELN ('THERE WERE'. COUNT2 :0:2. 'RAINYDAYS IN THIS PERIOD.')
END.
I
p
Micro-PROUST Code Page 54
111.4 EXAMPLE4.PASPROGRAN RAINFALL CINPUT.OUTPUT )
VARRAIN. DAYS. TOTAIRAIN. RAINDAYS. HIONRAIN. AVERAIN: REAL;
BEGINDAYS :x 0.TDTALRAIN :a 0;RAINDAYS U0;
HIGHRAIN :~0;
REPEATWRITELE ('ENTER RAINFALL');
* READIN;READ (RAIN);
*WILE RAIN "~ 9999 DOBEGIN
* DAYS *DAYS.# 1;TOTALRAIN := TOTALRAIN + RAIN;IF RAIN )- 0 THEN
* RAINDAYS :a RAINDAYS # 1;IF RAIN ),HIONRAIN THEN
HICNRAIN :z RAINEND
UlNTIL RAIN z 9999;
AVERAIN :*TOTALRAIN /DAYS;
WRITEIN;VRITEIN (DAYS:0:O. 'VALID RAINFALLS WERE ENTERED');WRITELN;WRITELE ('THE AVERAGE RAINFALL WAS'.AVERAIN:0:2.'INCHES PER DAY');WRITEIN;VRITELN ('THE HIGHEST RAINFALL WAS' .HIGHRAIN:0:2. 'INCHES'):WRITEIN;WRITELE ('THERE WERE' .RAINDAYS:O:0. 'IN THIS PERIDI';
END.
Micro-PROUST Code Page 55
11.5 EXAMPLE5.PASPROGRAN TESTI(INPJT. OuTPUT);VAR
StfiN .N fAX. A yE:REAL;COULiT.RAINY: INTEGER;
BEGINStN: SO;COUNT:0O;5 RAINY :ni.NAX :0O:
% WRITELNV ENTER RAINFALL');READIN;RE AD(%);WHILE Nt>99gg DOBEGINIF N(0 THENWRITELN(N:0:2.' IS NOT A POSSIBLE RAINFALL. TRY AGAIN')
ELSEBEGIN
COUNT: zCDtMT*1.
IF N>0 THEEq RAINY'f:4AINY+I;
IF N>NAX THENN:=NAX;
END;WRITELN(ENTER RAINFALL');READLN;READ (N
END;VRITELN;IF COtNTzO THENVRITELN(CDUNT:.' VALID RAINFALLS WERE ENTERED.')
ELSEBEGIN
AVE:=SUN/COUNT;VRITELN('THE AVERAGE RAINFALL WAS '.AVE:0:2.' INCHES PER DAY.);VRITELN('THE HIGHEST RAINFALL WAS '.NAX:0:2.' INCHES.');WRITELN('THERE WERE '.RAINY:0.' RAINY DAYS IN THIS PERID.')
ENDEND.
Page 56Micro-PROUST Code
.U.S EXAMPLEA.PAS
PROGRAN Average (inputoutput);
VAR Sun. Count. New: INTEGER;
Avg: REAL;
BEGINSu :x 0;Count :a 0;Read (New);WHILE Nev>99
99 DO
BEGINSum := Sum.New;Count := Countl;
Read (New)
END;IF Covet s 0THEN VRITELN ('No average')
ELSE BEGINAvg :s Sum/Count;VRITELN ('The average is .Ovg);
END
END;
..
Micro-PROUST Code Page 57
I1.7 EXAMPLER.PASPROGRAN TEST1(INPUT. OUTPUT):
VAR
SUN.N.NAX.AVE:REAL;COUNT, RAINY: INTEGER;
BEGIN
SUN: =O;COUNT:=0;RAINY :w0;
NAX :z0:VRITELN('ENTER RAINFALL');
READLN;READ(N);WHILE N<>9999 DO
BEGIN
IF NO THENVRITELN(N:O:2.' IS NOT A POSSIBLE RAINFALL. TRY AGAIN')
ELSEBEGINCOUNT:=COUNT+I;
SUN:SUN*N;IF N>O THENRAINY: =RAINY*I;
IF N>NAX THENNAX:N,
END;
VRITELN ('ENTER RAINFALL');
READLN;READ(N)
END;
WRITELN;IF COUNTRO THEN"RITELN(COUNTO.' VALID RAINFALLS WERE ENTERED.')
ELSEBEGIN
AVE:xSUN/COUNT;
.RITELN(COUNT:O.' VALID RAINFALLS WERE ENTERED.');RITELN('THE AVERAGE RAINFALL WAS '.AVE:0:2.' INCHES PER DAY.');
WRITELN(THE HIGHEST RAINFALL WAS ',NAX:0:2.' INCHES.');
WRITELNC'THERE WERE '.RAINY:O,' RAINY DAYS IN THIS PERIO.')
END
END.
* '* , . . . . . *... . -.--.. '. . . . . .... . .. . . * *"- :" % ' " "-" ' - . " ' , :''' ,' '' ' ' , ; " ' . '"., " :' .'" ' . '-..-" ' .--. ._ , . .;. ' -
Micro-PROUST Code Page 58
"I. Problem Specifications
M.1 AVERAGE.PRB
Average Problem AVERAGE.prb
Taken from Nicro-Proust, Design Spec 10/23/84
(goal .average) uas added to guard exception to akebug reporting for missimg-exception-guard micer
((sentinel-control led-loop (stop 9999))
(average)(covet (covet . (over* count average)))
* "(see (neu . (evar* new sentinel-comtrolled-loop))(total , (evar* sum average)))
(output (val . (evar* vg average)))(guard-excoption (code (ever* output: output))
(pred. (a (evar* count count) 0))
(goal . average))(guard-exception (code * (evar* update: average))
(prod. (a (evere count couet) 0))
, (goal average)))
*o J
i-
Micro-PROUST Code Page 59
111.2 RAINFALL.PRB
Rainfall Problem Description RAINFALL.prb*Taken from Nicro-Proust Design Spec 10/23/84
(goal . ) added to guard-exception to ale* bug reporting nicer
((sentiaet-coatrolled-loop (stop . 9999))(loop-input-validation (mew (*var* new sentinel-controtted-loop))
(prod (oer* new sentinet-controlted-loop) 0)))
(a verage)(count (count (*ere count average)))(output (vat (*var$ avg average)))(guard-exception (code .(evar$ output: output))
(pred .(- (*vare count count) 0))(goal average))
(output (vat . (*ware count count)))(sum (new . (evar* new sentinel-controlled-loop))
(total .(evar* sum overage)))(guarded-count (pred . (ov(ear* now sentinel-controlled-loop) 0)))(output (val .(evar* count guarded-count)))(maximaum (new .(evar* new sentinel-controlled-loop)))
p (output (vat[ (evare max maxious)))(guard-exception (code .(*vmr* update: average))
(prod . ( (ear* coant count) 0))(goa I overage))
(guard-exception (code .(*war* output: output))(prod . u(ever* count count) 0))(goal .maximum)))
FILMED
DTIC