سؤال

أنا أعمل حاليًا على برنامج Prolog متكرر لربط المسارات معًا لإنشاء ملف أساسي نظام تحديد المواقع في منطقة برمنغهام.في الوقت الحالي يمكنني الحصول على الإخراج على النحو التالي:

مدخل

routeplan(selly_oak, aston, P).

انتاج |

P = [selly_oak, edgbaston, ... , aston]

ما أود فعله هو أن يوفر برنامجي نوعًا ما من الواجهة، لذلك إذا كنت سأكتب شيئًا على غرار:

Route from selly_oak to aston

من شأنه أن يوفر لي:

Go from selly_oak to edgbaston
Go from edgbaston to ...
Finally, Go from ... to aston.

Prolog هي لغة قوية لذا أفترض أن هذا ممكن بسهولة، ولكن يبدو أن العديد من الكتب التي قمت بإخراجها تتخطى هذا الجزء.بقدر ما أعلم، لا بد لي من استخدام شيء ما على غرار write() و read() على الرغم من أن التفاصيل غير معروفة بالنسبة لي.

هل يمكن لأي شخص هنا أن يكون مبتدئًا في Prolog مع بعض الأمثلة الأساسية أو الروابط لمزيد من المعلومات؟

يحرر: تبدو الكثير من هذه الإجابات معقدة للغاية، حيث يجب أن يتكون الحل من 5 إلى 10 أسطر فقط من التعليمات البرمجية.لا تمثل القراءة في القيمة مشكلة حيث يمكنني القيام بشيء على غرار:

find:- 
    write('Where are you? '), 
    read(X), 
    nl, write('Where do you want to go? '),
    read(Y), 
    loopForRoute(X,Y).

أفضّل أن تتم كتابة الإخراج باستخدام write() بحيث يمكن استخدام سطر جديد (nl)، بحيث يتم عرضه مثل الإخراج أعلاه.

إذا كانت هذه مدخلاتي، فكيف يمكنني بعد ذلك ترتيب مخطط المسار العلوي () للعمل مع هذه المدخلات؟وأيضًا، إذا أردت إضافة الخطوط لهذه المحطات كمعلمة إضافية، فكيف سيتم تنفيذ ذلك؟يتم تعريف جميع الروابط في بداية الملف كما يلي:

rlinks(selly_oak, edgbaston, uob_line).
rlinks(edgbaston, bham_new_street, main_line).

لذلك، مع هذه المعلومات، سيكون من الجيد أن تكون قادرًا على قراءة السطر بهذه الطريقة.

Go from selly_oak to edgbaston using the uob_line
Go from edgbaston to ... using the ...
Finally, go from ... to aston using the astuni_line
هل كانت مفيدة؟

المحلول

بالنسبة لهذا النوع من الأشياء، عادةً ما أقوم بإنشاء مسندات الصدفة.لذلك في حالتك ...

guided:-
    print('Enter your start point'),nl,
    read(Start),
    print('Enter your destination'),nl,
    read(Dest),
    routeplan(Start, Dest, Route),
    print_route(Route).

ويمكن أن يكون print_route/1 شيئًا متكررًا مثل هذا:

print_route([]).

print_route([[A,B,Method]|Tail]):-
    print_route(Tail),
    print('Go from '), print(A),
    print(' to '), print(B),
    print(' by '), print(Method), nl.

لقد افترضت أن المتغير الثالث لمسند Routeplan/3 هو قائمة القوائم.كما أنه مبني بإضافة إلى الذيل.إذا لم يكن الأمر كذلك، فيجب أن يكون من السهل التكيف معه إلى حد ما.اسأل في التعليقات.

نصائح أخرى

والكتاب الذي يناقش مثل هذه الأمور بالتفصيل هو معالجة اللغات الطبيعية لمبرمجي Prologبقلم مايكل أ.كوفينجتون.

بشكل عام، ما عليك القيام به هو

  1. رمزية الإدخال
  2. تحليل الرموز المميزة (على سبيل المثال.مع DCG) للحصول على المدخلات routeplan/3
  3. يتصل routeplan/3
  4. توليد بعض اللغة الإنجليزية على أساس إخراج routeplan/3

شيء من هذا القبيل (يعمل في SWI-Prolog):

% Usage example:
%
% ?- query_to_response('Route from selly_oak to aston', Response).
%
% Response = 'go from selly_oak to edgbaston then go from edgbaston
%         to aston then stop .'
%
query_to_response(Query, Response) :-
    concat_atom(QueryTokens, ' ', Query), % simple tokenizer
    query(path(From, To), QueryTokens, []),
    routeplan(From, To, Plan),
    response(Plan, EnglishTokens, []),
    concat_atom(EnglishTokens, ' ', Response).

% Query parser
query(path(From, To)) --> ['Route'], from(From), to(To).
from(From) --> [from], [From], { placename(From) }.
to(To) --> [to], [To], { placename(To) }.

% Response generator
response([_]) --> [stop], [.].
response([From, To | Tail]) -->
    goto(path(From, To)), [then], response([To | Tail]).
goto(path(From, To)) --> [go], from(From), to(To).

% Placenames
placename(selly_oak).
placename(aston).
placename(edgbaston).

% Mock routeplan/3
routeplan(selly_oak, aston, [selly_oak, edgbaston, aston]).

حسنًا، إذا كنت أفهمك بشكل صحيح، فأنت تريد فقط تنسيق القائمة بشكل جيد للطباعة، أليس كذلك؟

في SWI-Prolog يعمل هذا:

output_string([A,B],StrIn,StrOut) :-
 concat_atom([StrIn, 'Finally, Go from ', A, ' to ', B, '.'],StrOut),
 write(StrOut).

output_string([A,B|Rest],StrIn,StrOut) :-
 concat_atom([StrIn,'Go from ', A, ' to ', B, '.\n'],StrAB),
 output_string([B|Rest],StrAB,StrOut).

ثم اتصل مع

output_string(P,'',_).

ربما لا تكون فعالة جدًا، لكنها تؤدي المهمة.:)

فيما يلي بعض المسندات لقراءة الأسطر من ملف/دفق إلى سلسلة Prolog:

%%% get_line(S, CL): CL is the string read up to the end of the line from S.
%%% If reading past end of file, returns 'end_of_file' in CL first, raises
%%% an exception second time.
%%% :- pred get_string(+stream, -list(int)).
get_line(S, CL) :-
    peek_code(S, C),
    (   C = -1
    ->  get_code(S, _),
        CL = end_of_file
    ;   get_line(S, C, CL)).

get_line(_, -1, CL) :- !, CL = [].  % leave end of file mark on stream
get_line(S, 0'\n, CL) :- !,
    get_code(S, _),
    CL = [].
get_line(S, C, [C|CL]) :-
    get_code(S, _),
    peek_code(S, NC),
    get_line(S, NC, CL).

%% read_lines(L): reads lines from current input to L.  L is a list of list
%% of character codes, newline characters are not included.
%% :- pred read_lines(-list(list(char))).
read_lines(L) :-
    current_input(In),
    get_line(In, L0),
    read_lines(In, L0, L).

%% read_lines(F, L): reads lines from F to L.  L is a list of list of character
%% codes, newline characters are not included.
%% :- pred read_lines(+atom, -list(list(char))).
read_lines(F, L) :-
    fail_on_error(open(F, read, S)),
    call_cleanup((get_line(S, L0),
              read_lines(S, L0, L)),
             close(S)).

read_lines(_, end_of_file, L) :- !, L = [].
read_lines(S, H, [H|T]) :-
    get_line(S, NH),
    read_lines(S, NH, T).

ثم، نلقي نظرة على دي سي جيللحصول على معلومات حول كيفية تحليل سلسلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top