Max out of values defined by prolog clauses

前端 未结 5 882
名媛妹妹
名媛妹妹 2021-01-01 07:41

I know how to iterate over lists in Prolog to find the maximum, but what if each thing is a separate clause? For example if I had a bunch of felines and their ages, how woul

5条回答
  •  独厮守ぢ
    2021-01-01 08:31

    Here is a solution that loops through all the solutions, always recording the solution that is better than the previous best. In the end, the best solution is returned.

    The recording is done using assert/1, you could also use a non-backtrackable global variable if your Prolog provides that (SWI-Prolog does).

    The benefit of this approach is that is considers each solution only once, i.e. complexity O(n). So, even though it looks uglier than starblue's solution, it should run better.

    % Data
    cat(sassy, 5).
    cat(misty, 3).
    cat(miisu, 10).
    cat(princess, 2).
    
    % Interface
    oldest_cat(Name) :-
        loop_through_cats,
        fetch_oldest_cat(Name).
    
    loop_through_cats :-
        cat(Name, Age),
        record_cat_age(Name, Age),
        fail ; true.
    
    
    :- dynamic current_oldest_cat/2.
    
    record_cat_age(Name, Age) :-
        current_oldest_cat(_, CAge),
        !,
        Age > CAge,
        retract(current_oldest_cat(_, _)),
        assert(current_oldest_cat(Name, Age)).
    
    record_cat_age(Name, Age) :-
        assert(current_oldest_cat(Name, Age)).
    
    
    fetch_oldest_cat(Name) :-
        retract(current_oldest_cat(Name, _Age)).
    

    Usage example:

    ?- oldest_cat(Name).
    
    Name = miisu
    

    Miisu is a typical Estonian cat name. ;)

提交回复
热议问题