<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Abstract Syntax Trees to Gain Insights into How Students Program</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Manuel Freire-Morán</string-name>
          <email>manuel.freire@fdi.ucm.es</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Complutense University of Madrid (UCM)</institution>
          ,
          <addr-line>Profesor José García Santesmases 9, 28040 Madrid</addr-line>
          ,
          <country country="ES">Spain</country>
        </aff>
      </contrib-group>
      <abstract>
        <p>Computer Science students often have to program exercises to practice and gain insights, to be then submitted for grading and feedback by instructors. The submission and grading process may be partly automated, for instance by requiring electronic submission and running automated tests on answers; but is mostly a laborious and manual process. Data collected by such systems can be of significant use for learning analytics, helping teachers to better understand how their students have attempted to solve exercises.</p>
      </abstract>
      <kwd-group>
        <kwd>Software similarity</kwd>
        <kwd>Abstract syntax trees</kwd>
        <kwd>Learning analytics</kwd>
      </kwd-group>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Introduction</title>
      <p>When learning Computer Science, many subjects include practical exercises that involve
programming. Often, students submit these exercises using generic VLEs (Virtual Learning
Environments), such as Moodle; other times, programming-specific submission environments are
used, which may include automated tests to be run on submissions.</p>
      <p>In the authors’ institution, several courses make use of the Domjudge1 system to automatically
judge submissions by students. Typically, problem statements include only a sample of the full
number of test-cases that will be used, so submissions to a problem are often correct for samples,
but incorrect for the full set. It is frequent for students to send multiple answers, each time
making changes to their source-code in an attempt to fix it account for the hidden test-cases.
Figure 1 illustrates the teacher dashboard for a domjudge installation; note that some students
have sent the same exercise over 10 times. Teachers will often only look at the last submission
for grading purposes.
CEUR
Workshop
Proceedings</p>
      <p>
        Our initial goal was to develop a simple system that could provide insights into how students
learn to program, by analyzing how their answers changed over time. A very simple approach
would be to use something similar to Unix’s dif [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] tool on each pair of succesive versions.
Indeed, Domjudge can already show difs between versions of a single file in a given submission.
However, requesting these reports from Domjudge requires significant user intervention, as
each version of each file of each submission must be individually queried; and dif results
generally lack context, as the comparison is performed on plain text and not programs, and can
therefore be hard to understand. We wanted a tool that would produce readable output more
similar to what a human would comment after looking at those diferences with full context.
Did the student modify a condition within a particular function? Did the student choose an
entirely diferent approach to solve the problem?. This was prompted by previous work in
similarity detection in the context of code plagiarism prevention, so we thought it possible to
extend existing tools to tackle automated diference labelling. Note that there have been some
attempts to incorporate semantical information in dif-like programs 2, but they are certainly
not in mainstream use.
      </p>
      <p>The next section describes our approach to making submission history for a single user easier
to understand for teachers, by combining existing similarity-detection code with syntax trees for
the specific languages used in these exercises. We then describe results of running a prototype
of the tool on actual submissions from a Data Structures course. Finally, conclussions and future
work outline how the tool could be adapted to facilitate other learning analytics tasks.
2For example, https://semanticdiff.com (commercial) appears to provide semantic visual difs for several languages</p>
    </sec>
    <sec id="sec-2">
      <title>2. Proposal</title>
      <p>To compare program semantics instead of their textual contents, knowledge of the programming
language is required. Programs can be viewed at two very distinct level: at a lower, sintactical
level, tokenizing a source-file allows it to be viewed as a sequence of tokens rather than a
sequence of characters. At a higher level, programs can be analyzed as trees of related tokens,
grouped into declarations, loops, loop conditions, methods, and so on. These trees are often
termed abstract syntax trees (ASTs), and the process of converting source-code into trees that
retain their semantics is termed parsing. ASTs can be used not only for compiling or interpreting
source-code, but also to analyze programs and transform program constructs.</p>
      <p>
        Source-code parsing is a well-understood topic in computer science. Given a suitable grammar
indicating how to parse source-code into ASTs, there are multiple well-known parser-generation
programs that can generate the corresponding parsers for those grammars. One such program
is Antlr 4 [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ], by Terence Parr, which is well-documented, available as open-source, and has
an active community which has contributed open-source grammars for many programming
languages3.
      </p>
      <p>
        Software similarity is often used in academic contexts to locate, and thus deter, plagiarism.
Students that know that there is a high chance that plagiarism will get caught will think
twice before presenting work of others as theirs. There is substantial literature on the subject
if plagiarism, with reviews such as Karnalim’s [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ] identifying a wide variety of techniques,
including string-matching, token-counting, metric-based, or even structural analysis of
parsetrees and call-graphs. There is also relevant literature in the field of code-clone analysis, used
to improve refactoring in production code-bases. In a recent review on code-clone detection,
Ain et Al. [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ] identify essentially the same techniques used for plagiarism detection as useful
for code-clone analysis.
      </p>
      <p>
        A simple and robust technique to detect code similarity, not present in Karnalim’s review,
relies on analyzing the entropy between sources: similar source-code will, when compressed by
a high-quality compressor, compress better than totally unrelated code. For a more in-depth
analysis of NCD (Normalized Compression Distance), see [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ]. NCD itself can be applied to any
sequence, and not just source-code. For example, it has been used in both image comparisons
and to generate phylogenetic trees for genomics research. When applied to source-code, a
significant reduction in noise can be achieved by tokenizing the source-code first, so that
whitespace, non-semantically relevant indentation, identifier names, or comments no longer
contribute to distance.
      </p>
      <p>
        We have built the prototype described in this work on top of AC24, an existing open-source
plagiarism detector with robust similarity detection [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ]. AC2 uses NCD to determine the
similarity between two submissions; files from each submission are concatenated and tokenized
before comparison. Util this work, AC2 used Antlr 4 grammars only for tokenization.
      </p>
      <p>In this work, we describe an extension to AC2 which uses parse trees to annotate diferences
between subsequent versions of a given submission. After building the ASTs of a submission, it
is possible to compare semantically-significant parts of submissions instead of simple
concate3As of june 2023, there are over 250 grammars at https://github.com/antlr/grammars-v4.
4AC2 is available at https://github.com/manuel-freire/ac2
nations of files. The smallest segments of program ASTs where changes are located can be used
to generate semantically-significant labels for diferent versions of a single submission. For
example, if a single conditional has changed, then the label describing that version increment
could be</p>
      <p>Condition changed in Tree.cpp::find_smallest:
- if (i &lt;= size) {
+ if (i &lt; size) {
2.1. Prototype
The prototype first downloads submissions from a Domjudge server, which results in a set
of folders, one per problem (columns in Fig. 1). Inside each problem-folder there is another
folder for each student that has attempted to solve it; and inside each student folder, there is an
additional per-submission folder. The prototype then uses a parse-tree aware version of AC2 to
compare, within each student-folder, each submission to the next one. Output describing these
diferences is generated to a text-file and placed in the student-folder.</p>
      <p>
        To compare two submissions, both are first parsed into ASTs, which must then be aligned
to locate exactly what each change corresponds to. The problem of matching trees has been
examined, for example, in [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ]. We use a very simple approach, starting with a breadth-first
search on both trees that marks each tree node as either identical or at least similar to nodes
on the other tree. To easily detect equal nodes, a textual representation of the tokens at each
tree level is hashed, at a cost of ( ⋅ ) , where  is the total number of tokens in a program
and  is the depth of its parse tree. There are significant advantages in reducing  , by selecting
a subset of possible parse-rules as significant for alignment, and skipping all others. When
an identical node is found via hash-comparison, there is no need to recurse further into the
tree, as all subtrees can then be expected to also result in exact matches. For subtrees with no
identical counterpart, all candidate subtrees are analyzed for similarity using NCD, with only
the most-similar opposing subtree retained for alignment.
      </p>
      <p>The result of aligning two trees  and  is therefore, for each subtree of  , a corresponding
subtree of  that is either identical or considered as the most similar available. The last step
of the process simply generates a textual descripiton of the diferences between non-identical
alignments. Additionally, the annotation process must also describe elements in  that have
not been matched to  as being newly added; and a similar consideration should be made for
elements in  that have entirely dissapeared from  .</p>
      <p>The following pseudocode illustrates these steps:
let astA = parse(submissionA);
let astB = parse(submissionB);
let hashesA = recursiveHash(astA);
let hashesB = recursiveHash(astB);
let alignmentAB = align(astA, astB, hashesA, hashesB);
annotate(alignmentAB);</p>
    </sec>
    <sec id="sec-3">
      <title>3. Case study</title>
      <p>We have tested the prototype annotation tool on a set of submissions by 17 distinct students for
10 problems (partly illustrated in Fig. 1), with a total of 445 submissions from those students
attempting to solve the problems, from which a total of 109 were correct and the remainder
returned either compiler-error (73), run-time error (83), time-limit exceeded (27), wrong-answer
(146), or no-output (7). The students were enrolled in a course on Data Structures in a university
in Madrid, Spain.</p>
      <p>
        The prototype annotated the 449 submissions (with 1919 C++ files in total) in under 15
seconds; performance can certainly be improved, for example by caching parse-trees for files
that were part of the problem statements, such as implementations of common abstract data
types. For each set of sequential submissions by a student, the tool generates a file that describes
what changed from each submission to the next. A sample file is included below (student I04,
problem 473):
[
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] :: s77161_280223_1550_I04_compiler-error -&gt; s77162_280223_1550_I04_compiler-error
      </p>
      <p>
        New @BinTree.h::: (10171-char patch)
[
        <xref ref-type="bibr" rid="ref2">2</xref>
        ] :: s77162_280223_1550_I04_compiler-error -&gt; s77163_280223_1551_I04_compiler-error
      </p>
      <p>
        New @Exceptions.h::: (1581-char patch)
[
        <xref ref-type="bibr" rid="ref3">3</xref>
        ] :: s77163_280223_1551_I04_compiler-error -&gt; s77166_280223_1552_I04_correct
      </p>
      <p>New @Queue.h::: (4857-char patch)
New @List.h::: (11732-char patch)</p>
      <p>
        In the above file, the student forgot to include several dependencies, leading to compiler
errors. In the 4th version, the final 2 dependencies were included, leading to a veredict of correct
by the online judge. Large changes (currently limited to 1024 characters), such as the contents
of new files, are hidden by default. In the next example (student I08, problem 478), each change
describes the method of the class that encompasses the relevant code, providing important
context for a grader familiar with the template used by students:
[
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] :: s78256_070323_1552_I08_wrong-answer -&gt; s78258_070323_1554_I08_wrong-answer
      </p>
      <p>Modified @template.cpp::Bank::transfer(int line, string source, string target, int quantity):
@@ -25,5 +25,5 @@
// Iterate map in alphabetical order and output money in non-empty, non-* accounts
for (auto it = accounts.cbegin(); it != accounts.end(); it++) {
- if ((it.key() != "*") &amp;&amp; (it.value() &gt; 0)) {
+ if (!(it.key() == "*") &amp;&amp; (it.value() &gt; 0)) {</p>
      <p>cout &lt;&lt; it.key() &lt;&lt; " " &lt;&lt; it.value() &lt;&lt; endl;
}</p>
      <p>While the prototype generates readable descriptions of changes in submissions, it is currently
experimental code, and will require significant work before being made available for other
teachers in the author’s institution that use Domjudge for exercises. Each year, over 300
students from the author’s institution enroll in subjects that make heavy use Domjudge. Their
submissions mostly remain on the server hosting the judge, and we plan to enroll their teachers
to test future versions of our tool.</p>
      <p>From the point of view of user experience, having to read a large numbers of text files is
still work, even if each file manages to quickly describe how several submissions have evolved
over time. Additionally, using a fixed cutof-point to hide details, while often useful, can also
hide important details – presenting the information interactively on demand, say within a
web application, would result in a better user experience than having to look up additional
information by pointing an IDE to the actual source files.</p>
    </sec>
    <sec id="sec-4">
      <title>4. Conclussions and future work</title>
      <p>The prototype used for the above case-study does provide readable overviews of what has
changed in submissions to a given problem over time. This makes it possible for teachers to
gain quick overviews of large sets of (similar) submissions from a single author attempting to
solve a single problem, opening a large number of collected submissions to potential analysis
to better understand how students learn programming. However, the extent to which these
overviews are efective at their goal of making it easier for teachers to understand how their
students learn can only be measured by further experiments.</p>
      <p>
        Beyond the application presented here, we consider that there is significant potential for
tools that can automatically annotate diferences in code submissions. The following additional
use-cases come to mind:
1. Automated labelling of changes could be used to auto-generate descriptions of changes
for version-control systems. Knowing which functions and data-structures were changed
by a commit can be much more useful than only knowing the files that were modified.
2. Plagiarism detection can greatly benefit from automatic alignment. For example, when
looking at submissions from two students, it is useful to show which code from student
 best corresponds to a given fragment of code by student  . This could also be used to
describe the steps that  could have taken to cover their tracks.
3. If code snapshots are collected periodically while students are solving a coding exercise,
it may be possible to generate interesting insights into how students learn to code. In [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ],
Budiman and Karnalim describe a VS Code plugin that periodically collects code from
students and sends it to a server to be checked for plagiarism. We believe that a snapshot
approach can also be used to better understand how students learn to code in many other
contexts, such as block-based computational-thinking games.
      </p>
      <p>There also remain multiple hurdles to this vision of semantic labelling of code diferences.
The general problem of finding the most human-readable description of the diferences between
two programs is not solvable by traditional programs. Any approach will have to rely on
reasonable heuristics for common cases, which however can be extremely efective if and when
their preconditions are met. For example, in this paper we rely on an expectation for small
amounts of changes between subsequent versions of submissions. In many cases, this is indeed
the case, and short and readable descriptions can be succesfully generated. However developing
good heuristics can take time, and heuristics are, by nature, fragile.</p>
      <p>Future work will include an improved version of the tool, and larger experiments testing
both its efectiveness and usability.</p>
    </sec>
    <sec id="sec-5">
      <title>Acknowledgments</title>
      <p>Co-funded by the Ministry of Education (PID2020-119620RB-I00) and by the
TelefónicaComplutense Chair on Digital Education and Serious Games.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>J. W.</given-names>
            <surname>Hunt</surname>
          </string-name>
          ,
          <string-name>
            <surname>M. D. McIlroy</surname>
          </string-name>
          ,
          <article-title>An Algorithm for Diferential File Comparison</article-title>
          ,
          <source>Technical Report CSTR 41</source>
          ,
          <string-name>
            <surname>Bell</surname>
            <given-names>Laboratories</given-names>
          </string-name>
          , Murray Hill, NJ,
          <year>1976</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>T.</given-names>
            <surname>Parr</surname>
          </string-name>
          ,
          <article-title>The definitive ANTLR 4 reference</article-title>
          , The Pragmatic Bookshelf,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>O.</given-names>
            <surname>Karnalim</surname>
          </string-name>
          , Simon,
          <string-name>
            <given-names>W.</given-names>
            <surname>Chivers</surname>
          </string-name>
          ,
          <article-title>Similarity detection techniques for academic source code plagiarism and collusion: A review</article-title>
          , in: 2019 IEEE International Conference on Engineering,
          <article-title>Technology and Education (TALE)</article-title>
          , IEEE,
          <year>2019</year>
          , pp.
          <fpage>1</fpage>
          -
          <lpage>8</lpage>
          . doi:
          <volume>10</volume>
          .1109/tale48000.
          <year>2019</year>
          .
          <volume>9225953</volume>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>Q. U.</given-names>
            <surname>Ain</surname>
          </string-name>
          ,
          <string-name>
            <given-names>W. H.</given-names>
            <surname>Butt</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M. W.</given-names>
            <surname>Anwar</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>Azam</surname>
          </string-name>
          ,
          <string-name>
            <given-names>B.</given-names>
            <surname>Maqbool</surname>
          </string-name>
          ,
          <article-title>A systematic review on code clone detection</article-title>
          ,
          <source>IEEE Access 7</source>
          (
          <year>2019</year>
          )
          <fpage>86121</fpage>
          -
          <lpage>86144</lpage>
          . doi:
          <volume>10</volume>
          .1109/ACCESS.
          <year>2019</year>
          .
          <volume>2918202</volume>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>M.</given-names>
            <surname>Cebrián</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Alfonseca</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Ortega</surname>
          </string-name>
          ,
          <article-title>The normalized compression distance is resistant to noise</article-title>
          ,
          <source>IEEE Transactions on Information Theory</source>
          <volume>53</volume>
          (
          <year>2007</year>
          )
          <fpage>1895</fpage>
          -
          <lpage>1900</lpage>
          . doi:
          <volume>10</volume>
          .1109/tit.
          <year>2007</year>
          .
          <volume>894669</volume>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>M.</given-names>
            <surname>Freire</surname>
          </string-name>
          ,
          <article-title>Visualizing program similarity in the ac plagiarism detection system</article-title>
          ,
          <source>in: Proceedings of the working conference on Advanced visual interfaces</source>
          ,
          <year>2008</year>
          , pp.
          <fpage>404</fpage>
          -
          <lpage>407</lpage>
          . doi:
          <volume>10</volume>
          .1145/1385569.1385644.
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>R.</given-names>
            <surname>Kumar</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J. O.</given-names>
            <surname>Talton</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Ahmad</surname>
          </string-name>
          ,
          <string-name>
            <given-names>T.</given-names>
            <surname>Roughgarden</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S. R.</given-names>
            <surname>Klemmer</surname>
          </string-name>
          ,
          <article-title>Flexible tree matching</article-title>
          ,
          <source>in: Proceedings of the Twenty-Second International Joint Conference on Artificial Intelligence -</source>
          Volume Volume Three,
          <source>IJCAI'11</source>
          , AAAI Press,
          <year>2011</year>
          , p.
          <fpage>2674</fpage>
          -
          <lpage>2679</lpage>
          . doi:
          <volume>10</volume>
          .5555/2283696. 2283841.
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>A. E.</given-names>
            <surname>Budiman</surname>
          </string-name>
          ,
          <string-name>
            <given-names>O.</given-names>
            <surname>Karnalim</surname>
          </string-name>
          ,
          <article-title>Automated hints generation for investigating source code plagiarism and identifying the culprits on in-class individual programming assessment</article-title>
          ,
          <source>Computers</source>
          <volume>8</volume>
          (
          <year>2019</year>
          ). URL: https://www.mdpi.com/2073-431X/8/1/11. doi:
          <volume>10</volume>
          .3390/ computers8010011.
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>