forked from rvirding/erlog
-
Notifications
You must be signed in to change notification settings - Fork 0
/
erlang.pl
48 lines (43 loc) · 1.35 KB
/
erlang.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
% -*- mode: prolog -*-
% erlog standard lib, code for working with erlang
%
% Copyright 2014 Zachary Kessin
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Code for handling erlang records
%
% erlog:prove(State, {record, RecordName, record_info(fields,RecordName)})
% will define erlog predicates to access that record by field name
% and to modify them
%
% person(Field, Record, Value).
% person(Field, Record, NewValue, NewRecord).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
record(_,[]):- !.
record(RecordName,Fields) :-
get_record(RecordName, Fields, 1),
set_record(RecordName, Fields, 1).
swap_place(New,[_Head|Tail],0,Acc) :-
Acc = [New|Tail].
swap_place(New,[Head|Tail],N,Acc) :-
Next is N - 1,
Acc = [Head|R],
swap_place(New, Tail, Next, R).
set_record(_, [], _) :- !.
set_record(RecordName, [Field|Rest], Place) :-
SetRule =.. [RecordName, Field, Record, NewValue, NData],
N is Place + 1,
set_record(RecordName, Rest, N),
asserta((SetRule :-
Record =.. Data,
Pivot is N - 1,
swap_place(NewValue,Data, Pivot,NewRecord),
NData =.. NewRecord
)).
get_record(_, [], _) :-!.
get_record(RecordName, [Field|Rest], Place) :-
GetRule =.. [RecordName, Field, Record, Value],
asserta((GetRule :- arg(Place, Record, Value))),
N is Place + 1,
get_record(RecordName, Rest, N).