Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %Требуется SWI-Prolog. Проверено на версии 6.4.1.
- %Написал proud_anon с linux.org.ru
- %См. https://www.linux.org.ru/forum/linux-org-ru/9627248?cid=9689847
- %ТИПА ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС
- %readvotes(+FilePath): прочитать vote.txt, assert'нуть voteopt/2 и vote/1
- readvotes(FilePath) :- readfile_votes(FilePath).
- %vote(-ListOfChosenOptions): readvotes добавит в базу результат каждый голос в виде факта vote(СПИСОК_ID_ВЫБРАННЫХ_ВАРИАНТОВ)
- :- dynamic vote/1.
- %show_options: вывести список всех опций
- show_all_options :-
- get_total_count(TotalCount),
- get_total_count_votes(TCV),
- write('ФОРМАТ: Вариант [ID варианта]: число выбравших (процент от общего числа голосовавших)'), nl, nl,
- rec_show_option(1), nl,
- write('Всего проголосовавших: '), write(TotalCount), nl,
- write('Всего голосов: '), write(TCV).
- %Вспомогательный предикат
- rec_show_option(OptionID) :-
- show_option(OptionID) -> nl, ONext is OptionID + 1, rec_show_option(ONext) ; true.
- %show_option(+OptionID): вывести информацию о варианте по его числовому ID
- show_option(OptionID) :-
- get_vote_representation(OptionID, OptionAtom, NumVotes),
- get_total_count(TC),
- gpc(NumVotes, TC, Percent),
- format('~a [~d]: ~d (~2f%)', [OptionAtom, OptionID, NumVotes, Percent]).
- %explain_vote(+ChosenOptions, -Atoms): список числовых ID выбранных вариантов превратить в список человеческих названий
- explain_vote(ChosenOptions, Atoms) :-
- maplist(voteopt, ChosenOptions, Atoms).
- %count(+Options, -Count): посчитать количество голосов с ровно такой комбинацией выборов
- count(Options, Count) :-
- findall(X, (vote(X), X = Options), List),
- length(List, Count).
- %find(+Options, -Vote): найти голос, где есть по крайней мере выбранные варианты
- find(Options, Vote) :-
- (is_list(Options) -> Opt = Options ; Opt = [Options]),
- vote(Vote),
- subset(Opt, Vote).
- %find_count(+Options, -NumVotes): посчитать количество голосов, где есть по крайней мере выбранные варианты
- find_count(Options, NumVotes) :-
- findall(X, find(Options, X), ListOfVotes),
- length(ListOfVotes, NumVotes).
- %correlation(+OptionID): вывести данные о корреляции указанного варианта с другими
- correlation(OptionID) :-
- get_vote_representation(OptionID, OptionAtom, NumVotes),
- get_total_count(TC),
- gpc(NumVotes, TC, P),
- format('Всего выбравших "~a" [~d]: ~d (~2f%)', [OptionAtom, OptionID, NumVotes, P]),
- nl,
- write('Из них выбрали также:'), nl,
- rec_xcount(OptionID, NumVotes, 1).
- %Вспомогательный предикат
- rec_xcount(_, _, CorelOpt) :- \+ voteopt(CorelOpt, _), !.
- rec_xcount(MainOpt, ChoosersNum, CorelOpt) :-
- voteopt(CorelOpt, OptAtom),
- get_total_count(TC),
- (MainOpt = CorelOpt ->
- (count([MainOpt], Num),
- gpc(Num, TC, PAll),
- gpc(Num, ChoosersNum, PChoosers),
- format('* Никаких других вариантов: ~d\n\t~2f% выбравших исходный вариант\n\t~2f% всех голосовавших', [Num, PChoosers, PAll]))
- ; (find_count([MainOpt, CorelOpt], Num),
- find_count(CorelOpt, NumCC),
- gpc(Num, TC, PAll),
- gpc(Num, ChoosersNum, PChoosers),
- gpc(Num, NumCC, PCC),
- format('* "~a" [~d]: ~d\n\t~2f% выбравших исходный вариант\n\t~2f% всех выбравших этот вариант\n\t~2f% всех голосовавших', [OptAtom, CorelOpt, Num, PChoosers, PCC, PAll]))
- ),
- nl,
- NextOpt is CorelOpt + 1, !,
- rec_xcount(MainOpt, ChoosersNum, NextOpt).
- %Во всех более сложных случаях придётся непосредственно вызывать vote(-СПИСОК_ВЫБРАННЫХ_ВАРИАНТОВ)
- %и с ним работать
- %ГРАММАТИКА ДЛЯ vote.txt
- :- dynamic voteopt/2.
- voteopt(_ID, _Atom) :- fail. %ID = число, Atom = расшифровка
- whitespace --> (" " ; "\t"), !, optwhitespace.
- optwhitespace --> whitespace ; [].
- strvalue(Value) --> "\\\\", !, strvalue(V2), append("\\", V2, Value).
- strvalue(Value) --> "\\\\\"", !, strvalue(V2), append("\\\"", V2, Value).
- strvalue([]) --> "\"", !.
- strvalue([C|Rem]) --> [C], strvalue(Rem).
- fullstr(Value) --> "\"", strvalue(Value). %strvalue заканчивается на кавычке
- strarray([Value|OtherVals]) --> fullstr(Value), optwhitespace, ("," , optwhitespace, strarray(OtherVals) ; [], {OtherVals = []}).
- %Используется предположение, что отправить результат голосования без единого варианта невозможно
- linevote(Options) --> "{", optwhitespace, strarray(Options), optwhitespace, "}".
- registeropts([]) :- !.
- registeropts([AllChoices|Rem]) :-
- (member(C, AllChoices), atom_codes(CA, C),
- (voteopt(_, CA) -> true ; (voteopt(LastNum ,_) -> true ; LastNum = 0), NewNum is LastNum + 1, asserta(voteopt(NewNum, CA))),
- fail) ; !,
- registeropts(Rem).
- registervotes([]) :- !.
- registervotes([Vote|Rem]) :-
- (maplist(atom_codes, VoteAtoms, Vote),
- maplist(voteopt, VoteNums, VoteAtoms) -> true ; throw('Internal error: unregistered options or atom_codes failed')),
- assertz(vote(VoteNums)), !, registervotes(Rem).
- lines(Opts) --> optwhitespace, linevote(O1), optwhitespace, "\n", (lines(O2) ; [], {O2 = []}), {append([O1], O2, Opts)}.
- lines([], "\n", []). %На случай пустого перевода строки в конце файла.
- start --> (lines(Opts) ; throw('Failed to parse the file')), !, {registeropts(Opts), registervotes(Opts)}.
- %ДРУГИЕ ПРЕДИКАТЫ "ВНУТРЕННЕГО ПОЛЬЗОВАНИЯ"
- readfile_votes(FilePath) :- phrase_from_file(start, FilePath).
- get_vote_representation(OptionID, OptionAtom, NumVotes) :-
- voteopt(OptionID, OptionAtom),
- (findall(X, (vote(X), memberchk(OptionID, X)), ListVotes) -> length(ListVotes, NumVotes) ; NumVotes = 0), !.
- get_total_count(Count) :-
- findall(X, vote(X), ListVotes),
- length(ListVotes, Count).
- gpc(Count, TotalCount, Percent) :-
- Percent is (Count rdiv TotalCount) * 100.
- get_total_count_votes(Count) :- %Это то, что на ЛОРе называется "Всего голосов"
- findall(X, vote(X), ListVotes),
- maplist(length, ListVotes, ListLens),
- sum_list(ListLens, Count).
Advertisement
Add Comment
Please, Sign In to add comment