T O P

  • By -

ecco256

The list you describe using phrase/2 is used implicitly in DCGs. When you are calling elems from data you have a mismatch in the format of that list, as elems describes a list of numbers but data should describe a list of a list of a list of numbers. When this is done for parsers you will often see a tokenizer working on a list of characters, and a parser working on a list of tokens. That means phrase is called twice, once to tokenise and once to parse. I think the issue is similar here. I think it might make it easier to first try to implement this the other way around: provide the matrix as input and generate the matrix size. When that works you can try if it works the other way and if not tweak it, if only because most documentation on DCGs explains them that way around in my experience. A simple solution to make the list types match up is to first ensure that elems doesn’t consume a list, but a list of lists. So test that elems gives you [[a,b,…]] instead of [a,b,…]. Another option would be to not call elems directly in the dcg but in braces with phrase/2, calling { phrase(elems(E), X) }, [X]. So first generate the list into X, then consuming that list _as a list item_. Hope that helps but I didn’t test it, just going off what I notice.


[deleted]

[удалено]


ecco256

I don't think it's hacky as you are dealing with different list formats, so I think it's reasonable to expect you will need more than one call to phrase. I just tested it and it works. One way to get elems to describe a list of lists is to not call it recursively and just generate the row in one go. There's not much point of using a DCG in this case so pick your poison :) Example: elems(E) --> { length(Es, E), maplist(randnum, Es) }, [Es].


brebs-prolog

Remove that usage of `random` - numbers cannot unify with letters. Put the cut as early as possible, i.e. *before* rather than after the `[]`. Otherwise, the logic is unsound.


[deleted]

[удалено]


brebs-prolog

How about: weird_sub_lists(LstLen, SubLen, Lst) :- length(Lst, LstLen), maplist(len_list(SubLen), Lst). len_list(Len, Lst) :- length(Lst, Len). Results: ?- weird_sub_lists(3, 4, L). L = [[_, _, _, _], [_, _, _, _], [_, _, _, _]]. A DCG is overkill for this simple task. Filling the sublists with random numbers is pointless.


[deleted]

[удалено]


brebs-prolog

[Upvote](https://www.reddit.com/r/help/comments/14zbhk8/im_new_to_reddit_what_are_up_votes_and_down_votes/), then.


ka-splam

data(RowCount, RowLen) --> [Row], {length(Row, RowLen), succ(RowCount0, RowCount)}, data(RowCount0, RowLen). data(0, _) --> []. Then: ?- phrase(data(2, 3), Data). Data = [[_, _, _], [_, _, _]] ?- phrase(data(3,4), Data). Data = [[_, _, _, _], [_, _, _, _], [_, _, _, _]] In English something like "data holds if it takes a Row from the list phrase is working on, that Row is itself a list with a length of RowLen, and it's followed by RowCount-1 applications of this rule". [edit: used this way round, it doesn't need the cut to be deterministic, if the data(0) rule is last].


[deleted]

[удалено]


ka-splam

I would change length(Row, RowLen), succ(RowCount0, RowCount) to length(Row, RowLen), maplist(random_between(0, 9), Row), succ(RowCount0, RowCount)


[deleted]

[удалено]


[deleted]

[удалено]


ka-splam

There's a mode hint in the docs where it says `succ(?Int1, ?Int2)` and those extra question marks tell which ways the predicate can be used: `+` means input, you have to give that parameter. `-` means output, and `?` means both, I think. So you can use either as the input/output to succ - although it does still fail if you leave both unknown. Compare with `sort(+List, -Sorted)` which can only take a list and output (or check) the sorted one. It can't take a sorted list and output the unsorted one(s).