You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
br-parser-tools/collects/mrdemo/toyproof.ss

378 lines
11 KiB
Scheme

;; Toy proof checkers implemented with MrEd and units
;; Kathi Fisler
;; September 3, 1996
;; This code demonstrates the combined use of MrEd and units to
;; implement a collection of simple proof checkers.
;; Proof Checker Architecture:
;;
;; A proof checker consists of two main components: a list of
;; operations supported by the checker and the interface through which
;; the user invokes the checker. Each of these components is
;; implemented as a unit in the code below.
;;
;; The "operations" unit, (signature prover-core^) provides a list
;; containing the names of the operations, a list containing the
;; operations corresponding to the names, and a default operation.
;;
;; The "interface" unit (signature interface^) is a compound unit with
;; subunits corresponding to the various pieces of the interface.
;; Subunits exist for how the user inputs data to the checker, how the
;; checker displays results to the user, how the user selects from
;; among the possible operations, how the user instructs the checker
;; to check the current data against the selected operation, and how
;; the user exits the checker. The interface unit combines these
;; subunits into a main interface and provides a function
;; (create-interface) that can be invoked to create a checker with the
;; specified interface components and the specified operations from
;; the operations unit.
;; The Collection of Checkers
;;
;; Each of the implemented checkers contains three objects into which
;; the user can enter data and one object through which the checker
;; displays results. Two operations units are provided:
;; proof-core-calculator@ and proof-core-tester@. The former computes
;; simple arithmetic functions over the three inputs and the latter
;; tests boolean-valued relationships between the three inputs. The
;; checker displays the values returned by either type of operation.
;;
;; Two types of interfaces are possible: one in which the operations
;; are selected through radio boxes and the other in which the
;; operations are selected through menu options.
;;
;; Three checkers are defined explicitly at the end of the code:
;; make-calculator/radio, make-checker/radio, and make-checker/menu,
;; each taking the appropriate combination of the described interface
;; and operations units.
;;;;; The Implementation ;;;;;
(require-library "trigger.ss")
;;;;; Signature Definitions ;;;;;
(define-signature prover-core^
(proof-rule-names proof-rule-checkers default-rule-checker))
(define-signature num-entry-interface^
(create-num-entry-interface get-numbers))
(define-signature result-display-interface^
(create-result-display-interface show-result))
(define-signature rule-select-interface^
(create-rule-select-interface
current-proof-rule set-current-proof-rule))
(define-signature compute-interface^
(create-compute-interface))
(define-signature quit-interface^
(create-quit-interface))
(define-signature main-interface^
(create-interface quit-prover))
(define-signature interface^
((open main-interface^)))
;;;;; Compound Unit Definitions ;;;;;
(define interface@
(lambda (numentry resdisplay ruleselect compute quit main)
(compound-unit/sig
(import (MRED : mred^) (CORE : prover-core^))
(link
(NUMENTRY : num-entry-interface^ (numentry MRED))
(RESDISPLAY : result-display-interface^ (resdisplay MRED))
(RULESELECT : rule-select-interface^ (ruleselect CORE MRED))
(COMPUTE : compute-interface^ (compute RESDISPLAY RULESELECT
NUMENTRY MRED))
(QUIT : quit-interface^ (quit MAIN MRED))
(MAIN : main-interface^ (main NUMENTRY RESDISPLAY
RULESELECT COMPUTE QUIT MRED))
)
(export (open MAIN)))))
(define prover@
(lambda (core interface)
(compound-unit/sig
(import (MRED : mred^))
(link
(CORE : prover-core^ (core))
(INTERFACE : interface^ (interface MRED CORE)))
(export (open INTERFACE)))))
;;;;; Primitive Unit Definitions ;;;;;
;;;;;;;; Interface Units ;;;;;;;;
(define main-interface-no-menus@
(unit/sig main-interface^
(import num-entry-interface^ result-display-interface^
rule-select-interface^ compute-interface^
quit-interface^ (mred : mred^))
(define outer-frame
(make-object mred:frame% `() "Toy Prover"))
(define v-panel
(make-object mred:vertical-panel% outer-frame))
(define upper-hpanel
(make-object mred:horizontal-panel% v-panel))
(define lower-hpanel
(make-object mred:horizontal-panel% v-panel))
(define create-interface
(lambda ()
(create-num-entry-interface upper-hpanel)
(create-result-display-interface lower-hpanel)
(create-compute-interface upper-hpanel)
(create-quit-interface upper-hpanel outer-frame)
(create-rule-select-interface lower-hpanel)
(send outer-frame show #t)))
(define quit-prover
(lambda ()
(send outer-frame show #f)))
))
(define main-interface-menus@
(unit/sig main-interface^
(import num-entry-interface^ result-display-interface^
rule-select-interface^ compute-interface^
quit-interface^ (mred : mred^))
(define myframe%
(class mred:standard-menus-frame% args
(rename [super-make-menu-bar make-menu-bar])
(public
[make-menu-bar
(lambda ()
(let ([mb (super-make-menu-bar)])
(create-rule-select-interface mb)
mb))]
[panel% mred:vertical-panel%]
)
(sequence (apply super-init args))))
(define outer-frame
(make-object myframe% null "Toy Prover"))
(define v-panel (ivar outer-frame panel))
(define upper-hpanel
(make-object mred:horizontal-panel% v-panel))
(define lower-hpanel
(make-object mred:horizontal-panel% v-panel))
(define create-interface
(lambda ()
(create-num-entry-interface upper-hpanel)
(create-result-display-interface lower-hpanel)
(create-compute-interface upper-hpanel)
(create-quit-interface upper-hpanel outer-frame)
(send outer-frame show #t)))
(define quit-prover
(lambda ()
(send outer-frame show #f)))
))
(define num-entry-interface-3text@
(unit/sig num-entry-interface^
(import (mred : mred^))
(define num1 (void))
(define num2 (void))
(define num3 (void))
(define create-num-entry-interface
(lambda (panel)
(set! num1
(make-object mred:text% panel (lambda (self event) #f)
"" ""))
(set! num2
(make-object mred:text% panel (lambda (self event) #f)
"" ""))
(set! num3
(make-object mred:text% panel (lambda (self event) #f)
"" ""))))
(define get-numbers
(lambda ()
(map string->number
(list (send num1 get-value)
(send num2 get-value)
(send num3 get-value)))))
))
(define result-display-interface-text@
(unit/sig result-display-interface^
(import (mred : mred^))
(define resdisplay (void))
(define create-result-display-interface
(lambda (panel)
(set! resdisplay
(make-object mred:text% panel (lambda (self event) #f) "Result"))
))
(define show-result
(lambda (res)
(send resdisplay set-value
(cond ((string? res) res)
((number? res) (number->string res))
((boolean? res) (if res "True" "False"))
(error "Argument of Unknown Type")))))
))
(define rule-select-interface-radio@
(unit/sig rule-select-interface^
(import prover-core^ (mred : mred^))
(define current-proof-rule default-rule-checker)
(define set-current-proof-rule
(lambda (rule)
(set! current-proof-rule rule)))
(define create-rule-select-interface
(lambda (panel)
(make-object mred:radio-box%
panel
(lambda (self event)
(set-current-proof-rule
(list-ref proof-rule-checkers
(send self get-selection))))
"" -1 -1 -1 -1
proof-rule-names)))
))
(define rule-select-interface-menus@
(unit/sig rule-select-interface^
(import prover-core^ (mred : mred^))
(define current-proof-rule default-rule-checker)
(define set-current-proof-rule
(lambda (rule)
(set! current-proof-rule rule)))
(define create-rule-select-interface
(lambda (mb)
(let ([rules-menu (make-object mred:menu%)])
(map
(lambda (name checker)
(send rules-menu append-item name
(lambda ()
(set-current-proof-rule checker))))
proof-rule-names
proof-rule-checkers)
(send mb append rules-menu "Rules"))))
))
(define compute-interface-button@
(unit/sig compute-interface^
(import result-display-interface^ rule-select-interface^
num-entry-interface^ (mred : mred^))
(define create-compute-interface
(lambda (panel)
(make-object mred:button%
panel
(lambda (self event)
(show-result
(apply current-proof-rule (get-numbers))))
"Apply Rule")))))
(define quit-interface-button@
(unit/sig quit-interface^
(import main-interface^ (mred : mred^))
(define create-quit-interface
(lambda (panel outer-frame)
(make-object mred:button%
panel
(lambda (self event) (quit-prover))
"Quit")))))
;;;;;;;; Prover Core Units ;;;;;;;;
(define proof-core-calculator@
(unit/sig prover-core^
(import)
(define-struct proof-rule (name checker))
(define proof-rules
(list
(make-proof-rule "Add" +)
(make-proof-rule "Mult" *)
(make-proof-rule "Max" max)))
(define proof-rule-names (map proof-rule-name proof-rules))
(define proof-rule-checkers (map proof-rule-checker proof-rules))
(define default-rule-checker (car proof-rule-checkers))))
(define proof-core-tester@
(unit/sig prover-core^
(import)
(define-struct proof-rule (name checker))
(define square
(lambda (num)
(* num num)))
(define proof-rules
(list
(make-proof-rule "Test Add"
(lambda (num-1 num-2 num-3)
(= num-3 (+ num-1 num-2))))
(make-proof-rule "Test Mult"
(lambda (num-1 num-2 num-3)
(= num-3 (* num-1 num-2))))
(make-proof-rule "Test Increasing"
(lambda (num-1 num-2 num-3)
(and (< num-1 num-2)
(< num-2 num-3))))
(make-proof-rule "Test Triangle"
(lambda (num-1 num-2 num-3)
(= (square num-3)
(+ (square num-1) (square num-2)))))
))
(define proof-rule-names (map proof-rule-name proof-rules))
(define proof-rule-checkers (map proof-rule-checker proof-rules))
(define default-rule-checker (car proof-rule-checkers))))
;;;;; Creating Provers ;;;;;
(define make-calculator/radio
(lambda ()
(invoke-open-unit/sig
(prover@ proof-core-calculator@
(interface@ num-entry-interface-3text@
result-display-interface-text@
rule-select-interface-radio@
compute-interface-button@
quit-interface-button@
main-interface-no-menus@))
#f (mred : mred^))
(create-interface)))
(define make-checker/radio
(lambda ()
(invoke-open-unit/sig
(prover@ proof-core-tester@
(interface@ num-entry-interface-3text@
result-display-interface-text@
rule-select-interface-radio@
compute-interface-button@
quit-interface-button@
main-interface-no-menus@))
#f (mred : mred^))
(create-interface)))
(define make-checker/menu
(lambda ()
(invoke-open-unit/sig
(prover@ proof-core-tester@
(interface@ num-entry-interface-3text@
result-display-interface-text@
rule-select-interface-menus@
compute-interface-button@
quit-interface-button@
main-interface-menus@))
#f (mred : mred^))
(create-interface)))