Skip to content

Commit fe8cb91

Browse files
mishina-harutoMishinaHarutoteituesdayjz
authored
Feature/qlmntal (#359)
* make public * refactor * fix cardpop * fix cardpush * change instruction name * update * update * add eqmaps * remove hh * Add .iltest for qlmntal test * Fix include guard * Merge branch 'develop' into feature/qlmntal --------- Co-authored-by: MishinaHaruto <mishina8610@akane.waseda.jp> Co-authored-by: tei <tei@ueda.info.waseda.ac.jp> Co-authored-by: Kayo Tei <moka010302@gmail.com> Co-authored-by: Kayo Tei <82920808+tuesdayjz@users.noreply.github.com>
1 parent d929581 commit fe8cb91

32 files changed

Lines changed: 2853 additions & 84 deletions

src/element/instruction.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,15 @@ const std::map<LmnInstruction, InstrSpec> instr_spec = {
284284
{INSTR_MERGESET, {"mergeset", {InstrVar, InstrVar}}},
285285
{INSTR_FREESET, {"freeset", {InstrVar}}},
286286

287+
/* QLMNtal */
288+
{INSTR_PUSHMAP, {"pushmap", {InstrVar, InstrVarList}}},
289+
{INSTR_PICKMAPS, {"pickmaps", {InstrVar, InstrVar, InstrVar}}},
290+
{INSTR_POPMAP, {"popmap", {InstrVar}}},
291+
{INSTR_MAPNEQATOM, {"mapneqatom", {InstrVar, InstrVarList}}},
292+
{INSTR_MAPNEQMEM, {"mapneqmem", {InstrVar, InstrVarList}}},
293+
{INSTR_ANYATOM, {"anyatom", {InstrVar, InstrVar}}},
294+
{INSTR_EQMAPS, {"eqmaps", {InstrVar, InstrVar}}},
295+
287296
/* etc */
288297
{INSTR_CELLDUMP, {"celldump", {}}}};
289298

src/element/instruction.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,15 @@ enum LmnInstruction {
273273

274274
INSTR_PRINTINSTR,
275275

276+
/* QLMNtal */
277+
INSTR_PUSHMAP,
278+
INSTR_PICKMAPS,
279+
INSTR_POPMAP,
280+
INSTR_MAPNEQATOM,
281+
INSTR_MAPNEQMEM,
282+
INSTR_ANYATOM,
283+
INSTR_EQMAPS,
284+
276285
NUM_INSTRS // this must be the last
277286
};
278287

src/vm/atom.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ enum LmnLinkAttribute {
126126
LMN_ATTR_FLAG | 0x04U, /**< @deprecated constant string literal */
127127
LMN_CONST_DBL_ATTR =
128128
LMN_ATTR_FLAG | 0x05U, /**< @deprecated constant double literal */
129-
LMN_HL_ATTR = LMN_ATTR_FLAG | 0x0aU /**< exclamation atom */
129+
LMN_HL_ATTR = LMN_ATTR_FLAG | 0x0aU, /**< exclamation atom */
130+
LMN_CARD_ATTR = LMN_ATTR_FLAG | 0x0bU /**< cardinality */ /* QLMNtal */
130131
};
131132

132133
#include "element/element.h"

src/vm/cardinality.hpp

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
/* QLMNtal */
2+
#ifndef CARDINALITY_HPP
3+
#define CARDINALITY_HPP
4+
5+
#define LMN_ATTR_IS_CARD(ATTR) ((ATTR) == LMN_CARD_ATTR)
6+
7+
typedef std::pair<size_t, LmnRegister> CardPair;
8+
typedef std::vector<CardPair> CardMap;
9+
typedef std::vector<CardMap> CardQueue;
10+
11+
struct LmnCard {
12+
CardQueue queue;
13+
std::vector<LmnRegister> included_list;
14+
int pop_index;
15+
16+
public:
17+
LmnCard(CardQueue queue) :
18+
queue(queue),
19+
included_list(std::vector<LmnRegister>()),
20+
pop_index(0) {};
21+
22+
CardQueue get_queue() {
23+
return queue;
24+
}
25+
26+
void reset_queue() {
27+
queue = CardQueue();
28+
included_list = std::vector<LmnRegister>();
29+
pop_index = 0;
30+
}
31+
32+
void push_map(CardMap map) {
33+
queue.push_back(map);
34+
}
35+
36+
CardMap pop_map() {
37+
CardMap map = queue[pop_index];
38+
pop_index++;
39+
return map;
40+
}
41+
42+
std::vector<LmnRegister> get_included_list() {
43+
return included_list;
44+
}
45+
46+
void concat_included_list(std::vector<LmnRegister> included) {
47+
included_list.insert(included_list.end(), included.begin(), included.end());
48+
}
49+
50+
int get_pop_index() {
51+
return pop_index;
52+
}
53+
54+
void set_pop_index(int i) {
55+
pop_index = i;
56+
}
57+
58+
std::vector<LmnRegister> calc_picked_maps_regs(size_t max) {
59+
LmnCard* card;
60+
card = new LmnCard(CardQueue());
61+
auto picked_maps_regs = std::vector<LmnRegister>{{(LmnWord)card, LMN_CARD_ATTR, TT_OTHER}};
62+
for (CardMap map: queue) {
63+
auto map_included_list = std::vector<LmnRegister>();
64+
for (CardPair pair: map) {
65+
if (pair.second.register_tt() == TT_ATOM || pair.second.register_tt() == TT_MEM) {
66+
map_included_list.push_back(pair.second);
67+
} else if (LMN_ATTR_IS_CARD(pair.second.register_at())) {
68+
std::vector<LmnRegister> queue_reg_included_list = ((LmnCard*)(pair.second.register_wt()))->get_included_list();
69+
map_included_list.insert(map_included_list.end(), queue_reg_included_list.begin(), queue_reg_included_list.end());
70+
}
71+
}
72+
auto new_picked_maps_regs = std::vector<LmnRegister>();
73+
for (LmnRegister reg: picked_maps_regs) {
74+
new_picked_maps_regs.push_back(reg);
75+
if (max > 0 && ((LmnCard*)(reg.register_wt()))->get_queue().size() < max) {
76+
std::vector<LmnRegister> queue_included_list = ((LmnCard*)(reg.register_wt()))->get_included_list();
77+
BOOL overlap = FALSE;
78+
for (LmnRegister queue_included: queue_included_list) {
79+
for (LmnRegister map_included: map_included_list) {
80+
if (queue_included.register_tt() == TT_ATOM && map_included.register_tt() == TT_ATOM) {
81+
if (queue_included.register_wt() == map_included.register_wt()){
82+
overlap = TRUE;
83+
}
84+
} else if (queue_included.register_tt() == TT_MEM && map_included.register_tt() == TT_MEM) {
85+
if (queue_included.register_wt() == map_included.register_wt()){
86+
overlap = TRUE;
87+
}
88+
}
89+
if (overlap == TRUE) {
90+
break;
91+
}
92+
}
93+
if (overlap == TRUE) {
94+
break;
95+
}
96+
}
97+
if (!overlap) {
98+
card = new LmnCard(((LmnCard*)(reg.register_wt()))->get_queue());
99+
card->concat_included_list(queue_included_list);
100+
card->push_map(map);
101+
card->concat_included_list(map_included_list);
102+
new_picked_maps_regs.push_back({(LmnWord)card, LMN_CARD_ATTR, TT_OTHER});
103+
}
104+
}
105+
}
106+
picked_maps_regs = new_picked_maps_regs;
107+
}
108+
return picked_maps_regs;
109+
}
110+
};
111+
112+
typedef LmnCard* LmnCardRef;
113+
114+
BOOL mapneqatom(size_t atom1, std::vector<size_t> atom2list, LmnReactCxt *rc, LmnRegister queue_reg){
115+
CardQueue queue = ((LmnCardRef)(queue_reg.register_wt()))->get_queue();
116+
if (atom2list.size() == 1) {
117+
for (CardMap map: queue) {
118+
for (CardPair pair: map) {
119+
if (atom2list[0] == pair.first) {
120+
if (!(LMN_ATTR_IS_DATA(rc->at(atom1)) || LMN_ATTR_IS_DATA(pair.second.register_at()) ||
121+
LMN_SATOM(rc->wt(atom1)) != LMN_SATOM(pair.second.register_wt()))) {
122+
return FALSE;
123+
}
124+
}
125+
}
126+
}
127+
} else {
128+
size_t atom2list_head = atom2list[0];
129+
atom2list.erase(atom2list.begin());
130+
for (CardMap map: queue) {
131+
for (CardPair pair: map) {
132+
if (atom2list_head == pair.first) {
133+
if (!mapneqatom(atom1, atom2list, rc, pair.second)) {
134+
return FALSE;
135+
}
136+
}
137+
}
138+
}
139+
}
140+
return TRUE;
141+
}
142+
143+
BOOL mapneqmem(size_t mem1, std::vector<size_t> mem2list, LmnReactCxt *rc, LmnRegister queue_reg){
144+
CardQueue queue = ((LmnCardRef)(queue_reg.register_wt()))->get_queue();
145+
if(mem2list.size() == 1) {
146+
for (CardMap map: queue) {
147+
for (CardPair pair: map) {
148+
if(mem2list[0] == pair.first) {
149+
if (rc->wt(mem1) == pair.second.register_wt()) {
150+
return FALSE;
151+
}
152+
}
153+
}
154+
}
155+
} else {
156+
size_t mem2list_head = mem2list[0];
157+
mem2list.erase(mem2list.begin());
158+
for (CardMap map: queue) {
159+
for (CardPair pair: map) {
160+
if(mem2list_head == pair.first) {
161+
if (!mapneqmem(mem1, mem2list, rc, pair.second)) {
162+
return FALSE;
163+
}
164+
}
165+
}
166+
}
167+
}
168+
return TRUE;
169+
}
170+
171+
void slim::vm::interpreter::anyatom(LmnMembrane *mem, size_t reg){
172+
std::map<LmnFunctor, AtomListEntry *> atomlists = mem->atom_lists();
173+
auto atom_regs = std::vector<LmnRegister>();
174+
for (std::pair<LmnFunctor, AtomListEntry *> atomlist: atomlists) {
175+
auto iter = std::begin(*atomlist.second);
176+
auto end = std::end(*atomlist.second);
177+
if (iter == end || atomlist.first == 0 || atomlist.first == 1)
178+
continue;
179+
auto v = std::vector<LmnRegister>(atomlist.second->size());
180+
std::transform(iter, end, v.begin(), [](LmnSymbolAtomRef atom) {
181+
return LmnRegister({(LmnWord)atom, LMN_ATTR_MAKE_LINK(0), TT_ATOM});
182+
});
183+
atom_regs.insert(atom_regs.end(), v.begin(), v.end());
184+
}
185+
if(lmn_env.shuffle_atom) {
186+
std::random_shuffle(atom_regs.begin(), atom_regs.end());
187+
}
188+
this->false_driven_enumerate(reg, std::move(atom_regs));
189+
}
190+
191+
BOOL eqmaps_sub(CardMap map1, CardMap map2);
192+
193+
BOOL eqmaps(CardQueue queue1, CardQueue queue2) {
194+
if (queue1.size() != queue2.size()){
195+
return FALSE;
196+
}
197+
for (CardMap map1: queue1) {
198+
BOOL hit = FALSE;
199+
auto new_queue2 = CardQueue();
200+
for (CardMap map2: queue2) {
201+
if (!hit & eqmaps_sub(map1, map2)) {
202+
hit = TRUE;
203+
} else {
204+
new_queue2.push_back(map2);
205+
}
206+
}
207+
if (!hit) {
208+
return FALSE;
209+
}
210+
queue2 = new_queue2;
211+
}
212+
return TRUE;
213+
}
214+
215+
BOOL eqmaps_sub(CardMap map1, CardMap map2){
216+
if (map1.size() != map2.size()) {
217+
return FALSE;
218+
}
219+
for (CardPair pair1: map1) {
220+
int index1 = pair1.first;
221+
LmnRegister reg1 = pair1.second;
222+
BOOL hit = FALSE;
223+
auto new_map2 = CardMap();
224+
for (CardPair pair2: map2) {
225+
int index2 = pair2.first;
226+
LmnRegister reg2 = pair2.second;
227+
if (!hit & reg1.register_tt() == reg2.register_tt()) {
228+
if (reg1.register_tt() == TT_ATOM) {
229+
if (!(LMN_ATTR_IS_DATA(reg1.register_at()) || LMN_ATTR_IS_DATA(reg2.register_at()) ||
230+
LMN_SATOM(reg1.register_wt()) != LMN_SATOM(reg2.register_wt()))) {
231+
hit = TRUE;
232+
} else {
233+
new_map2.push_back(pair2);
234+
}
235+
} else if (pair1.second.register_tt() == TT_MEM) {
236+
if (reg1.register_wt() == reg2.register_wt()) {
237+
hit = TRUE;
238+
} else {
239+
new_map2.push_back(pair2);
240+
}
241+
} else if(LMN_ATTR_IS_CARD(pair1.second.register_at())) {
242+
CardQueue queue1 = ((LmnCardRef)(pair1.second.register_wt()))->get_queue();
243+
CardQueue queue2 = ((LmnCardRef)(pair2.second.register_wt()))->get_queue();
244+
if (eqmaps(queue1, queue2)) {
245+
hit = TRUE;
246+
} else {
247+
new_map2.push_back(pair2);
248+
}
249+
}
250+
} else {
251+
new_map2.push_back(pair2);
252+
}
253+
}
254+
if (!hit) {
255+
return FALSE;
256+
}
257+
map2 = new_map2;
258+
}
259+
return TRUE;
260+
}
261+
262+
int replace_in_card_by_tbl(ProcessTableRef p, LmnCardRef card, LmnWord *value) {
263+
CardQueue queue = card->get_queue();
264+
CardQueue new_queue = CardQueue();
265+
for (CardMap map: queue) {
266+
auto new_map = CardMap();
267+
for (CardPair pair: map) {
268+
LmnWord t;
269+
if (pair.second.register_tt() == TT_ATOM) {
270+
if (LMN_ATTR_IS_DATA(pair.second.register_at())) {
271+
new_map.push_back(CardPair{pair.first, {lmn_copy_data_atom(pair.second.register_wt(), pair.second.register_at()), pair.second.register_at(), TT_ATOM}});
272+
} else {
273+
if (proc_tbl_get_by_atom(p, (LmnSymbolAtomRef)pair.second.register_wt(), &t)) {
274+
new_map.push_back(CardPair{pair.first, {t, pair.second.register_at(), TT_ATOM}});
275+
} else {
276+
return 0;
277+
}
278+
}
279+
} else if (pair.second.register_tt() == TT_MEM) {
280+
if (proc_tbl_get_by_mem(p, (LmnMembraneRef)pair.second.register_wt(), &t)) {
281+
new_map.push_back(CardPair{pair.first, {t, pair.second.register_at(), TT_MEM}});
282+
} else {
283+
return 0;
284+
}
285+
} else if (LMN_ATTR_IS_CARD(pair.second.register_at())) {
286+
if (replace_in_card_by_tbl(p, (LmnCardRef)pair.second.register_wt(), &t)) {
287+
new_map.push_back(CardPair{pair.first, {t, pair.second.register_at(), TT_OTHER}});
288+
} else {
289+
return 0;
290+
}
291+
}
292+
}
293+
new_queue.push_back(new_map);
294+
}
295+
LmnCardRef new_card;
296+
new_card = new LmnCard(new_queue);
297+
*value = (LmnWord)new_card;
298+
return 1;
299+
}
300+
301+
#endif // CARDINALITY_HPP

src/vm/interpret/interpreter.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ struct interpreter {
8686
void findatom_through_hyperlink(LmnReactCxt *rc, LmnRule *rule,
8787
LmnRuleInstr instr, SameProcCxt *spc,
8888
LmnMembrane *mem, LmnFunctor f, size_t reg);
89+
void anyatom(LmnMembrane *mem, size_t reg); /* QLMNtal */
8990
bool run();
9091

9192
template <typename... Args> void push_stackframe(Args... args) {

0 commit comments

Comments
 (0)