Search code examples
prolog

I don't know why my prolog code won't run


I have to create a project for school where it generates a random story, but for some reason it won't run and I don't know what I am doing wrong.

Output:

?- go.
ERROR: Unknown procedure: (=>)/2
ERROR:   Rules must be loaded from a file
ERROR:   See FAQ at https://www.swi-prolog.org/FAQ/ToplevelMode.txt
ERROR: In:
ERROR:   [12] start=>_12692
ERROR:   [11] story(start) at c:/users/kelli/onedrive/desktop/prolog/compproject2.pl:10
ERROR:   [10] go at c:/users/kelli/onedrive/desktop/prolog/compproject2.pl:16
ERROR:    [9] toplevel_call(user:user:go) at c:/program files (x86)/swipl/boot/toplevel.pl:1158
   Exception: (12) start=>_12166 ? creep
   Exception: (11) story(start) ? creep

Here is my code:

:-op(600, xfy, =>).

story([]).
story(A * B):- story(A), story(B).
story(A + B):-makelist(A + B, L),
    length(L, M),
    p is random( M)+1,!,
    nth1(p, L, X),
    story(X).
story(A) :- A => B, !, story(B).
story(A) :-atomic(A), write(A), nl.

makelist(A + B, [A|C]):-makelist(B,C).
makelist(A, [A]).

go:-story(start), write('---------the end--------'), nl.

:- write('Enter go. to be told stories.'), nl.

start=>'Earth'*(catastrophe + science + attack + collision).
catastrophe=>(('burns up' + 'freezes' + 'falls into the sun')
             *'and'
             *possible_megadeath).
collision=>('is struck by a giant'
           *('comet' + 'asteroid' + 'cloud')
           *('but is saved.' + 'and is destroyed.' +saved)
           ).
possible_megadeath=>('everybody dies.' + ('some people'+ 'everybody' + 'almost everybody')*('dies.'+rescued+saved)).
rescued=>('is rescued by'*sizes*extraterrestrial*beings).
saved=>('but is saved by '*('earth'+extraterrestrial)* 'scientists.'* 'The'*science).
science=>('scientists'*('invent' + 'discover')*sizes*beings*whichetc).
attack=>('is attacked by'*sizes*extraterrestrial*beings*whichetc).
sizes=>('tiny' + 'giant' + 'enormous').
extraterrestrial=>('Martian' + 'Lunar' + 'ExtraGalactic').
beings=>('bugs' +'reptiles' +'blobs' +'superbeings').
whichetc=>('who' *(wantwomen + ('are friendly' *('.' +
                  ('and'*(denouement + happyending))) + (
                  ('are friendly'*'but misunderstood' +
                  'misunderstand us' +
                  'understand us all too well' + hungry) *butetc) +
          (hungry * ('and eatus.'+denouement))))).
hungry=> 'look upon us as a source of nourishment'.
wantwomen=>'want our women, and take a few and leave'.
butetc=>('and are' + 'and are not')*'radioactive'*'and'*try_to_kill.
killers=>(killer + killer*'and'*killer ).`
killer=>('a crowd of peasants'
        + 'the Army'
        + 'the Navy'
        + 'the Air Force'
        + 'the Marines'
        + 'the Atom Bomb').
try_to_kill=>(('can be killed by'*killers*'.') +
             ('can not be killed by'*killers*soetc)).
soetc=>('but they die from catching a cold.'
       + 'so they kill us.'
       + 'so they put us under a benign dictatorship.'
       + 'so they eat us.'
       + ('so scientists invent a weapon'
         *('which turns them into disgusting lumps' +
          'which kills them' +
          'which fails,'*soetc))
       +('But'*denouement)).
denouement=>(('a cute little kid convinces them people are OKk.' *ending)
           + ('a priest talks to them of God,' *ending)
           + ('they fall in love with this beautiful girl' *(ending + happyending))).
ending=>('and they die.'
        + 'and they leave.'
        + 'and they turn into disgusting lumps.').
happyending=>'and they get married and live happily ever after'.

grammar:-Nonterminal=>Expansion, write(Nonterminal),
    write(' ---> '), nl, write('   '), write(Expansion), nl, nl, fail.
:- write('Enter grammar. to list the rules generating the stories.'), nl.

Solution

  • ?- go.
    ERROR: Unknown procedure: (=>)/2 
    
    ?- trace, go.
    Call: (11) go ? creep
    Call: (12) story(start) ? creep
    ERROR: Unknown procedure: (=>)/2
    

    Your code has:

    story([]).           % story(start) is not passing an empty list, skip this.
    
    story(A * B):-       % nor an A * B term, skip this one.
    
    story(A + B):-       % nor an A + B term, skip this one.
    
    story(A) :- A => B   % here! story(start) tries this. => doesn't exist. Error
    

    You do say :- op(600, xfy, =>) which makes it an operator, but you still need to code what the operator does, as a predicate with two arguments:

    =>(A, B) :- ... code here ....