Why is Prolog unifying a free variable to another free?Two stars in a Prolog listWhy is this prolog query both true and false?How do return both a variable result and a true/false in Prolog?SWI-Prolog - show long listProlog anonymous variableHow to use variables in Prolog query shell?Prolog VariableProlog nth1 anonymous variablesWhy does Prolog predicate member/2 print an extra whitespace in output?Why it doesn't unify? prolog

Did I make a mistake by ccing email to boss to others?

Are Captain Marvel's powers affected by Thanos breaking the Tesseract and claiming the stone?

The Digit Triangles

Showing mass murder in a kid's book

Given this phrasing in the lease, when should I pay my rent?

I'm just a whisper. Who am I?

Air travel with refrigerated insulin

Overlapping circles covering polygon

How do I prevent inappropriate ads from appearing in my game?

What the heck is gets(stdin) on site coderbyte?

How to I force windows to use a specific version of SQLCMD?

Why didn’t Eve recognize the little cockroach as a living organism?

Why would five hundred and five be same as one?

Typing CO_2 easily

Is there anyway, I can have two passwords for my wi-fi

Is there a reason to prefer HFS+ over APFS for disk images in High Sierra and/or Mojave?

Deciphering cause of death?

How do you justify more code being written by following clean code practices?

Storage of electrolytic capacitors - how long?

How can I, as DM, avoid the Conga Line of Death occurring when implementing some form of flanking rule?

Do I have to take mana from my deck or hand when tapping a dual land?

Telemetry for feature health

How to test the sharpness of a knife?

Why does the Persian emissary display a string of crowned skulls?



Why is Prolog unifying a free variable to another free?


Two stars in a Prolog listWhy is this prolog query both true and false?How do return both a variable result and a true/false in Prolog?SWI-Prolog - show long listProlog anonymous variableHow to use variables in Prolog query shell?Prolog VariableProlog nth1 anonymous variablesWhy does Prolog predicate member/2 print an extra whitespace in output?Why it doesn't unify? prolog













1















maxmin([X|L], Max, Min) :-
maxmin(L, X, X, Max, Min),
!.

maxmin([], CurrentMax, CurrentMin, Max, Min) :-
Max is CurrentMax,
Min is CurrentMin,
!.
maxmin([X|L], CurrentMax, CurrentMin, Max, Min) :-
CurrentMax2 is max(X, CurrentMax),
CurrentMin2 is min(X, CurrentMin),
maxmin(L, CurrentMax2, CurrentMin2, Max, Min).


Upon performing the query ?- maxmin([2],Max,Min)., it will return Max = Min, Min = 2..



Why? I have several variation of this and none of them seems to work. How it is possible that it is assigning a free to another free? Is this some reflection stuff in Prolog I am not aware of?



Tracing does not show anything particularly interesting either. Namely, it exits from Exit: (8) maxmin([2], 2, 2) ? creep which looks perfectly fine to me. This will only happen when I have a list of 1.



I am obviously not understanding Prolog but I can't figure out for the life of me where I am wrong. Any pointers?










share|improve this question



















  • 2





    It's saying Max and Min are both bound to 2. It would be no different if it said Max = 2, Min = 2. SWI does this for some reason.

    – Daniel Lyons
    Mar 7 at 5:56











  • @Hanif Bin Ariffin Prolog makes a variable chain - the last variable will reffer to value.

    – Anton Danilov
    Mar 7 at 5:57






  • 1





    In Prolog if you have Max = Min, Min = 2 then Max is also unified to 2. That's why it is called "unification" and not "assignment".

    – Enigmativity
    Mar 7 at 9:09






  • 1





    Maybe you could explain how it does not work, as it seems to make sense. Both the maximum and minimum of a list of one will be that one value. Your cuts are pointless: maxmin/3 has only one clause, and in maxmin/5 the pattern-matching on the first parameter will discriminate. There is no reason to use is instead of = unless you are evaluating mathematical expressions.

    – Tomas By
    Mar 7 at 11:10















1















maxmin([X|L], Max, Min) :-
maxmin(L, X, X, Max, Min),
!.

maxmin([], CurrentMax, CurrentMin, Max, Min) :-
Max is CurrentMax,
Min is CurrentMin,
!.
maxmin([X|L], CurrentMax, CurrentMin, Max, Min) :-
CurrentMax2 is max(X, CurrentMax),
CurrentMin2 is min(X, CurrentMin),
maxmin(L, CurrentMax2, CurrentMin2, Max, Min).


Upon performing the query ?- maxmin([2],Max,Min)., it will return Max = Min, Min = 2..



Why? I have several variation of this and none of them seems to work. How it is possible that it is assigning a free to another free? Is this some reflection stuff in Prolog I am not aware of?



Tracing does not show anything particularly interesting either. Namely, it exits from Exit: (8) maxmin([2], 2, 2) ? creep which looks perfectly fine to me. This will only happen when I have a list of 1.



I am obviously not understanding Prolog but I can't figure out for the life of me where I am wrong. Any pointers?










share|improve this question



















  • 2





    It's saying Max and Min are both bound to 2. It would be no different if it said Max = 2, Min = 2. SWI does this for some reason.

    – Daniel Lyons
    Mar 7 at 5:56











  • @Hanif Bin Ariffin Prolog makes a variable chain - the last variable will reffer to value.

    – Anton Danilov
    Mar 7 at 5:57






  • 1





    In Prolog if you have Max = Min, Min = 2 then Max is also unified to 2. That's why it is called "unification" and not "assignment".

    – Enigmativity
    Mar 7 at 9:09






  • 1





    Maybe you could explain how it does not work, as it seems to make sense. Both the maximum and minimum of a list of one will be that one value. Your cuts are pointless: maxmin/3 has only one clause, and in maxmin/5 the pattern-matching on the first parameter will discriminate. There is no reason to use is instead of = unless you are evaluating mathematical expressions.

    – Tomas By
    Mar 7 at 11:10













1












1








1








maxmin([X|L], Max, Min) :-
maxmin(L, X, X, Max, Min),
!.

maxmin([], CurrentMax, CurrentMin, Max, Min) :-
Max is CurrentMax,
Min is CurrentMin,
!.
maxmin([X|L], CurrentMax, CurrentMin, Max, Min) :-
CurrentMax2 is max(X, CurrentMax),
CurrentMin2 is min(X, CurrentMin),
maxmin(L, CurrentMax2, CurrentMin2, Max, Min).


Upon performing the query ?- maxmin([2],Max,Min)., it will return Max = Min, Min = 2..



Why? I have several variation of this and none of them seems to work. How it is possible that it is assigning a free to another free? Is this some reflection stuff in Prolog I am not aware of?



Tracing does not show anything particularly interesting either. Namely, it exits from Exit: (8) maxmin([2], 2, 2) ? creep which looks perfectly fine to me. This will only happen when I have a list of 1.



I am obviously not understanding Prolog but I can't figure out for the life of me where I am wrong. Any pointers?










share|improve this question
















maxmin([X|L], Max, Min) :-
maxmin(L, X, X, Max, Min),
!.

maxmin([], CurrentMax, CurrentMin, Max, Min) :-
Max is CurrentMax,
Min is CurrentMin,
!.
maxmin([X|L], CurrentMax, CurrentMin, Max, Min) :-
CurrentMax2 is max(X, CurrentMax),
CurrentMin2 is min(X, CurrentMin),
maxmin(L, CurrentMax2, CurrentMin2, Max, Min).


Upon performing the query ?- maxmin([2],Max,Min)., it will return Max = Min, Min = 2..



Why? I have several variation of this and none of them seems to work. How it is possible that it is assigning a free to another free? Is this some reflection stuff in Prolog I am not aware of?



Tracing does not show anything particularly interesting either. Namely, it exits from Exit: (8) maxmin([2], 2, 2) ? creep which looks perfectly fine to me. This will only happen when I have a list of 1.



I am obviously not understanding Prolog but I can't figure out for the life of me where I am wrong. Any pointers?







prolog swi-prolog prolog-toplevel






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 7 at 9:06









repeat

16.2k443139




16.2k443139










asked Mar 7 at 2:28









Hanif Bin AriffinHanif Bin Ariffin

707




707







  • 2





    It's saying Max and Min are both bound to 2. It would be no different if it said Max = 2, Min = 2. SWI does this for some reason.

    – Daniel Lyons
    Mar 7 at 5:56











  • @Hanif Bin Ariffin Prolog makes a variable chain - the last variable will reffer to value.

    – Anton Danilov
    Mar 7 at 5:57






  • 1





    In Prolog if you have Max = Min, Min = 2 then Max is also unified to 2. That's why it is called "unification" and not "assignment".

    – Enigmativity
    Mar 7 at 9:09






  • 1





    Maybe you could explain how it does not work, as it seems to make sense. Both the maximum and minimum of a list of one will be that one value. Your cuts are pointless: maxmin/3 has only one clause, and in maxmin/5 the pattern-matching on the first parameter will discriminate. There is no reason to use is instead of = unless you are evaluating mathematical expressions.

    – Tomas By
    Mar 7 at 11:10












  • 2





    It's saying Max and Min are both bound to 2. It would be no different if it said Max = 2, Min = 2. SWI does this for some reason.

    – Daniel Lyons
    Mar 7 at 5:56











  • @Hanif Bin Ariffin Prolog makes a variable chain - the last variable will reffer to value.

    – Anton Danilov
    Mar 7 at 5:57






  • 1





    In Prolog if you have Max = Min, Min = 2 then Max is also unified to 2. That's why it is called "unification" and not "assignment".

    – Enigmativity
    Mar 7 at 9:09






  • 1





    Maybe you could explain how it does not work, as it seems to make sense. Both the maximum and minimum of a list of one will be that one value. Your cuts are pointless: maxmin/3 has only one clause, and in maxmin/5 the pattern-matching on the first parameter will discriminate. There is no reason to use is instead of = unless you are evaluating mathematical expressions.

    – Tomas By
    Mar 7 at 11:10







2




2





It's saying Max and Min are both bound to 2. It would be no different if it said Max = 2, Min = 2. SWI does this for some reason.

– Daniel Lyons
Mar 7 at 5:56





It's saying Max and Min are both bound to 2. It would be no different if it said Max = 2, Min = 2. SWI does this for some reason.

– Daniel Lyons
Mar 7 at 5:56













@Hanif Bin Ariffin Prolog makes a variable chain - the last variable will reffer to value.

– Anton Danilov
Mar 7 at 5:57





@Hanif Bin Ariffin Prolog makes a variable chain - the last variable will reffer to value.

– Anton Danilov
Mar 7 at 5:57




1




1





In Prolog if you have Max = Min, Min = 2 then Max is also unified to 2. That's why it is called "unification" and not "assignment".

– Enigmativity
Mar 7 at 9:09





In Prolog if you have Max = Min, Min = 2 then Max is also unified to 2. That's why it is called "unification" and not "assignment".

– Enigmativity
Mar 7 at 9:09




1




1





Maybe you could explain how it does not work, as it seems to make sense. Both the maximum and minimum of a list of one will be that one value. Your cuts are pointless: maxmin/3 has only one clause, and in maxmin/5 the pattern-matching on the first parameter will discriminate. There is no reason to use is instead of = unless you are evaluating mathematical expressions.

– Tomas By
Mar 7 at 11:10





Maybe you could explain how it does not work, as it seems to make sense. Both the maximum and minimum of a list of one will be that one value. Your cuts are pointless: maxmin/3 has only one clause, and in maxmin/5 the pattern-matching on the first parameter will discriminate. There is no reason to use is instead of = unless you are evaluating mathematical expressions.

– Tomas By
Mar 7 at 11:10












1 Answer
1






active

oldest

votes


















3















How it is possible that it is assigning a free to another free?




Your use of the word assigning is telling us a secret about how you think about Prolog. When you see = in Prolog, that is not assignment, but unification, see: =/2. Prolog works by unification or more specifically syntactic unification.



If Prolog can unify two free variables together, for example A and B and when one of them then becomes bound, the other is also bound at the same time because they were unified before.



While not entirely accurate, another way to think about this is as pointers.



If you start off with one pointer pointing to A and a different pointer pointing to B, which are different locations and latter find that A and B are unified, the pointers to both A and B will be adjusted to now point to the same location. However the location they point to is still an unbound location as neither A or B have a value. When either A or B are bound to a value, then they both become bound at the same time because the pointers are pointing to the same location.



Here is some test code the demonstrates the details.



test_01 :-
format('A: ~w~n',[A]),
format('B: ~w~n',[B]),
A = B,
format('A: ~w~n',[A]),
format('B: ~w~n',[B]),
A = 5,
format('A: ~w~n',[A]),
format('B: ~w~n',[B]).


Running this returns the following. I added the comments in after the fact by hand.



?- test_01.
A: _480 % Line 1
B: _486 % Line 2
A: _480 % line 3
B: _480 % line 4
A: 5 % Line 5
B: 5 % Line 6
true.


In line 1 the variable A is internally referenced as an unbound variable: _480

In line 2 the variable B is internally referenced as an unbound variable: _486

Note that _480 and _486 represents two different unbound variables.

Note that A and B are not internally referencing the same.



Next the code executes A = B



then



In line 3 the variable A is internally referenced as _480

In line 4 the variable B is internally referenced as _480



Note that now A and B are internally referencing the same: _480.



Next the code executes A = 5



In line 5 the variable A internally references _480 which is now bound with the value 5.

In line 6 the variable B internally references _480 which is now bound with the value 5.



When this happened, there were not two separate bindings, but one binding to one location, which because of unification, and thus the reference to the same location, two variables became bound to a value with one action.



So when you see B = A, A = 2. it is can mean that B and A were unified, (referencing the same location), and that the bound value in the location for B is 2, which is also the same bound value for B since A and B were unified.




However in your specific example since Max and Min were never unified it is just the particular way the SWI-Prolog displays them.



I ran a trace of your example to see exactly what your were noting.



?- leash(-all),visible(+all),trace.
true.

[trace] ?- maxmin([2],Max,Min).
Call: (8) maxmin([2], _4408, _4410)
Unify: (8) maxmin([2], _4408, _4410)
Call: (9) maxmin([], 2, 2, _4408, _4410)
Unify: (9) maxmin([], 2, 2, _4408, _4410)
Call: (10) _4408 is 2
Exit: (10) 2 is 2
Call: (10) _4410 is 2
Exit: (10) 2 is 2
Exit: (9) maxmin([], 2, 2, 2, 2)
Exit: (8) maxmin([2], 2, 2)
Max = Min, Min = 2.


It might be that SWI-Prolog is keeping a table of display values and that it notices that both Max and Min have the same value so displays them that way, but I don't want to take the time to dig into the code find the details.





Is this some reflection stuff in Prolog I am not aware of?




I would not use the word Reflection to describe it.




Some test cases for your code. I used to make sure your code was working in case you had a bug and forgot to ask about it.



:- begin_tests(maxmin_tests).

maxmin_test_case([1],1,1).
maxmin_test_case([1,2],2,1).
maxmin_test_case([2,1],2,1).
maxmin_test_case([1,2,3],3,1).
maxmin_test_case([3,2,1],3,1).
maxmin_test_case([2,3,1],3,1).
maxmin_test_case([3,1,2],3,1).

test(1,[forall(maxmin_test_case(Input,Expected_max,Expected_min))]) :-
maxmin(Input,Max,Min),
assertion( Max == Expected_max ),
assertion( Min == Expected_min ).

test(2,[fail]) :-
maxmin([],_,_).

:- end_tests(maxmin_tests).



Example run



?- run_tests.
% PL-Unit: maxmin_tests ........ done
% All 8 tests passed
true.





share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55035126%2fwhy-is-prolog-unifying-a-free-variable-to-another-free%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3















    How it is possible that it is assigning a free to another free?




    Your use of the word assigning is telling us a secret about how you think about Prolog. When you see = in Prolog, that is not assignment, but unification, see: =/2. Prolog works by unification or more specifically syntactic unification.



    If Prolog can unify two free variables together, for example A and B and when one of them then becomes bound, the other is also bound at the same time because they were unified before.



    While not entirely accurate, another way to think about this is as pointers.



    If you start off with one pointer pointing to A and a different pointer pointing to B, which are different locations and latter find that A and B are unified, the pointers to both A and B will be adjusted to now point to the same location. However the location they point to is still an unbound location as neither A or B have a value. When either A or B are bound to a value, then they both become bound at the same time because the pointers are pointing to the same location.



    Here is some test code the demonstrates the details.



    test_01 :-
    format('A: ~w~n',[A]),
    format('B: ~w~n',[B]),
    A = B,
    format('A: ~w~n',[A]),
    format('B: ~w~n',[B]),
    A = 5,
    format('A: ~w~n',[A]),
    format('B: ~w~n',[B]).


    Running this returns the following. I added the comments in after the fact by hand.



    ?- test_01.
    A: _480 % Line 1
    B: _486 % Line 2
    A: _480 % line 3
    B: _480 % line 4
    A: 5 % Line 5
    B: 5 % Line 6
    true.


    In line 1 the variable A is internally referenced as an unbound variable: _480

    In line 2 the variable B is internally referenced as an unbound variable: _486

    Note that _480 and _486 represents two different unbound variables.

    Note that A and B are not internally referencing the same.



    Next the code executes A = B



    then



    In line 3 the variable A is internally referenced as _480

    In line 4 the variable B is internally referenced as _480



    Note that now A and B are internally referencing the same: _480.



    Next the code executes A = 5



    In line 5 the variable A internally references _480 which is now bound with the value 5.

    In line 6 the variable B internally references _480 which is now bound with the value 5.



    When this happened, there were not two separate bindings, but one binding to one location, which because of unification, and thus the reference to the same location, two variables became bound to a value with one action.



    So when you see B = A, A = 2. it is can mean that B and A were unified, (referencing the same location), and that the bound value in the location for B is 2, which is also the same bound value for B since A and B were unified.




    However in your specific example since Max and Min were never unified it is just the particular way the SWI-Prolog displays them.



    I ran a trace of your example to see exactly what your were noting.



    ?- leash(-all),visible(+all),trace.
    true.

    [trace] ?- maxmin([2],Max,Min).
    Call: (8) maxmin([2], _4408, _4410)
    Unify: (8) maxmin([2], _4408, _4410)
    Call: (9) maxmin([], 2, 2, _4408, _4410)
    Unify: (9) maxmin([], 2, 2, _4408, _4410)
    Call: (10) _4408 is 2
    Exit: (10) 2 is 2
    Call: (10) _4410 is 2
    Exit: (10) 2 is 2
    Exit: (9) maxmin([], 2, 2, 2, 2)
    Exit: (8) maxmin([2], 2, 2)
    Max = Min, Min = 2.


    It might be that SWI-Prolog is keeping a table of display values and that it notices that both Max and Min have the same value so displays them that way, but I don't want to take the time to dig into the code find the details.





    Is this some reflection stuff in Prolog I am not aware of?




    I would not use the word Reflection to describe it.




    Some test cases for your code. I used to make sure your code was working in case you had a bug and forgot to ask about it.



    :- begin_tests(maxmin_tests).

    maxmin_test_case([1],1,1).
    maxmin_test_case([1,2],2,1).
    maxmin_test_case([2,1],2,1).
    maxmin_test_case([1,2,3],3,1).
    maxmin_test_case([3,2,1],3,1).
    maxmin_test_case([2,3,1],3,1).
    maxmin_test_case([3,1,2],3,1).

    test(1,[forall(maxmin_test_case(Input,Expected_max,Expected_min))]) :-
    maxmin(Input,Max,Min),
    assertion( Max == Expected_max ),
    assertion( Min == Expected_min ).

    test(2,[fail]) :-
    maxmin([],_,_).

    :- end_tests(maxmin_tests).



    Example run



    ?- run_tests.
    % PL-Unit: maxmin_tests ........ done
    % All 8 tests passed
    true.





    share|improve this answer





























      3















      How it is possible that it is assigning a free to another free?




      Your use of the word assigning is telling us a secret about how you think about Prolog. When you see = in Prolog, that is not assignment, but unification, see: =/2. Prolog works by unification or more specifically syntactic unification.



      If Prolog can unify two free variables together, for example A and B and when one of them then becomes bound, the other is also bound at the same time because they were unified before.



      While not entirely accurate, another way to think about this is as pointers.



      If you start off with one pointer pointing to A and a different pointer pointing to B, which are different locations and latter find that A and B are unified, the pointers to both A and B will be adjusted to now point to the same location. However the location they point to is still an unbound location as neither A or B have a value. When either A or B are bound to a value, then they both become bound at the same time because the pointers are pointing to the same location.



      Here is some test code the demonstrates the details.



      test_01 :-
      format('A: ~w~n',[A]),
      format('B: ~w~n',[B]),
      A = B,
      format('A: ~w~n',[A]),
      format('B: ~w~n',[B]),
      A = 5,
      format('A: ~w~n',[A]),
      format('B: ~w~n',[B]).


      Running this returns the following. I added the comments in after the fact by hand.



      ?- test_01.
      A: _480 % Line 1
      B: _486 % Line 2
      A: _480 % line 3
      B: _480 % line 4
      A: 5 % Line 5
      B: 5 % Line 6
      true.


      In line 1 the variable A is internally referenced as an unbound variable: _480

      In line 2 the variable B is internally referenced as an unbound variable: _486

      Note that _480 and _486 represents two different unbound variables.

      Note that A and B are not internally referencing the same.



      Next the code executes A = B



      then



      In line 3 the variable A is internally referenced as _480

      In line 4 the variable B is internally referenced as _480



      Note that now A and B are internally referencing the same: _480.



      Next the code executes A = 5



      In line 5 the variable A internally references _480 which is now bound with the value 5.

      In line 6 the variable B internally references _480 which is now bound with the value 5.



      When this happened, there were not two separate bindings, but one binding to one location, which because of unification, and thus the reference to the same location, two variables became bound to a value with one action.



      So when you see B = A, A = 2. it is can mean that B and A were unified, (referencing the same location), and that the bound value in the location for B is 2, which is also the same bound value for B since A and B were unified.




      However in your specific example since Max and Min were never unified it is just the particular way the SWI-Prolog displays them.



      I ran a trace of your example to see exactly what your were noting.



      ?- leash(-all),visible(+all),trace.
      true.

      [trace] ?- maxmin([2],Max,Min).
      Call: (8) maxmin([2], _4408, _4410)
      Unify: (8) maxmin([2], _4408, _4410)
      Call: (9) maxmin([], 2, 2, _4408, _4410)
      Unify: (9) maxmin([], 2, 2, _4408, _4410)
      Call: (10) _4408 is 2
      Exit: (10) 2 is 2
      Call: (10) _4410 is 2
      Exit: (10) 2 is 2
      Exit: (9) maxmin([], 2, 2, 2, 2)
      Exit: (8) maxmin([2], 2, 2)
      Max = Min, Min = 2.


      It might be that SWI-Prolog is keeping a table of display values and that it notices that both Max and Min have the same value so displays them that way, but I don't want to take the time to dig into the code find the details.





      Is this some reflection stuff in Prolog I am not aware of?




      I would not use the word Reflection to describe it.




      Some test cases for your code. I used to make sure your code was working in case you had a bug and forgot to ask about it.



      :- begin_tests(maxmin_tests).

      maxmin_test_case([1],1,1).
      maxmin_test_case([1,2],2,1).
      maxmin_test_case([2,1],2,1).
      maxmin_test_case([1,2,3],3,1).
      maxmin_test_case([3,2,1],3,1).
      maxmin_test_case([2,3,1],3,1).
      maxmin_test_case([3,1,2],3,1).

      test(1,[forall(maxmin_test_case(Input,Expected_max,Expected_min))]) :-
      maxmin(Input,Max,Min),
      assertion( Max == Expected_max ),
      assertion( Min == Expected_min ).

      test(2,[fail]) :-
      maxmin([],_,_).

      :- end_tests(maxmin_tests).



      Example run



      ?- run_tests.
      % PL-Unit: maxmin_tests ........ done
      % All 8 tests passed
      true.





      share|improve this answer



























        3












        3








        3








        How it is possible that it is assigning a free to another free?




        Your use of the word assigning is telling us a secret about how you think about Prolog. When you see = in Prolog, that is not assignment, but unification, see: =/2. Prolog works by unification or more specifically syntactic unification.



        If Prolog can unify two free variables together, for example A and B and when one of them then becomes bound, the other is also bound at the same time because they were unified before.



        While not entirely accurate, another way to think about this is as pointers.



        If you start off with one pointer pointing to A and a different pointer pointing to B, which are different locations and latter find that A and B are unified, the pointers to both A and B will be adjusted to now point to the same location. However the location they point to is still an unbound location as neither A or B have a value. When either A or B are bound to a value, then they both become bound at the same time because the pointers are pointing to the same location.



        Here is some test code the demonstrates the details.



        test_01 :-
        format('A: ~w~n',[A]),
        format('B: ~w~n',[B]),
        A = B,
        format('A: ~w~n',[A]),
        format('B: ~w~n',[B]),
        A = 5,
        format('A: ~w~n',[A]),
        format('B: ~w~n',[B]).


        Running this returns the following. I added the comments in after the fact by hand.



        ?- test_01.
        A: _480 % Line 1
        B: _486 % Line 2
        A: _480 % line 3
        B: _480 % line 4
        A: 5 % Line 5
        B: 5 % Line 6
        true.


        In line 1 the variable A is internally referenced as an unbound variable: _480

        In line 2 the variable B is internally referenced as an unbound variable: _486

        Note that _480 and _486 represents two different unbound variables.

        Note that A and B are not internally referencing the same.



        Next the code executes A = B



        then



        In line 3 the variable A is internally referenced as _480

        In line 4 the variable B is internally referenced as _480



        Note that now A and B are internally referencing the same: _480.



        Next the code executes A = 5



        In line 5 the variable A internally references _480 which is now bound with the value 5.

        In line 6 the variable B internally references _480 which is now bound with the value 5.



        When this happened, there were not two separate bindings, but one binding to one location, which because of unification, and thus the reference to the same location, two variables became bound to a value with one action.



        So when you see B = A, A = 2. it is can mean that B and A were unified, (referencing the same location), and that the bound value in the location for B is 2, which is also the same bound value for B since A and B were unified.




        However in your specific example since Max and Min were never unified it is just the particular way the SWI-Prolog displays them.



        I ran a trace of your example to see exactly what your were noting.



        ?- leash(-all),visible(+all),trace.
        true.

        [trace] ?- maxmin([2],Max,Min).
        Call: (8) maxmin([2], _4408, _4410)
        Unify: (8) maxmin([2], _4408, _4410)
        Call: (9) maxmin([], 2, 2, _4408, _4410)
        Unify: (9) maxmin([], 2, 2, _4408, _4410)
        Call: (10) _4408 is 2
        Exit: (10) 2 is 2
        Call: (10) _4410 is 2
        Exit: (10) 2 is 2
        Exit: (9) maxmin([], 2, 2, 2, 2)
        Exit: (8) maxmin([2], 2, 2)
        Max = Min, Min = 2.


        It might be that SWI-Prolog is keeping a table of display values and that it notices that both Max and Min have the same value so displays them that way, but I don't want to take the time to dig into the code find the details.





        Is this some reflection stuff in Prolog I am not aware of?




        I would not use the word Reflection to describe it.




        Some test cases for your code. I used to make sure your code was working in case you had a bug and forgot to ask about it.



        :- begin_tests(maxmin_tests).

        maxmin_test_case([1],1,1).
        maxmin_test_case([1,2],2,1).
        maxmin_test_case([2,1],2,1).
        maxmin_test_case([1,2,3],3,1).
        maxmin_test_case([3,2,1],3,1).
        maxmin_test_case([2,3,1],3,1).
        maxmin_test_case([3,1,2],3,1).

        test(1,[forall(maxmin_test_case(Input,Expected_max,Expected_min))]) :-
        maxmin(Input,Max,Min),
        assertion( Max == Expected_max ),
        assertion( Min == Expected_min ).

        test(2,[fail]) :-
        maxmin([],_,_).

        :- end_tests(maxmin_tests).



        Example run



        ?- run_tests.
        % PL-Unit: maxmin_tests ........ done
        % All 8 tests passed
        true.





        share|improve this answer
















        How it is possible that it is assigning a free to another free?




        Your use of the word assigning is telling us a secret about how you think about Prolog. When you see = in Prolog, that is not assignment, but unification, see: =/2. Prolog works by unification or more specifically syntactic unification.



        If Prolog can unify two free variables together, for example A and B and when one of them then becomes bound, the other is also bound at the same time because they were unified before.



        While not entirely accurate, another way to think about this is as pointers.



        If you start off with one pointer pointing to A and a different pointer pointing to B, which are different locations and latter find that A and B are unified, the pointers to both A and B will be adjusted to now point to the same location. However the location they point to is still an unbound location as neither A or B have a value. When either A or B are bound to a value, then they both become bound at the same time because the pointers are pointing to the same location.



        Here is some test code the demonstrates the details.



        test_01 :-
        format('A: ~w~n',[A]),
        format('B: ~w~n',[B]),
        A = B,
        format('A: ~w~n',[A]),
        format('B: ~w~n',[B]),
        A = 5,
        format('A: ~w~n',[A]),
        format('B: ~w~n',[B]).


        Running this returns the following. I added the comments in after the fact by hand.



        ?- test_01.
        A: _480 % Line 1
        B: _486 % Line 2
        A: _480 % line 3
        B: _480 % line 4
        A: 5 % Line 5
        B: 5 % Line 6
        true.


        In line 1 the variable A is internally referenced as an unbound variable: _480

        In line 2 the variable B is internally referenced as an unbound variable: _486

        Note that _480 and _486 represents two different unbound variables.

        Note that A and B are not internally referencing the same.



        Next the code executes A = B



        then



        In line 3 the variable A is internally referenced as _480

        In line 4 the variable B is internally referenced as _480



        Note that now A and B are internally referencing the same: _480.



        Next the code executes A = 5



        In line 5 the variable A internally references _480 which is now bound with the value 5.

        In line 6 the variable B internally references _480 which is now bound with the value 5.



        When this happened, there were not two separate bindings, but one binding to one location, which because of unification, and thus the reference to the same location, two variables became bound to a value with one action.



        So when you see B = A, A = 2. it is can mean that B and A were unified, (referencing the same location), and that the bound value in the location for B is 2, which is also the same bound value for B since A and B were unified.




        However in your specific example since Max and Min were never unified it is just the particular way the SWI-Prolog displays them.



        I ran a trace of your example to see exactly what your were noting.



        ?- leash(-all),visible(+all),trace.
        true.

        [trace] ?- maxmin([2],Max,Min).
        Call: (8) maxmin([2], _4408, _4410)
        Unify: (8) maxmin([2], _4408, _4410)
        Call: (9) maxmin([], 2, 2, _4408, _4410)
        Unify: (9) maxmin([], 2, 2, _4408, _4410)
        Call: (10) _4408 is 2
        Exit: (10) 2 is 2
        Call: (10) _4410 is 2
        Exit: (10) 2 is 2
        Exit: (9) maxmin([], 2, 2, 2, 2)
        Exit: (8) maxmin([2], 2, 2)
        Max = Min, Min = 2.


        It might be that SWI-Prolog is keeping a table of display values and that it notices that both Max and Min have the same value so displays them that way, but I don't want to take the time to dig into the code find the details.





        Is this some reflection stuff in Prolog I am not aware of?




        I would not use the word Reflection to describe it.




        Some test cases for your code. I used to make sure your code was working in case you had a bug and forgot to ask about it.



        :- begin_tests(maxmin_tests).

        maxmin_test_case([1],1,1).
        maxmin_test_case([1,2],2,1).
        maxmin_test_case([2,1],2,1).
        maxmin_test_case([1,2,3],3,1).
        maxmin_test_case([3,2,1],3,1).
        maxmin_test_case([2,3,1],3,1).
        maxmin_test_case([3,1,2],3,1).

        test(1,[forall(maxmin_test_case(Input,Expected_max,Expected_min))]) :-
        maxmin(Input,Max,Min),
        assertion( Max == Expected_max ),
        assertion( Min == Expected_min ).

        test(2,[fail]) :-
        maxmin([],_,_).

        :- end_tests(maxmin_tests).



        Example run



        ?- run_tests.
        % PL-Unit: maxmin_tests ........ done
        % All 8 tests passed
        true.






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 9 at 10:28

























        answered Mar 7 at 10:46









        Guy CoderGuy Coder

        16.1k44287




        16.1k44287





























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55035126%2fwhy-is-prolog-unifying-a-free-variable-to-another-free%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            1928 у кіно

            Захаров Федір Захарович

            Ель Греко