1

假设我有以下 Prolog 知识库:

likes( john, mary ).
likes( john, emma ).
likes( john, ashley ).

如果我编写以下 C 代码:

#include...

term_t tv;
term_t tu;
term_t goal_term;
functor_t goal_functor;

int main( int argc, char** argv )
{
    argv[ 0 ] = "libpl.dll";
    PL_initialise( 1, argv );
    PlCall( "consult( 'likes.pl' )" );

    tv = PL_new_term_ref( );
    PL_put_atom_chars( tv, "john" );
    tu = PL_new_term_ref( );
    goal_term = PL_new_term_ref( );
    goal_functor = PL_new_functor( PL_new_atom( "likes" ), 2 );
    PL_cons_functor( goal_term, goal_functor, tv, tu );

    if ( PL_call( goal_term, NULL ) );
     {
       char* solution;
       PL_get_atom_chars( tu, &solution );
       cout << solution << endl;
     }

    PL_halt( PL_toplevel( ) ? 0 : 1 );
}

它只会调用谓词“likes”一次,从而只产生“mary”。如何让它回溯并生成和打印所有结果?

谢谢,

4

1 回答 1

0

我在下面包含了 Hanoi、Factorial 和 Backtracking 的完整程序。我希望初学者能从中受益。如果有人不确定用于连接 C++ 和 Prolog 的 VS2008 设置,我很乐意为他们提供。

#include <iostream>
#include <fstream>
#include <string>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdafx.h>
using namespace std;
#include "Windows.h"
#include "ctype.h"
#include "SWI-cpp.h"
#include "SWI-Prolog.h"
#include "SWI-Stream.h"

term_t t;
predicate_t p;

term_t tf;
term_t tx;

term_t tv;
term_t tu;
predicate_t pred;

term_t goal_term;
functor_t goal_functor;

int main( int argc, char** argv )
{
    argv[ 0 ] = "libpl.dll";
    PL_initialise( argc, argv );
    PlCall( "consult( swi( 'plwin.rc' ) )" );
    PlCall( "consult( 'myPrologFile.pl' )" );


    cout << "Enter your hanoi number: ";
    int n;
    cin >> n;
    cout << "Calculating hanoi of " << n << endl;
    PL_put_integer( t, n );
    p = PL_predicate( "hanoi", 1, NULL );
    PL_call_predicate( NULL, PL_Q_NORMAL, p, t );


    cout << "Enter your factorial number: ";
    int nf;
    cin >> nf;
    cout << "Calculating factorial of " << nf << endl;
    tf = PL_new_term_ref( );
    PL_put_integer( tf, nf );
    tx = PL_new_term_ref( );
    goal_term = PL_new_term_ref( );
    goal_functor = PL_new_functor( PL_new_atom( "factorial" ), 2 );
    PL_cons_functor( goal_term, goal_functor, tf, tx );
    int fact;
    if ( PL_call( goal_term, NULL ) )
    {
        PL_get_integer( tx, &fact );
        cout << fact << endl;
    }
    else
    {
        PL_fail;
    }


    cout << "Backtracking . . .";
    tv = PL_new_term_ref( );
    PL_put_atom_chars( tv, "john" );
    pred = PL_predicate( "likes", 2, NULL );
    tu = PL_new_term_ref( );
    qid_t qid = PL_open_query( NULL, PL_Q_NODEBUG, pred, tv );
    while ( int i = PL_next_solution( qid ) )
    {
        char* solution;
        PL_get_atom_chars( tu, &solution );
        cout << solution << endl;
    }
    PL_close_query( qid );


    PL_halt( PL_toplevel( ) ? 0 : 1 );
}

这是 myPrologFile.pl

:- use_module( library( shlib ) ).
:- use_module( library( lists ) ).


hanoi( N ):-
    move( N, left, center, right ).

move( 0, _, _, _ ):-
    !.
move( N, A, B, C ):-
    M is N-1,
    move( M, A, C, B ),
    inform( A, B ),
    move( M, C, B, A ).

inform( X, Y ):-
    write( 'move a disk from ' ),
    write( X ),
    write( ' to ' ),
    write( Y ),
    nl.


factorial( 1, 1 ):-
    !.
factorial( X, Fac ):-
    X > 1,
    Y is X - 1,
    factorial( Y, New_Fac ),
     Fac is X * New_Fac.


likes( john, mary ).
likes( john, emma ).
likes( john, ashley ).
于 2010-04-18T14:08:32.410 回答