!  Speak Up.
!
!  This program conducts a conversation, or a monologue.
!  It keeps a warehouse of sentences in "Speak Data", and
!  uses these to construct new sentences.
!
!  It builds new sentences word by word.  After each word,
!  it choses the next word: this pair must have occured
!  together somewhere in the sentence warehouse.  This
!  algorithm gives a semblence of meaning...
!
!  We've primed "Speak Data" with proverbs by William Blake.
!  If you engage in conversation, all your sentences will
!  be added to the sentence warehouse, and will be used
!  as raw materials for subsequent speech.
!
!  This program is based on Tim Stryker's "Brain" program
!  from a very long time ago.  Thanks, Tim.
!
!
LIBRARY "AmigaLib*"

RANDOMIZE
CALL init
SET margin 60

CALL Say("Hello there.  Please wait a minnut. o kay.")

OPEN #1: name "Speak Data", create newold, organization text
DO while more #1
   LINE INPUT #1: sentence$
   CALL Digest(sentence$)
LOOP
RESET #1: end

PRINT "I would like to do some talking."
PRINT "Do you want to have a conversation";
LINE INPUT s$
IF Ucase$(s$[1:1])<>"Y" then
   FOR sp = 1 to 30*Rnd+15
       CALL Speak
   NEXT sp
ELSE
   DO
      LINE INPUT sentence$
      IF sentence$ = "" then EXIT DO
      CALL Say(sentence$)
      PRINT #1: sentence$
      CALL Digest(sentence$)
      FOR sp = 1 to 3*Rnd+1
          CALL Speak
      NEXT sp
   LOOP
END IF
CALL Say("Thank you.  This has been very enjoyable.")


DIM word$(1000), succ$(1000)

SUB Breakup(p$,w$)
    LET p$ = Trim$(p$)
    LET p = Pos(p$," ")
    IF p=0 then LET p=Maxnum
    LET w$ = p$[1:p-1]
    LET p$[1:p] = ""
END SUB

SUB Digest(sentence$)
    LET prev = wd_START
    DO while sentence$<>""
       CALL Breakup(sentence$,wd$)
       CALL Lookup(wd$,curr)
       CALL Addsucc(prev,curr)
       LET prev = curr
    LOOP
    CALL Addsucc(prev,wd_END)
END SUB

SUB Addsucc(prev,curr)
    LET x$ = ""
    CALL Packb(x$,1,16,curr)
    LET succ$(prev) = succ$(prev) & x$
END SUB

SUB Lookup(wd$,index)
    LET index = wd_END+1
    DO
       LET index = index+1
       IF word$(index) = "" then LET word$(index)=wd$
    LOOP until word$(index) = wd$
END SUB

SUB Speak
    LET speech$ = ""
    LET i = wd_START
    DO
       CALL Divide(Len(succ$(i)),2,n,r)     !number of entries (2 bytes each)
       LET n = Int(rnd*n)
       LET i = Unpackb(succ$(i),16*n+1,16)
       IF i = wd_END then EXIT DO
       PRINT word$(i); " ";
       LET speech$ = speech$ & word$(i) & " "
    LOOP
    PRINT
    CALL Say(speech$)
END SUB

SUB Init
    LET wd_START = 1
    LET wd_END   = 2
    LET word$(wd_START), word$(wd_END) = " "
END SUB

END
