Pengines shows input text after input

Hey, i dont know to name my problem the right way, but i got a problem while using pengines.
This is my whole code so far. You can try it with swish :slight_smile:

<!DOCTYPE HTML>

<html>
<head>
  <meta charset="UTF-8">
  <title>Create sine table using Pengines</title>
  <script src="https://code.jquery.com/jquery-2.1.3.min.js"
  type="text/javascript">
</script>
  <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>

  <script src="https://swish.swi-prolog.org/pengine/pengines.js"
          type="text/javascript">
  </script>

<script type="text/x-prolog">
  /*Brand,Model,Cores,clockrate,onBoard-graphics(true,false),max-ram*/
  processor(intel,'i3-3220',2,3300,true,32).
  processor(intel,'i5-8400',6,4000,true,128).
  processor(intel,'i7-8750H',6,4100,true,64).
  processor(amd,'ryzen 5 3600',6,4200,false,128).
  processor(intel,'i7-11850HE',8,4700,true,128).
  processor(amd,'ryzen threadripper 3990X',64,4300,false,256).
  
  
  /*brand,model,graphics memory*/
  graphiccard(nvidia,'geforce gtx 1050',2).
  graphiccard(nvidia,'geforce gtx 1050 ti', 4).
  graphiccard(nvidia,'geforce rtx 2080',8).
  graphiccard(nvidia,'geforce rtx 3080',10).
  
  /*Games specs- (name,ram, graphic memory, needed space , cores, clockrate)
  */
  game('cyberpunk 2077',12,6,70,4,4000).
  game('valorant',4,4,8,4,3400).
  game('warzone',12,6,175,6,3700).
  game('gtav',8,2,72,4,3600).
  game('minecraft',4,2,4,4,3900).
  game('test',2,2,20,6,4200).
  
  /*programs- (name,cores,clockrate, graphicmemory, ram, needed space*/
  program('photoshop',2,2000,4,8,4).
  program('after effects',4,3000,16,4,15).
  program('premiere pro',8, 4000,16,4,8). 
  program('blender',4, 4000, 6, 16,0).

  go :-
    pengine_input("Gaming oder Office",Type),
    (Type = 'Gaming'->
    pengine_input("Gaming also, welche spiele?", Game1),
    pengine_output(Game1),
    game(Game1,A,Y1,B,X1,Z1),
    graphiccard(V,W,Y2),
    processor(Name,Model,X2,Z2,Grafik,Ram),
    Y1 =< Y2, X1 =<X2, Z1=<Z2,
    pengine_output("Unsere Empfehlung ist:"),
    pengine_output(V),
    pengine_output(W),
    pengine_output("With:"),
    pengine_output(Y1),
    pengine_output(" GB Grafikspeicher"),
    pengine_output("Und"),
    pengine_output(Name),
    pengine_output(Model);
    Type='Office' -> pengine_input("Welche Programme",Programm1),
    pengine_output(Programm1),
    program(Programm1,Cores,Clock,Graph1,Ram,Space),
    graphiccard(V,W,Graph2),Graph1 =< Graph2, 
    pengine_output("<b>Unsere emofehlung:</b> "),
    pengine_output(V),
    pengine_output(W)).
    


</script>

<script type="text/javascript">
jQuery(document).ready(function() {
  $('.js-example-basic-multiple').select2();
});
var buttonstep = 0;
var pengine = new Pengine({ server: "https://swish.swi-prolog.org/pengine",
          ask:'go',
          application: "swish",
          onprompt:handlePrompt,
          onoutput:handleOutput
          });
        
 
          /* Print pengine_input text X of "pengine_input(X, input)*/
          function handlePrompt(){
            $("#msg").html("<h1>" + this.data + "hhh" + "</h1>");
          }
            function handleOutput() {
                if(this.data != "[object Object]"){
                $('#answer').append(this.data + "<br/>");
                }
		   }
          function buttonclick(){
          var o = $('.js-example-basic-multiple').select2('data')[0].text;
          pengine.respond("'" + o + "'");
          buttonstep++;
          if(buttonstep==1 && o == "Gaming"){
              var data = {
                  "games": [
                {
                  id: 1,
                  text: 'gtav'
                 },
                {
                    id:2,
                    text:'valorant'
                }
                      ],
              }
            $('.js-example-basic-multiple').empty().trigger('change');
            for(var i = 0; i < data.games.length; i++) {
                var text = data.games[i].text;
                var id = data.games[i].id;
                var newOption = new Option(text,id,false,false);
                $('.js-example-basic-multiple').append(newOption).trigger('change');

            
            }
          }
          else if (buttonstep == 1 && o == "Office"){
            console.log("office");
             var data = {
                  "programs": [
                {
                  id: 1,
                  text: 'photoshop'
                 },
                {
                    id:2,
                    text:'blender'
                }
                      ],
              }
            $('.js-example-basic-multiple').empty().trigger('change');
            for(var i = 0; i < data.programs.length; i++) {
                var text = data.programs[i].text;
                var id = data.programs[i].id;
                var newOption = new Option(text,id,false,false);
                $('.js-example-basic-multiple').append(newOption).trigger('change');

            
            }
            
          }


}

</script>
</head>
<body>
<div id="out">
    <select class="js-example-basic-multiple" name="games[]" multiple="multiple" style="width:300px">
        <option value="Office">Office</option>
        <option value="Gaming">Gaming</option>
    </select>
    <button onclick="buttonclick()">click</button>
</div>
<div id="msg">
</div>
<div id="answer"></div>

</body>
</html>

My problem now is, that pengine should show “Gaming oder Office” at the beginning and should wait for the response. But for know it just shows it, after i already made an input. It worked before i used that conditional stuff " (Type = ‘Gaming’->…; Type=‘Office’ → …)". Is there anything wrong with my prolog code or what is the problem? Trying to solve this now for like 5 hours and cant fix it…

Hope you guys can help me.

One suggestion is to simplify the conditional statement under go to see if your problem is there. Maybe just:

go:-
pengine_input("Gaming oder Office",Type),
(Type = 'Gaming'-> pengine_output('Says gaming'); pengine_output('Says something else')).

Good luck!

This works well, but if I replace the first output with a new input, it doesn’t work as expected.
So this doesn’t work:

go:-
   pengine_input("Gaming oder Office",Type),
   (Type = 'Gaming'-> pengine_input("Gaming also, welche spiele?", Game1); 
   Type = 'Office' ->
   pengine_output('Says something else')).

but I don’t get why?

Friendly reminder

=/2 is unification.

==/2 is comparison.

->/2 is usually used with comparison and not unification.

I don’t know if that is the cause of your problem but worth remembering and checking. :slightly_smiling_face:

thanks, but even with ==/2 its not working as expected.


I get this error in the console. Could this be related to my problem? And how to fix this? :slight_smile:

Who knows … If I go to swish and run ?- write(hello). after enabling the browser debugging tools with network monitoring, I see a pull request with as answer:

HTTP/2 200 OK
server: nginx/1.14.0 (Ubuntu)
date: Tue, 18 Jan 2022 15:58:53 GMT
content-type: application/json; charset=UTF-8
content-length: 214
access-control-allow-origin: *
cache-control: no-cache, no-store, must-revalidate
pragma: no-cache
expires: 0
X-Firefox-Spdy: h2

That looks fine to me.

I tend to write if-then-else patterns in Prolog by splitting different conditions across different clauses because i feel that this is easier to read (not sure if this is the best way though), e.g.

go:- 
    writeln('What food do you like? choose italian, german or mexican.'), 
    read(Input), 
    condition(Input).

condition('italian'):- 
    writeln('Are you vegetarian? yes/no'),
    read(Input),
    conditionVeg(Input).
condition('german'):- writeln('Knödel it is!').
condition('mexican'):- writeln('Tacos it is!').

conditionVeg('yes'):- writeln('Pizza Margerita it is!').
conditionVeg('no'):- writeln('Vitello Tonnato it is!').

Maybe it helps to try something similar :slight_smile:

Ok i found a solution by myself now :star_struck: .
I changed the pengine object to this:

var pengine = new Pengine({server: “https://swish.swi-prolog.org/pengine”,
ask:‘go’,
format:‘json-html’,
application:‘swish’,
onprompt:handlePrompt,
onoutput:handleOutput
});
So i added the format option, now the CORS error is gone and it works as expected. Now the prolog messages will also be printed but thats fine, i will just hide them with css or remove them from the DOM with JS.

1 Like

Thanks, nice solution for the CORS problem!
That bugged me and I had no time to solve.